Source code for honeybee_radiance.postprocess.solartracking

"""Functions for post-processing results of dynamic objects that track the sun."""
import os
import json
import shutil
import math

from ladybug_geometry.geometry3d.pointvector import Vector3D
from ladybug.sunpath import Sunpath

[docs]def post_process_solar_tracking( result_folders, sun_up_file, location, north=0, tracking_increment=5, destination_folder=None): """Postprocess a list of result folders to account for dynamic solar tracking. This function essentially takes .ill files for each state of a dynamic tracking system and produces a single .ill file that models the tracking behavior. Args: result_folders: A list of folders containing .ill files and each representing a state of the dynamic solar tracking system. These file should be ordered from eastern-most to wester-most, tracing the path of the tracking system over the day. The names of the .ill files should be the same in each folder (representing the same sensor grid in a different state). sun_up_file: Path to a sun-up-hours.txt that contains the sun-up hours of the simulation. location: A Ladybug Location object to be used to generate sun poisitions. north_: A number between -360 and 360 for the counterclockwise difference between the North and the positive Y-axis in degrees. (Default: 0). tracking_increment: An integer for the increment angle of each state in degrees. (Default: 5). destination_folder: A path to a destination folder where the final .ill files of the dynamic tracking system will be written. If None, all files will be written into the directory above the first result_folder. (Default: None). """ # get the orientation angles of the panels for each model st_angle = int(90 - (len(result_folders) * tracking_increment / 2)) + 1 end_angle = int(90 + (len(result_folders) * tracking_increment / 2)) angles = list(range(st_angle, end_angle, tracking_increment)) # create a sun path ang get the sun-up hours to be used to get solar positions sp = Sunpath.from_location(location, north) with open(sun_up_file) as suh_file: sun_up_hours = [float(hour) for hour in suh_file.readlines()] # for each hour of the sun_up_hours, figure out which file is the one to use mtx_to_use, ground_vec = [], Vector3D(1, 0, 0) for hoy in sun_up_hours: sun = sp.calculate_sun_from_hoy(hoy) vec = Vector3D(sun.sun_vector_reversed.x, 0, sun.sun_vector_reversed.z) orient = math.degrees(ground_vec.angle(vec)) for i, ang in enumerate(angles): if ang > orient: mtx_to_use.append(i) break else: mtx_to_use.append(-1) # parse the grids_info in the first folder to understand the sensor grids grids_info_file = os.path.join(result_folders[0], 'grids_info.json') with open(grids_info_file) as gi_file: grids_data = json.load(gi_file) grid_ids = [g['full_id'] for g in grids_data] # prepare the destination folder and copy the grids_info to it if destination_folder is None: destination_folder = os.path.dirname(result_folders[0]) if not os.path.isdir(destination_folder): os.mkdir(destination_folder) shutil.copyfile(grids_info_file, os.path.join(destination_folder, 'grids_info.json')) # convert the .ill files of each sensor grid into a single .ill file for grid_id in grid_ids: grid_mtx = [] for i, model in enumerate(result_folders): grid_file = os.path.join(model, '{}.ill'.format(grid_id)) with open(grid_file) as ill_file: grid_mtx.append([lin.split() for lin in ill_file]) grid_ill = [] for i, hoy_mtx in enumerate(mtx_to_use): hoy_vals = [] for pt in range(len(grid_mtx[0])): hoy_vals.append(grid_mtx[hoy_mtx][pt][i]) grid_ill.append(hoy_vals) dest_file = os.path.join(destination_folder, '{}.ill'.format(grid_id)) with open(dest_file, 'w') as ill_file: for row in zip(*grid_ill): ill_file.write(' '.join(row) + '\n')