Skip to content

Commit

Permalink
feat(recipe): Add support for conditional artifacts
Browse files Browse the repository at this point in the history
This commit also updates the annual daylight recipe to include schedule and threshold inputs while also exposing the annual metrics.
  • Loading branch information
chriswmackey authored and Chris Mackey committed Mar 5, 2021
1 parent 3af970e commit bd4ee03
Show file tree
Hide file tree
Showing 5 changed files with 337 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'sky_matrix', 'to': 'sky.mtx', 'from': self.sky_matrix},
{'name': 'sky_dome', 'to': 'sky.dome', 'from': self.sky_dome},
{'name': 'sensor_grid', 'to': 'grid.pts', 'from': self.sensor_grid},
{'name': 'scene_file', 'to': 'scene.oct', 'from': self.scene_file}]
{'name': 'sky_matrix', 'to': 'sky.mtx', 'from': self.sky_matrix, 'optional': False},
{'name': 'sky_dome', 'to': 'sky.dome', 'from': self.sky_dome, 'optional': False},
{'name': 'sensor_grid', 'to': 'grid.pts', 'from': self.sensor_grid, 'optional': False},
{'name': 'scene_file', 'to': 'scene.oct', 'from': self.scene_file, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -235,9 +235,9 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'modifiers', 'to': 'suns.mod', 'from': self.modifiers},
{'name': 'sensor_grid', 'to': 'grid.pts', 'from': self.sensor_grid},
{'name': 'scene_file', 'to': 'scene.oct', 'from': self.scene_file}]
{'name': 'modifiers', 'to': 'suns.mod', 'from': self.modifiers, 'optional': False},
{'name': 'sensor_grid', 'to': 'grid.pts', 'from': self.sensor_grid, 'optional': False},
{'name': 'scene_file', 'to': 'scene.oct', 'from': self.scene_file, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -294,7 +294,7 @@ def output(self):
}


class MergeResults(QueenbeeTask):
class MergeRawResults(QueenbeeTask):
"""Merge several files with similar starting name into one."""

# DAG Input parameters
Expand Down Expand Up @@ -343,7 +343,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'folder', 'to': 'input_folder', 'from': self.folder}]
{'name': 'folder', 'to': 'input_folder', 'from': self.folder, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -421,9 +421,9 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'direct_sky_matrix', 'to': 'sky_dir.ill', 'from': self.direct_sky_matrix},
{'name': 'total_sky_matrix', 'to': 'sky.ill', 'from': self.total_sky_matrix},
{'name': 'sunlight_matrix', 'to': 'sun.ill', 'from': self.sunlight_matrix}]
{'name': 'direct_sky_matrix', 'to': 'sky_dir.ill', 'from': self.direct_sky_matrix, 'optional': False},
{'name': 'total_sky_matrix', 'to': 'sky.ill', 'from': self.total_sky_matrix, 'optional': False},
{'name': 'sunlight_matrix', 'to': 'sun.ill', 'from': self.sunlight_matrix, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -527,7 +527,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'input_grid', 'to': 'grid.pts', 'from': self.input_grid}]
{'name': 'input_grid', 'to': 'grid.pts', 'from': self.input_grid, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -623,10 +623,10 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'sky_matrix', 'to': 'sky.mtx', 'from': self.sky_matrix},
{'name': 'sky_dome', 'to': 'sky.dome', 'from': self.sky_dome},
{'name': 'sensor_grid', 'to': 'grid.pts', 'from': self.sensor_grid},
{'name': 'scene_file', 'to': 'scene.oct', 'from': self.scene_file}]
{'name': 'sky_matrix', 'to': 'sky.mtx', 'from': self.sky_matrix, 'optional': False},
{'name': 'sky_dome', 'to': 'sky.dome', 'from': self.sky_dome, 'optional': False},
{'name': 'sensor_grid', 'to': 'grid.pts', 'from': self.sensor_grid, 'optional': False},
{'name': 'scene_file', 'to': 'scene.oct', 'from': self.scene_file, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -682,7 +682,7 @@ def output(self):
}


class _AnnualDaylightRayTracingOrchestrator(luigi.WrapperTask):
class _AnnualDaylightRayTracing_d3bf888cOrchestrator(luigi.WrapperTask):
"""Runs all the tasks in this module."""
# user input for this module
_input_params = luigi.DictParameter()
Expand All @@ -694,4 +694,4 @@ def input_values(self):
return params

def requires(self):
return [MergeResults(_input_params=self.input_values)]
return [MergeRawResults(_input_params=self.input_values)]
96 changes: 83 additions & 13 deletions lbt_recipes/annual_daylight/flow/main.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import luigi
import os
from queenbee_local import QueenbeeTask
from .dependencies.annual_daylight_ray_tracing import _AnnualDaylightRayTracingOrchestrator as AnnualDaylightRayTracingWorkerbee
from .dependencies.annual_daylight_ray_tracing import _AnnualDaylightRayTracing_d3bf888cOrchestrator as AnnualDaylightRayTracing_d3bf888cWorkerbee


_default_inputs = { 'model': None,
'north': 0.0,
'params_folder': '__params',
'radiance_parameters': '-ab 2 -ad 5000 -lw 2e-05',
'schedule': None,
'sensor_count': 200,
'sensor_grid': '*',
'simulation_folder': '.',
'thresholds': '-t 300 -lt 100 -ut 3000',
'wea': None}


Expand Down Expand Up @@ -125,7 +127,7 @@ def map_dag_inputs(self):
return inputs

def run(self):
yield [AnnualDaylightRayTracingWorkerbee(_input_params=self.map_dag_inputs)]
yield [AnnualDaylightRayTracing_d3bf888cWorkerbee(_input_params=self.map_dag_inputs)]
with open(os.path.join(self.execution_folder, 'annual_daylight_raytracing.done'), 'w') as out_file:
out_file.write('done!\n')

Expand Down Expand Up @@ -183,6 +185,71 @@ def output(self):
}


class CalculateAnnualMetrics(QueenbeeTask):
"""Calculate annual daylight metrics for annual daylight simulation."""

# DAG Input parameters
_input_params = luigi.DictParameter()

# Task inputs
@property
def thresholds(self):
return self._input_params['thresholds']

@property
def folder(self):
value = 'results'.replace('\\', '/')
return value if os.path.isabs(value) \
else os.path.join(self.initiation_folder, value)

@property
def schedule(self):
if self._input_params['schedule'] is None:
return None
value = self._input_params['schedule'].replace('\\', '/')
return value if os.path.isabs(value) \
else os.path.join(self.initiation_folder, value)

@property
def execution_folder(self):
return self._input_params['simulation_folder'].replace('\\', '/')

@property
def initiation_folder(self):
return self._input_params['simulation_folder'].replace('\\', '/')

@property
def params_folder(self):
return os.path.join(self.execution_folder, self._input_params['params_folder']).replace('\\', '/')

def command(self):
return 'honeybee-radiance post-process annual-daylight raw_results --schedule schedule.txt {thresholds} --sub_folder ../metrics'.format(thresholds=self.thresholds)

def requires(self):
return {'ParseSunUpHours': ParseSunUpHours(_input_params=self._input_params), 'AnnualDaylightRaytracing': AnnualDaylightRaytracing(_input_params=self._input_params)}

def output(self):
return {
'annual_metrics': luigi.LocalTarget(
os.path.join(self.execution_folder, 'metrics')
)
}

@property
def input_artifacts(self):
return [
{'name': 'folder', 'to': 'raw_results', 'from': self.folder, 'optional': False},
{'name': 'schedule', 'to': 'schedule.txt', 'from': self.schedule, 'optional': True}]

@property
def output_artifacts(self):
return [
{
'name': 'annual-metrics', 'from': 'metrics',
'to': os.path.join(self.execution_folder, 'metrics')
}]


class CreateDirectSky(QueenbeeTask):
"""Generate a sun-up sky matrix."""

Expand Down Expand Up @@ -241,7 +308,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'wea', 'to': 'sky.wea', 'from': self.wea}]
{'name': 'wea', 'to': 'sky.wea', 'from': self.wea, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -297,7 +364,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'model', 'to': 'model', 'from': self.model}]
{'name': 'model', 'to': 'model', 'from': self.model, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -359,8 +426,8 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'model', 'to': 'model', 'from': self.model},
{'name': 'sky', 'to': 'sky.sky', 'from': self.sky}]
{'name': 'model', 'to': 'model', 'from': self.model, 'optional': False},
{'name': 'sky', 'to': 'sky.sky', 'from': self.sky, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -423,7 +490,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'input_model', 'to': 'model.hbjson', 'from': self.input_model}]
{'name': 'input_model', 'to': 'model.hbjson', 'from': self.input_model, 'optional': False}]

@property
def output_artifacts(self):
Expand All @@ -449,6 +516,9 @@ class CreateSkyDome(QueenbeeTask):
# DAG Input parameters
_input_params = luigi.DictParameter()

# Task inputs
sky_density = luigi.Parameter(default='1')

@property
def execution_folder(self):
return self._input_params['simulation_folder'].replace('\\', '/')
Expand All @@ -462,7 +532,7 @@ def params_folder(self):
return os.path.join(self.execution_folder, self._input_params['params_folder']).replace('\\', '/')

def command(self):
return 'honeybee-radiance sky skydome --name rflux_sky.sky'
return 'honeybee-radiance sky skydome --name rflux_sky.sky --sky-density {sky_density}'.format(sky_density=self.sky_density)

def output(self):
return {
Expand Down Expand Up @@ -536,7 +606,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'wea', 'to': 'sky.wea', 'from': self.wea}]
{'name': 'wea', 'to': 'sky.wea', 'from': self.wea, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -595,7 +665,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'wea', 'to': 'sky.wea', 'from': self.wea}]
{'name': 'wea', 'to': 'sky.wea', 'from': self.wea, 'optional': False}]

@property
def output_artifacts(self):
Expand Down Expand Up @@ -652,7 +722,7 @@ def output(self):
@property
def input_artifacts(self):
return [
{'name': 'sun_modifiers', 'to': 'suns.mod', 'from': self.sun_modifiers}]
{'name': 'sun_modifiers', 'to': 'suns.mod', 'from': self.sun_modifiers, 'optional': False}]

@property
def output_artifacts(self):
Expand All @@ -663,7 +733,7 @@ def output_artifacts(self):
}]


class _MainOrchestrator(luigi.WrapperTask):
class _Main_d3bf888cOrchestrator(luigi.WrapperTask):
"""Runs all the tasks in this module."""
# user input for this module
_input_params = luigi.DictParameter()
Expand All @@ -675,4 +745,4 @@ def input_values(self):
return params

def requires(self):
return [AnnualDaylightRaytracing(_input_params=self.input_values), ParseSunUpHours(_input_params=self.input_values)]
return [CalculateAnnualMetrics(_input_params=self.input_values)]
Loading

0 comments on commit bd4ee03

Please sign in to comment.