From 796ccc8f1b03095702973c57029a54960522ed0e Mon Sep 17 00:00:00 2001 From: Mikkel Pedersen Date: Fri, 17 Feb 2023 22:18:25 +0100 Subject: [PATCH] fix(recipe): Re-export cumulative-radiation --- .../flow/dependencies/__init__.py | 1 + .../cumulative_radiation_postprocess.py | 117 ++++ .../cumulative_radiation_prepare_folder.py | 493 +++++++++++++++ .../flow/main_f645822f.py | 576 ++++++++++++++++++ lbt_recipes/cumulative_radiation/package.json | 2 +- lbt_recipes/cumulative_radiation/run.py | 6 +- lbt_recipes/cumulative_radiation/status.json | 10 +- 7 files changed, 1196 insertions(+), 9 deletions(-) create mode 100644 lbt_recipes/cumulative_radiation/flow/dependencies/__init__.py create mode 100644 lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_postprocess.py create mode 100644 lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_prepare_folder.py create mode 100644 lbt_recipes/cumulative_radiation/flow/main_f645822f.py diff --git a/lbt_recipes/cumulative_radiation/flow/dependencies/__init__.py b/lbt_recipes/cumulative_radiation/flow/dependencies/__init__.py new file mode 100644 index 00000000..ba9a5b15 --- /dev/null +++ b/lbt_recipes/cumulative_radiation/flow/dependencies/__init__.py @@ -0,0 +1 @@ +from .. import _queenbee_status_lock_ diff --git a/lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_postprocess.py b/lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_postprocess.py new file mode 100644 index 00000000..cc103aef --- /dev/null +++ b/lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_postprocess.py @@ -0,0 +1,117 @@ +""" +This file is auto-generated from cumulative-radiation:0.3.8. +It is unlikely that you should be editing this file directly. +Try to edit the original recipe itself and regenerate the code. + +Contact the recipe maintainers with additional questions. + mostapha: mostapha@ladybug.tools + ladybug-tools: info@ladybug.tools + +This file is licensed under "PolyForm Shield License 1.0.0". +See https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt for more information. +""" + + +import luigi +import pathlib +from queenbee_local import QueenbeeTask +from queenbee_local import load_input_param as qb_load_input_param +from . import _queenbee_status_lock_ + + +_default_inputs = { 'average_irradiance': None, + 'grid_name': None, + 'params_folder': '__params', + 'simulation_folder': '.', + 'timestep': 1, + 'wea': None} + + +class AccumulateResults(QueenbeeTask): + """Postprocess average irradiance (W/m2) into cumulative radiation (kWh/m2).""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def name(self): + return self._input_params['grid_name'] + + @property + def timestep(self): + return self._input_params['timestep'] + + @property + def average_irradiance(self): + value = pathlib.Path(self._input_params['average_irradiance']) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def wea(self): + value = pathlib.Path(self._input_params['wea']) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance post-process cumulative-radiation avg_irr.mtx weather.wea --timestep {timestep} --output radiation.mtx'.format(timestep=self.timestep) + + def output(self): + return { + 'radiation': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'results/cumulative_radiation/{name}.res'.format(name=self.name)).resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'average_irradiance', 'to': 'avg_irr.mtx', 'from': self.average_irradiance, 'optional': False}, + {'name': 'wea', 'to': 'weather.wea', 'from': self.wea, 'optional': False}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'radiation', 'from': 'radiation.mtx', + 'to': pathlib.Path(self.execution_folder, 'results/cumulative_radiation/{name}.res'.format(name=self.name)).resolve().as_posix(), + 'optional': False, + 'type': 'file' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class _CumulativeRadiationPostprocess_f645822fOrchestrator(luigi.WrapperTask): + """Runs all the tasks in this module.""" + # user input for this module + _input_params = luigi.DictParameter() + + @property + def input_values(self): + params = dict(_default_inputs) + params.update(dict(self._input_params)) + return params + + def requires(self): + yield [AccumulateResults(_input_params=self.input_values)] diff --git a/lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_prepare_folder.py b/lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_prepare_folder.py new file mode 100644 index 00000000..6e8f217f --- /dev/null +++ b/lbt_recipes/cumulative_radiation/flow/dependencies/cumulative_radiation_prepare_folder.py @@ -0,0 +1,493 @@ +""" +This file is auto-generated from cumulative-radiation:0.3.8. +It is unlikely that you should be editing this file directly. +Try to edit the original recipe itself and regenerate the code. + +Contact the recipe maintainers with additional questions. + mostapha: mostapha@ladybug.tools + ladybug-tools: info@ladybug.tools + +This file is licensed under "PolyForm Shield License 1.0.0". +See https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt for more information. +""" + + +import luigi +import pathlib +from queenbee_local import QueenbeeTask +from queenbee_local import load_input_param as qb_load_input_param +from . import _queenbee_status_lock_ + + +_default_inputs = { 'cpu_count': 50, + 'grid_filter': '*', + 'min_sensor_count': 500, + 'model': None, + 'north': 0.0, + 'params_folder': '__params', + 'radiance_parameters': '-ab 2 -ad 5000 -lw 2e-05', + 'simulation_folder': '.', + 'sky_density': 1, + 'timestep': 1, + 'wea': None} + + +class CreateRadFolder(QueenbeeTask): + """Create a Radiance folder from a HBJSON input file.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def grid_filter(self): + return self._input_params['grid_filter'] + + @property + def input_model(self): + value = pathlib.Path(self._input_params['model']) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance translate model-to-rad-folder model.hbjson --grid "{grid_filter}" --grid-check'.format(grid_filter=self.grid_filter) + + def output(self): + return { + 'model_folder': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'model').resolve().as_posix() + ), + + 'bsdf_folder': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'model/bsdf').resolve().as_posix() + ), + + 'sensor_grids_file': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'results/average_irradiance/grids_info.json').resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'input_model', 'to': 'model.hbjson', 'from': self.input_model, 'optional': False}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'model-folder', 'from': 'model', + 'to': pathlib.Path(self.execution_folder, 'model').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }, + + { + 'name': 'bsdf-folder', 'from': 'model/bsdf', + 'to': pathlib.Path(self.execution_folder, 'model/bsdf').resolve().as_posix(), + 'optional': True, + 'type': 'folder' + }, + + { + 'name': 'sensor-grids-file', 'from': 'model/grid/_info.json', + 'to': pathlib.Path(self.execution_folder, 'results/average_irradiance/grids_info.json').resolve().as_posix(), + 'optional': False, + 'type': 'file' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class CreateSky(QueenbeeTask): + """Generate a sun-up sky matrix.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def north(self): + return self._input_params['north'] + + @property + def sky_type(self): + return 'total' + + @property + def output_type(self): + return 'solar' + + @property + def output_format(self): + return 'ASCII' + + @property + def sky_density(self): + return self._input_params['sky_density'] + + @property + def cumulative(self): + return 'cumulative' + + sun_up_hours = luigi.Parameter(default='all-hours') + + @property + def wea(self): + value = pathlib.Path(self._input_params['wea']) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance sky mtx sky.wea --name sky --north {north} --sky-type {sky_type} --{cumulative} --{sun_up_hours} --{output_type} --output-format {output_format} --sky-density {sky_density}'.format(sun_up_hours=self.sun_up_hours, north=self.north, output_format=self.output_format, sky_density=self.sky_density, sky_type=self.sky_type, output_type=self.output_type, cumulative=self.cumulative) + + def output(self): + return { + 'sky_matrix': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'resources/sky.mtx').resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'wea', 'to': 'sky.wea', 'from': self.wea, 'optional': False}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'sky-matrix', 'from': 'sky.mtx', + 'to': pathlib.Path(self.execution_folder, 'resources/sky.mtx').resolve().as_posix(), + 'optional': False, + 'type': 'file' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class CreateSkyDome(QueenbeeTask): + """Create a skydome for daylight coefficient studies.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def sky_density(self): + return self._input_params['sky_density'] + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance sky skydome --name rflux_sky.sky --sky-density {sky_density}'.format(sky_density=self.sky_density) + + def output(self): + return { + 'sky_dome': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'resources/sky.dome').resolve().as_posix() + ) + } + + @property + def output_artifacts(self): + return [ + { + 'name': 'sky-dome', 'from': 'rflux_sky.sky', + 'to': pathlib.Path(self.execution_folder, 'resources/sky.dome').resolve().as_posix(), + 'optional': False, + 'type': 'file' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class CopyGridInfo(QueenbeeTask): + """Copy a file or folder to a destination.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def src(self): + value = pathlib.Path(self.input()['CreateRadFolder']['sensor_grids_file'].path) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'echo copying input path...' + + def requires(self): + return {'CreateRadFolder': CreateRadFolder(_input_params=self._input_params)} + + def output(self): + return { + 'dst': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'results/cumulative_radiation/grids_info.json').resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'src', 'to': 'input_path', 'from': self.src, 'optional': False}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'dst', 'from': 'input_path', + 'to': pathlib.Path(self.execution_folder, 'results/cumulative_radiation/grids_info.json').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }] + + @property + def task_image(self): + return 'docker.io/python:3.7-slim' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class CreateOctree(QueenbeeTask): + """Generate an octree from a Radiance folder.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + black_out = luigi.Parameter(default='default') + + include_aperture = luigi.Parameter(default='include') + + @property + def model(self): + value = pathlib.Path(self.input()['CreateRadFolder']['model_folder'].path) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance octree from-folder model --output scene.oct --{include_aperture}-aperture --{black_out}'.format(include_aperture=self.include_aperture, black_out=self.black_out) + + def requires(self): + return {'CreateRadFolder': CreateRadFolder(_input_params=self._input_params)} + + def output(self): + return { + 'scene_file': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'resources/scene.oct').resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'model', 'to': 'model', 'from': self.model, 'optional': False}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'scene-file', 'from': 'scene.oct', + 'to': pathlib.Path(self.execution_folder, 'resources/scene.oct').resolve().as_posix(), + 'optional': False, + 'type': 'file' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class SplitGridFolder(QueenbeeTask): + """Create new sensor grids folder with evenly distributed sensors. + + This function creates a new folder with evenly distributed sensor grids. The folder + will include a ``_redist_info.json`` file which has the information to recreate the + original input files from this folder and the results generated based on the grids + in this folder.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def cpu_count(self): + return self._input_params['cpu_count'] + + @property + def cpus_per_grid(self): + return '1' + + @property + def min_sensor_count(self): + return self._input_params['min_sensor_count'] + + @property + def input_folder(self): + value = pathlib.Path(self.input()['CreateRadFolder']['model_folder'].path, 'grid') + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance grid split-folder ./input_folder ./output_folder {cpu_count} --grid-divisor {cpus_per_grid} --min-sensor-count {min_sensor_count}'.format(min_sensor_count=self.min_sensor_count, cpu_count=self.cpu_count, cpus_per_grid=self.cpus_per_grid) + + def requires(self): + return {'CreateRadFolder': CreateRadFolder(_input_params=self._input_params)} + + def output(self): + return { + 'output_folder': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'resources/grid').resolve().as_posix() + ), + + 'dist_info': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'initial_results/_redist_info.json').resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'input_folder', 'to': 'input_folder', 'from': self.input_folder, 'optional': False}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'output-folder', 'from': 'output_folder', + 'to': pathlib.Path(self.execution_folder, 'resources/grid').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }, + + { + 'name': 'dist-info', 'from': 'output_folder/_redist_info.json', + 'to': pathlib.Path(self.execution_folder, 'initial_results/_redist_info.json').resolve().as_posix(), + 'optional': False, + 'type': 'file' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class _CumulativeRadiationPrepareFolder_f645822fOrchestrator(luigi.WrapperTask): + """Runs all the tasks in this module.""" + # user input for this module + _input_params = luigi.DictParameter() + + @property + def input_values(self): + params = dict(_default_inputs) + params.update(dict(self._input_params)) + return params + + def requires(self): + yield [CreateSky(_input_params=self.input_values), CreateSkyDome(_input_params=self.input_values), CopyGridInfo(_input_params=self.input_values), CreateOctree(_input_params=self.input_values), SplitGridFolder(_input_params=self.input_values)] diff --git a/lbt_recipes/cumulative_radiation/flow/main_f645822f.py b/lbt_recipes/cumulative_radiation/flow/main_f645822f.py new file mode 100644 index 00000000..1a1f208b --- /dev/null +++ b/lbt_recipes/cumulative_radiation/flow/main_f645822f.py @@ -0,0 +1,576 @@ +""" +This file is auto-generated from cumulative-radiation:0.3.8. +It is unlikely that you should be editing this file directly. +Try to edit the original recipe itself and regenerate the code. + +Contact the recipe maintainers with additional questions. + mostapha: mostapha@ladybug.tools + ladybug-tools: info@ladybug.tools + +This file is licensed under "PolyForm Shield License 1.0.0". +See https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt for more information. +""" + + +import luigi +import pathlib +from queenbee_local import QueenbeeTask +from queenbee_local import load_input_param as qb_load_input_param +from . import _queenbee_status_lock_ +from .dependencies.cumulative_radiation_postprocess import _CumulativeRadiationPostprocess_f645822fOrchestrator as CumulativeRadiationPostprocess_f645822fWorkerbee +from .dependencies.cumulative_radiation_prepare_folder import _CumulativeRadiationPrepareFolder_f645822fOrchestrator as CumulativeRadiationPrepareFolder_f645822fWorkerbee + + +_default_inputs = { 'cpu_count': 50, + 'grid_filter': '*', + 'min_sensor_count': 500, + 'model': None, + 'north': 0.0, + 'params_folder': '__params', + 'radiance_parameters': '-ab 2 -ad 5000 -lw 2e-05', + 'simulation_folder': '.', + 'sky_density': 1, + 'timestep': 1, + 'wea': None} + + +class PrepareFolderCumulativeRadiation(QueenbeeTask): + """No description is provided.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def timestep(self): + return self._input_params['timestep'] + + @property + def north(self): + return self._input_params['north'] + + @property + def cpu_count(self): + return self._input_params['cpu_count'] + + @property + def min_sensor_count(self): + return self._input_params['min_sensor_count'] + + @property + def grid_filter(self): + return self._input_params['grid_filter'] + + @property + def sky_density(self): + return self._input_params['sky_density'] + + radiance_parameters = luigi.Parameter(default='-ab 2 -ad 5000 -lw 2e-05') + + @property + def model(self): + value = pathlib.Path(self._input_params['model']) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def wea(self): + value = pathlib.Path(self._input_params['wea']) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + @property + def map_dag_inputs(self): + """Map task inputs to DAG inputs.""" + inputs = { + 'simulation_folder': self.execution_folder, + 'timestep': self.timestep, + 'north': self.north, + 'cpu_count': self.cpu_count, + 'min_sensor_count': self.min_sensor_count, + 'grid_filter': self.grid_filter, + 'sky_density': self.sky_density, + 'model': self.model, + 'wea': self.wea + } + try: + inputs['__debug__'] = self._input_params['__debug__'] + except KeyError: + # not debug mode + pass + + return inputs + + def run(self): + yield [CumulativeRadiationPrepareFolder_f645822fWorkerbee(_input_params=self.map_dag_inputs)] + pathlib.Path(self.execution_folder).mkdir(parents=True, exist_ok=True) + self._copy_output_artifacts(self.execution_folder) + self._copy_output_parameters(self.execution_folder) + pathlib.Path(self.execution_folder, 'prepare_folder_cumulative_radiation.done').write_text('done!') + + def output(self): + return { + + 'model_folder': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'model').resolve().as_posix() + ), + + 'resources': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'resources').resolve().as_posix() + ), + + 'results': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'results').resolve().as_posix() + ), + + 'initial_results': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'initial_results').resolve().as_posix() + ), + 'sensor_grids': luigi.LocalTarget( + pathlib.Path( + self.params_folder, + 'resources/grid/_info.json').resolve().as_posix() + ), + 'grids_info': luigi.LocalTarget( + pathlib.Path( + self.params_folder, + 'results/average_irradiance/grids_info.json').resolve().as_posix() + ), + 'is_done': luigi.LocalTarget(pathlib.Path(self.execution_folder, 'prepare_folder_cumulative_radiation.done').resolve().as_posix()) + } + + @property + def output_artifacts(self): + return [ + { + 'name': 'model-folder', 'from': 'model', + 'to': pathlib.Path(self.execution_folder, 'model').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }, + + { + 'name': 'resources', 'from': 'resources', + 'to': pathlib.Path(self.execution_folder, 'resources').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }, + + { + 'name': 'results', 'from': 'results', + 'to': pathlib.Path(self.execution_folder, 'results').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }, + + { + 'name': 'initial-results', 'from': 'initial_results', + 'to': pathlib.Path(self.execution_folder, 'initial_results').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }] + + @property + def output_parameters(self): + return [{'name': 'sensor-grids', 'from': 'resources/grid/_info.json', 'to': pathlib.Path(self.params_folder, 'resources/grid/_info.json').resolve().as_posix()}, + {'name': 'grids-info', 'from': 'results/average_irradiance/grids_info.json', 'to': pathlib.Path(self.params_folder, 'results/average_irradiance/grids_info.json').resolve().as_posix()}] + + +class SkyRadiationRaytracingLoop(QueenbeeTask): + """Calculate daylight coefficient for a grid of sensors from a sky matrix.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def radiance_parameters(self): + return self._input_params['radiance_parameters'] + + @property + def fixed_radiance_parameters(self): + return '-aa 0.0 -I -c 1' + + @property + def sensor_count(self): + return self.item['count'] + + @property + def conversion(self): + return '0.265 0.670 0.065' + + @property + def output_format(self): + return 'a' + + header = luigi.Parameter(default='keep') + + order_by = luigi.Parameter(default='sensor') + + @property + def sky_dome(self): + value = pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['resources'].path, 'sky.dome') + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def sky_matrix(self): + value = pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['resources'].path, 'sky.mtx') + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def scene_file(self): + value = pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['resources'].path, 'scene.oct') + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def sensor_grid(self): + value = pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['resources'].path, 'grid/{item_full_id}.pts'.format(item_full_id=self.item['full_id'])) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def bsdf_folder(self): + try: + pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['model_folder'].path, 'bsdf') + except TypeError: + # optional artifact + return None + value = pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['model_folder'].path, 'bsdf') + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + # get item for loop + try: + item = luigi.DictParameter() + except Exception: + item = luigi.Parameter() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder'], 'initial_results/{item_full_id}'.format(item_full_id=self.item['full_id'])).resolve().as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance dc scoeff scene.oct grid.pts sky.dome sky.mtx --sensor-count {sensor_count} --output results.ill --rad-params "{radiance_parameters}" --rad-params-locked "{fixed_radiance_parameters}" --conversion "{conversion}" --output-format {output_format} --order-by-{order_by} --{header}-header'.format(sensor_count=self.sensor_count, order_by=self.order_by, header=self.header, output_format=self.output_format, conversion=self.conversion, fixed_radiance_parameters=self.fixed_radiance_parameters, radiance_parameters=self.radiance_parameters) + + def requires(self): + return {'PrepareFolderCumulativeRadiation': PrepareFolderCumulativeRadiation(_input_params=self._input_params)} + + def output(self): + return { + 'result_file': luigi.LocalTarget( + pathlib.Path(self.execution_folder, '../{item_name}.res'.format(item_name=self.item['name'])).resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'sky_dome', 'to': 'sky.dome', 'from': self.sky_dome, 'optional': False}, + {'name': 'sky_matrix', 'to': 'sky.mtx', 'from': self.sky_matrix, 'optional': False}, + {'name': 'scene_file', 'to': 'scene.oct', 'from': self.scene_file, 'optional': False}, + {'name': 'sensor_grid', 'to': 'grid.pts', 'from': self.sensor_grid, 'optional': False}, + {'name': 'bsdf_folder', 'to': 'model/bsdf', 'from': self.bsdf_folder, 'optional': True}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'result-file', 'from': 'results.ill', + 'to': pathlib.Path(self.execution_folder, '../{item_name}.res'.format(item_name=self.item['name'])).resolve().as_posix(), + 'optional': False, + 'type': 'file' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class SkyRadiationRaytracing(luigi.Task): + """Calculate daylight coefficient for a grid of sensors from a sky matrix.""" + # global parameters + _input_params = luigi.DictParameter() + @property + def sensor_grids(self): + value = pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['sensor_grids'].path) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def items(self): + try: + # assume the input is a file + return qb_load_input_param(self.sensor_grids) + except: + # it is a parameter + return self.input()['PrepareFolderCumulativeRadiation']['sensor_grids'].path + + def run(self): + yield [SkyRadiationRaytracingLoop(item=item, _input_params=self._input_params) for item in self.items] + done_file = pathlib.Path(self.execution_folder, 'sky_radiation_raytracing.done') + done_file.parent.mkdir(parents=True, exist_ok=True) + done_file.write_text('done!') + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def requires(self): + return {'PrepareFolderCumulativeRadiation': PrepareFolderCumulativeRadiation(_input_params=self._input_params)} + + def output(self): + return { + 'is_done': luigi.LocalTarget(pathlib.Path(self.execution_folder, 'sky_radiation_raytracing.done').resolve().as_posix()) + } + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class RestructureResults(QueenbeeTask): + """Restructure files in a distributed folder.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def extension(self): + return 'res' + + @property + def input_folder(self): + value = pathlib.Path('initial_results') + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def command(self): + return 'honeybee-radiance grid merge-folder ./input_folder ./output_folder {extension} --dist-info dist_info.json'.format(extension=self.extension) + + def requires(self): + return {'SkyRadiationRaytracing': SkyRadiationRaytracing(_input_params=self._input_params)} + + def output(self): + return { + 'output_folder': luigi.LocalTarget( + pathlib.Path(self.execution_folder, 'results/average_irradiance').resolve().as_posix() + ) + } + + @property + def input_artifacts(self): + return [ + {'name': 'input_folder', 'to': 'input_folder', 'from': self.input_folder, 'optional': False}] + + @property + def output_artifacts(self): + return [ + { + 'name': 'output-folder', 'from': 'output_folder', + 'to': pathlib.Path(self.execution_folder, 'results/average_irradiance').resolve().as_posix(), + 'optional': False, + 'type': 'folder' + }] + + @property + def task_image(self): + return 'docker.io/ladybugtools/honeybee-radiance:1.64.140' + + @property + def image_workdir(self): + return '/home/ladybugbot/run' + + +class CumulativeRadiationPostprocessLoop(luigi.Task): + """No description is provided.""" + + # DAG Input parameters + _input_params = luigi.DictParameter() + _status_lock = _queenbee_status_lock_ + + # Task inputs + @property + def grid_name(self): + return self.item['full_id'] + + @property + def timestep(self): + return self._input_params['timestep'] + + @property + def average_irradiance(self): + value = pathlib.Path(self.input()['RestructureResults']['output_folder'].path, '{item_full_id}.res'.format(item_full_id=self.item['full_id'])) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def wea(self): + value = pathlib.Path(self._input_params['wea']) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + # get item for loop + try: + item = luigi.DictParameter() + except Exception: + item = luigi.Parameter() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + @property + def map_dag_inputs(self): + """Map task inputs to DAG inputs.""" + inputs = { + 'simulation_folder': self.execution_folder, + 'grid_name': self.grid_name, + 'average_irradiance': self.average_irradiance, + 'wea': self.wea, + 'timestep': self.timestep + } + try: + inputs['__debug__'] = self._input_params['__debug__'] + except KeyError: + # not debug mode + pass + + return inputs + + def run(self): + yield [CumulativeRadiationPostprocess_f645822fWorkerbee(_input_params=self.map_dag_inputs)] + done_file = pathlib.Path(self.execution_folder, 'cumulative_radiation_postprocess.done') + done_file.parent.mkdir(parents=True, exist_ok=True) + done_file.write_text('done!') + + def requires(self): + return {'PrepareFolderCumulativeRadiation': PrepareFolderCumulativeRadiation(_input_params=self._input_params), 'RestructureResults': RestructureResults(_input_params=self._input_params)} + + def output(self): + return { + 'is_done': luigi.LocalTarget(pathlib.Path(self.execution_folder, 'cumulative_radiation_postprocess.done').resolve().as_posix()) + } + + +class CumulativeRadiationPostprocess(luigi.Task): + """No description is provided.""" + # global parameters + _input_params = luigi.DictParameter() + @property + def grids_info(self): + value = pathlib.Path(self.input()['PrepareFolderCumulativeRadiation']['grids_info'].path) + return value.as_posix() if value.is_absolute() \ + else pathlib.Path(self.initiation_folder, value).resolve().as_posix() + + @property + def items(self): + try: + # assume the input is a file + return qb_load_input_param(self.grids_info) + except: + # it is a parameter + return self.input()['PrepareFolderCumulativeRadiation']['grids_info'].path + + def run(self): + yield [CumulativeRadiationPostprocessLoop(item=item, _input_params=self._input_params) for item in self.items] + done_file = pathlib.Path(self.execution_folder, 'cumulative_radiation_postprocess.done') + done_file.parent.mkdir(parents=True, exist_ok=True) + done_file.write_text('done!') + + @property + def initiation_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def execution_folder(self): + return pathlib.Path(self._input_params['simulation_folder']).as_posix() + + @property + def params_folder(self): + return pathlib.Path(self.execution_folder, self._input_params['params_folder']).resolve().as_posix() + + def requires(self): + return {'PrepareFolderCumulativeRadiation': PrepareFolderCumulativeRadiation(_input_params=self._input_params), 'RestructureResults': RestructureResults(_input_params=self._input_params)} + + def output(self): + return { + 'is_done': luigi.LocalTarget(pathlib.Path(self.execution_folder, 'cumulative_radiation_postprocess.done').resolve().as_posix()) + } + + +class _Main_f645822fOrchestrator(luigi.WrapperTask): + """Runs all the tasks in this module.""" + # user input for this module + _input_params = luigi.DictParameter() + + @property + def input_values(self): + params = dict(_default_inputs) + params.update(dict(self._input_params)) + return params + + def requires(self): + yield [CumulativeRadiationPostprocess(_input_params=self.input_values)] diff --git a/lbt_recipes/cumulative_radiation/package.json b/lbt_recipes/cumulative_radiation/package.json index 1544309a..391cc27f 100644 --- a/lbt_recipes/cumulative_radiation/package.json +++ b/lbt_recipes/cumulative_radiation/package.json @@ -6,7 +6,7 @@ "type": "MetaData", "annotations": {}, "name": "cumulative-radiation", - "tag": "0.3.4", + "tag": "0.3.8", "app_version": null, "keywords": [ "honeybee", diff --git a/lbt_recipes/cumulative_radiation/run.py b/lbt_recipes/cumulative_radiation/run.py index 60b58627..31acb157 100644 --- a/lbt_recipes/cumulative_radiation/run.py +++ b/lbt_recipes/cumulative_radiation/run.py @@ -1,5 +1,5 @@ """ -This file is auto-generated from cumulative-radiation:0.3.4. +This file is auto-generated from cumulative-radiation:0.3.8. It is unlikely that you should be editing this file directly. Try to edit the original recipe itself and regenerate the code. @@ -23,7 +23,7 @@ from queenbee_local import local_scheduler, _copy_artifacts, update_params, parse_input_args, LOGS_CONFIG from luigi.execution_summary import LuigiStatusCode -import flow.main_62668fa9 as cumulative_radiation_workerbee +import flow.main_f645822f as cumulative_radiation_workerbee _recipe_default_inputs = { 'cpu_count': 50, @@ -42,7 +42,7 @@ class LetCumulativeRadiationFly(luigi.WrapperTask): _input_params = luigi.DictParameter() def requires(self): - yield [cumulative_radiation_workerbee._Main_62668fa9Orchestrator(_input_params=self._input_params)] + yield [cumulative_radiation_workerbee._Main_f645822fOrchestrator(_input_params=self._input_params)] def start(project_folder, user_values, workers): diff --git a/lbt_recipes/cumulative_radiation/status.json b/lbt_recipes/cumulative_radiation/status.json index a41ecb0d..68f969de 100644 --- a/lbt_recipes/cumulative_radiation/status.json +++ b/lbt_recipes/cumulative_radiation/status.json @@ -1,5 +1,5 @@ { - "id": "77c6c72b-d76c-47e8-854c-dc12ae5693ac", + "id": "6a5ac09e-1dc4-4127-8228-fbbc9079c605", "author": { "id": "91d47029-1342-449f-b4ca-a6a7d9bfd9d1", "account_type": "user", @@ -24,7 +24,7 @@ "type": "MetaData", "annotations": {}, "name": "cumulative-radiation", - "tag": "0.3.4", + "tag": "0.3.8", "app_version": null, "keywords": [ "honeybee", @@ -413,12 +413,12 @@ "inputs": [], "outputs": [], "message": null, - "started_at": "2023-02-14T17:32:29+00:00", + "started_at": "2023-02-17T21:03:33+00:00", "finished_at": null, "source": null, "api_version": "v1beta1", - "id": "77c6c72b-d76c-47e8-854c-dc12ae5693ac_00", - "job_id": "77c6c72b-d76c-47e8-854c-dc12ae5693ac", + "id": "6a5ac09e-1dc4-4127-8228-fbbc9079c605_00", + "job_id": "6a5ac09e-1dc4-4127-8228-fbbc9079c605", "entrypoint": null, "status": "Unknown", "steps": {}