Ejemplo n.º 1
0
class MergeImages(Function):
    """Merge several .HDR image files with similar starting name into one."""

    folder = Inputs.folder(
        description='Target folder with the input .HDR image files.',
        path='input_folder')

    name = Inputs.str(description='Base name for files to be merged.',
                      default='view')

    extension = Inputs.str(
        description='File extension including the . before the extension '
        '(e.g. .HDR, .pic, .unf)',
        default='.unf')

    scale_factor = Inputs.float(
        description='A number that will be used to scale the dimensions of the '
        'output image as it is filtered for anti-aliasing.',
        default=1)

    @command
    def merge_files(self):
        return 'honeybee-radiance view merge input_folder view ' \
            '{{self.extension}} --scale-factor {{self.scale_factor}} ' \
            '--name {{self.name}}'

    result_image = Outputs.file(description='Output combined image file.',
                                path='{{self.name}}.HDR')
class EnergyUseIntensity(Function):
    """Get information about energy use intensity from energy simulation SQLite files."""

    result_folder = Inputs.folder(
        description='Path to folder containing SQLite files that were generated '
        'by EnergyPlus. This can be a single EnergyPlus simulation folder or '
        'it can be a folder with multiple sql files, in which case EUI will '
        'be computed across all results.',
        path='result_folder')

    units = Inputs.str(
        description=
        'A switch to indicate whether the data in the resulting JSON '
        'should be in SI or IP units. Valid values are "si" and "ip".',
        default='si',
        spec={
            'type': 'string',
            'enum': ['si', 'ip']
        })

    @command
    def energy_use_intensity(self):
        return 'honeybee-energy result energy-use-intensity result_folder ' \
            '--{{inputs.units}} --output-file output.json'

    eui_json = Outputs.file(
        description=
        'A JSON object with the following keys - eui, total_floor_area, '
        'total_energy, end_uses. The eui value is the energy use intensity across '
        'the total floor area. The end_uses value is a dictionary containing a '
        'breakdown of the eui by end use.',
        path='output.json')
Ejemplo n.º 3
0
class CreateOctree(Function):
    """Generate an octree from a Radiance folder."""

    # inputs
    include_aperture = Inputs.str(
        default='include',
        description=
        'A value to indicate if the static aperture should be included in '
        'octree. Valid values are include and exclude. Default is include.',
        spec={
            'type': 'string',
            'enum': ['include', 'exclude']
        })

    black_out = Inputs.str(
        default='default',
        description=
        'A value to indicate if the black material should be used. Valid '
        'values are default and black. Default value is default.',
        spec={
            'type': 'string',
            'enum': ['black', 'default']
        })

    model = Inputs.folder(description='Path to Radiance model folder.',
                          path='model')

    @command
    def create_octree(self):
        return 'honeybee-radiance octree from-folder model --output scene.oct ' \
            '--{{self.include_aperture}}-aperture --{{self.black_out}}'

    # outputs
    scene_file = Outputs.file(description='Output octree file.',
                              path='scene.oct')
Ejemplo n.º 4
0
class MergeFiles(Function):
    """Merge several files with similar starting name into one."""

    name = Inputs.str(
        description='Base name for files to be merged.',
        default='grid'
    )

    extension = Inputs.str(
        description='File extension including the . before the extension (e.g. .res, '
        '.ill)'
    )

    folder = Inputs.folder(
        description='Target folder with the input files.',
        path='input_folder'
    )

    @command
    def merge_files(self):
        return 'honeybee-radiance grid merge input_folder grid ' \
            ' {{self.extension}} --name {{self.name}}'

    result_file = Outputs.file(
        description='Output result file.', path='{{self.name}}{{self.extension}}'
    )
Ejemplo n.º 5
0
class AnnualDaylightMetrics(Function):
    """Calculate annual daylight metrics for annual daylight simulation."""

    folder = Inputs.folder(
        description='This folder is an output folder of annual daylight recipe. Folder '
        'should include grids_info.json and sun-up-hours.txt. The command uses the list '
        'in grids_info.json to find the result files for each sensor grid.',
        path='raw_results'
    )

    schedule = Inputs.file(
        description='Path to an annual schedule file. Values should be 0-1 separated '
        'by new line. If not provided an 8-5 annual schedule will be created.',
        path='schedule.txt', optional=True
    )

    thresholds = Inputs.str(
        description='A string to change the threshold for daylight autonomy and useful '
        'daylight illuminance. Valid keys are -t for daylight autonomy threshold, -lt '
        'for the lower threshold for useful daylight illuminance and -ut for the upper '
        'threshold. The defult is -t 300 -lt 100 -ut 3000. The order of the keys is not '
        'important and you can include one or all of them. For instance if you only '
        'want to change the upper threshold to 2000 lux you should use -ut 2000 as '
        'the input.', default='-t 300 -lt 100 -ut 3000'
    )

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

    # outputs
    annual_metrics = Outputs.folder(
        description='Annual metrics folder. This folder includes all the other '
        'subfolders which are also exposed as separate outputs.', path='metrics'
    )

    daylight_autonomy = Outputs.folder(
        description='Daylight autonomy results.', path='metrics/da'
    )

    continuous_daylight_autonomy = Outputs.folder(
        description='Continuous daylight autonomy results.', path='metrics/cda'
    )

    useful_daylight_illuminance_lower = Outputs.folder(
        description='Lower useful daylight illuminance results.',
        path='metrics/udi_lower'
    )

    useful_daylight_illuminance = Outputs.folder(
        description='Useful daylight illuminance results.', path='metrics/udi'
    )

    useful_daylight_illuminance_upper = Outputs.folder(
        description='Upper useful daylight illuminance results.',
        path='metrics/udi_upper'
    )
class RayTracingPicture(Function):
    """Run ray-tracing with rpict command for an input octree and a view file.."""

    view = Inputs.file(description='Input view file.', path='view.vf')

    scene_file = Inputs.file(
        description='Path to an octree file to describe the scene.', path='scene.oct'
    )

    radiance_parameters = Inputs.str(
        description='Radiance parameters to be exposed within recipes. -h is '
        'usually already included in the fixed_radiance_parameters and -I will '
        'be overwritten based on the input metric.', default='-ab 2'
    )

    metric = Inputs.str(
        description='Text for the type of metric to be output from the calculation. '
        'Choose from: illuminance, irradiance, luminance, radiance.',
        default='luminance',
        spec={'type': 'string',
              'enum': ['illuminance', 'irradiance', 'luminance', 'radiance']}
    )

    resolution = Inputs.int(
        description='An integer for the maximum dimension of the image in pixels '
        '(either width or height depending on the input view angle and type).',
        spec={'type': 'integer', 'minimum': 1}, default=512
    )

    scale_factor = Inputs.float(
        description='A number that will be multiplied by the input resolution to '
        'scale the dimensions of the output image. This is useful in workflows if '
        'one plans to re-scale the image after the ray tracing calculation to '
        'improve anti-aliasing.', default=1
    )

    ambient_cache = Inputs.file(
        description='Path to the ambient cache if an overture calculation was '
        'specified. If unspecified, no ambient cache will be used.',
        path='view.amb', optional=True
    )

    bsdf_folder = Inputs.folder(
        description='Folder containing any BSDF files needed for ray tracing.',
        path='model/bsdf', optional=True
    )

    @command
    def ray_tracing(self):
        return 'honeybee-radiance rpict rpict scene.oct view.vf ' \
            '--rad-params "{{self.radiance_parameters}}" --metric {{self.metric}} ' \
            '--resolution {{self.resolution}} --scale-factor {{self.scale_factor}} ' \
            '--output view.HDR'

    result_image = Outputs.file(
        description='Path to the High Dynamic Range (HDR) image file of the '
        'input view.', path='view.HDR'
    )
class RayTracingPointInTime(Function):
    """Run ray-tracing and post-process the results for a point-in-time simulation."""

    radiance_parameters = Inputs.str(
        description='Radiance parameters to be exposed within recipes. -h is '
        'usually already included in the fixed_radiance_parameters and -I will '
        'be overwritten based on the input metric.',
        default='-ab 2')

    metric = Inputs.str(
        description=
        'Text for the type of metric to be output from the calculation. '
        'Choose from: illuminance, irradiance, luminance, radiance.',
        default='illuminance',
        spec={
            'type': 'string',
            'enum': ['illuminance', 'irradiance', 'luminance', 'radiance']
        })

    fixed_radiance_parameters = Inputs.str(
        description=
        'Parameters that are meant to be fixed for a given recipe and '
        'should not be overwritten by radiance_parameters input.',
        default='-h')

    grid = Inputs.file(description='Input sensor grid.', path='grid.pts')

    scene_file = Inputs.file(
        description='Path to an octree file to describe the scene.',
        path='scene.oct')

    bsdf_folder = Inputs.folder(
        description='Folder containing any BSDF files needed for ray tracing.',
        path='model/bsdf',
        optional=True)

    @command
    def ray_tracing(self):
        return 'honeybee-radiance raytrace point-in-time scene.oct grid.pts ' \
            '--rad-params "{{self.radiance_parameters}}" --rad-params-locked ' \
            '"{{self.fixed_radiance_parameters}}" --metric {{self.metric}} ' \
            '--output grid.res'

    result = Outputs.file(
        description=
        'Point-in-time result file. The result for each sensor is in a '
        'new line of the file. Values are in standard SI units of the input '
        'metric (lux, W/m2, cd/m2, W/m2-sr).',
        path='grid.res')
Ejemplo n.º 8
0
class SplitGridFromFolder(SplitGrid):
    """Split a single sensor grid file into multiple grids based on maximum number
    of sensors.

    This function takes a folder of sensor grids and find the target grid based on
    grid-name.
    """

    name = Inputs.str(description='Grid name.')

    input_grid = Inputs.folder(description='Path to sensor grids folder.', path='.')

    @command
    def split_grid(self):
        return 'honeybee-radiance grid split {{self.name}}.pts ' \
            '{{self.sensor_count}} --folder output --log-file output/grids_info.json'
Ejemplo n.º 9
0
class AnnualIrradianceMetrics(Function):
    """Calculate annual irradiance metrics for annual irradiance simulation."""

    folder = Inputs.folder(
        description='A folder output from and annual irradiance recipe.',
        path='raw_results')

    wea = Inputs.file(
        description=
        'The .wea file that was used in the annual irradiance simulation. '
        'This will be used to determine the duration of the analysis for computing '
        'average irradiance.',
        path='weather.wea')

    timestep = Inputs.int(
        description='The timestep of the Wea file, which is used to ensure the '
        'summed row of irradiance yields cumulative radiation over the time '
        'period of the Wea.',
        default=1)

    @command
    def calculate_irradiance_metrics(self):
        return 'honeybee-radiance post-process annual-irradiance raw_results ' \
            'weather.wea --timestep {{self.timestep}} --sub-folder ../metrics'

    # outputs
    metrics = Outputs.folder(
        description='Annual irradiance metrics folder. This folder includes all '
        'the other subfolders which are exposed as separate outputs.',
        path='metrics')

    average_irradiance = Outputs.folder(
        description=
        'Average irradiance in W/m2 for each sensor over the wea period.',
        path='metrics/average_irradiance')

    peak_irradiance = Outputs.folder(
        description=
        'The highest irradiance value in W/m2 for each sensor during '
        'the wea period.',
        path='metrics/average_irradiance')

    cumulative_radiation = Outputs.folder(
        description='The cumulative radiation in kWh/m2 for each sensor over '
        'the wea period.',
        path='metrics/cumulative_radiation')
Ejemplo n.º 10
0
class LeedIlluminanceCredits(Function):
    """Estimate LEED daylight credits from two point-in-time illuminance folders."""

    folder = Inputs.folder(
        description=
        'Project folder for a LEED illuminance simulation. It should '
        'contain a HBJSON model and two sub-folders of complete point-in-time '
        'illuminance simulations labeled "9AM" and "3PM". These two sub-folders should '
        'each have results folders that include a grids_info.json and .res files with '
        'illuminance values for each sensor. If Meshes are found for the sensor '
        'grids in the HBJSON file, they will be used to compute percentages '
        'of occupied floor area that pass vs. fail. Otherwise, all sensors will '
        'be assumed to represent an equal amount of floor area.',
        path='raw_results')

    glare_control_devices = Inputs.str(
        description=
        'A switch to note whether the model has "view-preserving automatic '
        '(with manual override) glare-control devices," which means that illuminance '
        'only needs to be above 300 lux and not between 300 and 3000 lux.',
        default='glare-control',
        spec={
            'type': 'string',
            'enum': ['glare-control', 'no-glare-control']
        })

    @command
    def calculate_leed_credits(self):
        return 'honeybee-radiance post-process leed-illuminance raw_results ' \
            '--{{self.glare_control_devices}} --sub-folder ../pass_fail ' \
            '--output-file credit_summary.json'

    # outputs
    pass_fail_results = Outputs.folder(
        description='Pass/Fail results folder. This folder includes results for '
        'each sensor indicating whether they pass or fail the LEED criteria.',
        path='pass_fail')

    credit_summary = Outputs.folder(
        description=
        'JSON file containing the number of LEED credits achieved and '
        'a summary of the percentage of the sensor grid area that meets the criteria.',
        path='credit_summary.json')
class RayTracingDaylightFactor(Function):
    """Run ray-tracing and post-process the results for a daylight factor simulation."""

    radiance_parameters = Inputs.str(
        description=
        'Radiance parameters to be exposed within recipes. -I and -h are '
        'usually already included in the fixed_radiance_parameters.',
        default='-ab 2')

    sky_illum = Inputs.int(
        description='Sky illuminance level for the sky included in octree.',
        default=100000)

    fixed_radiance_parameters = Inputs.str(
        description=
        'Parameters that are meant to be fixed for a given recipe and '
        'should not be overwritten by radiance_parameters input.',
        default='-I -h')

    grid = Inputs.file(description='Input sensor grid.', path='grid.pts')

    scene_file = Inputs.file(
        description='Path to an octree file to describe the scene.',
        path='scene.oct')

    bsdf_folder = Inputs.folder(
        description='Folder containing any BSDF files needed for ray tracing.',
        path='model/bsdf',
        optional=True)

    @command
    def ray_tracing(self):
        return 'honeybee-radiance raytrace daylight-factor scene.oct grid.pts ' \
            '--rad-params "{{self.radiance_parameters}}" --rad-params-locked ' \
            '"{{self.fixed_radiance_parameters}}" --sky-illum {{self.sky_illum}} ' \
            '--output grid.res'

    result = Outputs.file(
        description=
        'Daylight factor results file. The results for each sensor is in a '
        'new line.',
        path='grid.res')
class DaylightCoefficient(Function):
    """Calculate daylight coefficient for a grid of sensors from a sky matrix."""

    radiance_parameters = Inputs.str(
        description=
        'Radiance parameters. -I, -c 1 and -aa 0 are already included in '
        'the command.',
        default='')

    fixed_radiance_parameters = Inputs.str(
        description=
        'Radiance parameters. -I, -c 1 and -aa 0 are already included in '
        'the command.',
        default='-aa 0')

    sensor_count = Inputs.int(
        description='Number of maximum sensors in each generated grid.',
        spec={
            'type': 'integer',
            'minimum': 1
        })

    sky_matrix = Inputs.file(description='Path to a sky matrix.',
                             path='sky.mtx',
                             extensions=['mtx', 'smx'])

    sky_dome = Inputs.file(description='Path to a sky dome.', path='sky.dome')

    sensor_grid = Inputs.file(description='Path to sensor grid files.',
                              path='grid.pts',
                              extensions=['pts'])

    scene_file = Inputs.file(
        description='Path to an octree file to describe the scene.',
        path='scene.oct',
        extensions=['oct'])

    conversion = Inputs.str(
        description=
        'Conversion values as a string which will be passed to rmtxop -c.'
        'This option is useful to post-process the results from 3 RGB components into '
        'one as part of this command.',
        default='')

    order_by = Inputs.str(
        description=
        'An option to change how results are ordered in each row. By '
        'default each row are the results for each sensor during all the datetime. '
        'Valid options are sensor and datetime.',
        default='sensor',
        spec={
            'type': 'string',
            'enum': ['sensor', 'datetime']
        })

    output_format = Inputs.str(
        description=
        'Output format for converted results. Valid inputs are a, f and '
        'd for ASCII, float or double.',
        default='f',
        spec={
            'type': 'string',
            'enum': ['a', 'd', 'f']
        })

    bsdf_folder = Inputs.folder(
        description='Folder containing any BSDF files needed for ray tracing.',
        path='model/bsdf',
        optional=True)

    @command
    def run_daylight_coeff(self):
        return 'honeybee-radiance dc scoeff scene.oct grid.pts sky.dome sky.mtx ' \
            '--sensor-count {{self.sensor_count}} --output results.ill --rad-params ' \
            '"{{self.radiance_parameters}}" --rad-params-locked '\
            '"{{self.fixed_radiance_parameters}}" --conversion "{{self.conversion}}" ' \
            '--output-format {{self.output_format}} --order-by-{{self.order_by}}'

    result_file = Outputs.file(description='Output result file.',
                               path='results.ill')
Ejemplo n.º 13
0
class DaylightContribution(Function):
    """
    Calculate daylight contribution for a grid of sensors from a series of modifiers
    using rcontrib command.
    """

    radiance_parameters = Inputs.str(
        description='Radiance parameters. -I and -aa 0 are already included in '
        'the command.', default=''
    )

    fixed_radiance_parameters = Inputs.str(
        description='Radiance parameters. -I and -aa 0 are already included in '
        'the command.', default='-aa 0'
    )

    calculate_values = Inputs.str(
        description='A switch to indicate if the values should be multiplied. '
        'Otherwise the contribution is calculated as a coefficient. Default is set to '
        'value. Use coeff for contribution', default='value',
        spec={'type': 'string', 'enum': ['value', 'coeff']}
    )

    conversion = Inputs.str(
        description='Conversion values as a string which will be passed to rmtxop -c.',
        default=''
    )

    order_by = Inputs.str(
        description='An option to change how results are grouped in each row. By '
        'default each row are the results for each sensor during all the datetimes. '
        'Valid options are sensor and datetime.',
        default='sensor', spec={'type': 'string', 'enum': ['sensor', 'datetime']}
    )

    output_format = Inputs.str(
        description='Output format for converted results. Valid inputs are a, f and '
        'd for ASCII, float or double. If conversion is not provided you can change the '
        'output format using rad-params options.', default='a',
        spec={'type': 'string', 'enum': ['a', 'd', 'f']}
    )

    sensor_count = Inputs.int(
        description='Number of maximum sensors in each generated grid.',
        spec={'type': 'integer', 'minimum': 1}
    )

    modifiers = Inputs.file(
        description='Path to modifiers file. In most cases modifiers are sun modifiers.',
        path='suns.mod'
    )

    sensor_grid = Inputs.file(
        description='Path to sensor grid files.', path='grid.pts',
        extensions=['pts']
    )

    scene_file = Inputs.file(
        description='Path to an octree file to describe the scene.', path='scene.oct',
        extensions=['oct']
    )

    bsdf_folder = Inputs.folder(
        description='Folder containing any BSDF files needed for ray tracing.',
        path='model/bsdf', optional=True
    )

    @command
    def run_daylight_coeff(self):
        return 'honeybee-radiance dc scontrib scene.oct grid.pts suns.mod ' \
            '--{{self.calculate_values}} --sensor-count {{self.sensor_count}} ' \
            '--rad-params "{{self.radiance_parameters}}" --rad-params-locked ' \
            '"{{self.fixed_radiance_parameters}}" --conversion "{{self.conversion}}" ' \
            '--output-format {{self.output_format}} --output results.ill ' \
            '--order-by-{{self.order_by}}'

    result_file = Outputs.file(description='Output result file.', path='results.ill')
Ejemplo n.º 14
0
class SplitView(Function):
    """Split a single view file (.vf) into multiple smaller views."""

    view_count = Inputs.int(
        description=
        'Number of views into which the input view will be subdivided.',
        spec={
            'type': 'integer',
            'minimum': 1
        })

    input_view = Inputs.file(description='Input view file.', path='view.vf')

    overture = Inputs.str(
        description='A switch to note whether an ambient file (.amb) should be '
        'generated for an overture calculation before the view is split into smaller '
        'views. With an overture calculation, the ambient file (aka ambient cache) is '
        'first populated with values. Thereby ensuring that - when reused to create '
        'an image - Radiance uses interpolation between already calculated values '
        'rather than less reliable extrapolation. The overture calculation has '
        'comparatively small computation time to full rendering but is single-core '
        'can become time consuming in situations with very high numbers of '
        'rendering multiprocessors.',
        default='overture',
        spec={
            'type': 'string',
            'enum': ['overture', 'skip-overture']
        })

    scene_file = Inputs.file(
        description=
        'Path to an octree file for the overture calculation. This must be '
        'specified when the overture is not skipped.',
        path='scene.oct',
        optional=True)

    radiance_parameters = Inputs.str(
        description='Radiance parameters for the overture calculation. '
        'If unspecified, default rpict paramters will be used.',
        default='-ab 2')

    bsdf_folder = Inputs.folder(
        description='Folder containing any BSDF files needed for ray tracing.',
        path='model/bsdf',
        optional=True)

    @command
    def split_view(self):
        return 'honeybee-radiance view split view.vf ' \
            '{{self.view_count}} --{{self.overture}} ' \
            '--octree {{self.scene_file}} --rad-params "{{self.radiance_parameters}}" ' \
            '--folder output --log-file output/views_info.json'

    views_list = Outputs.list(
        description='A JSON array that includes information about generated '
        'views.',
        path='output/views_info.json')

    output_folder = Outputs.folder(
        description='Output folder with new view files.', path='output')

    ambient_cache = Outputs.file(
        description='Path to the ambient cache if an overture calculation was '
        'specified.',
        path='output/view.amb',
        optional=True)
Ejemplo n.º 15
0
class ShortwaveMrtMap(Function):
    """Get CSV files with maps of shortwave MRT Deltas from Radiance results."""

    epw = Inputs.file(
        description='Weather file used to compute sun positions.',
        path='weather.epw',
        extensions=['epw'])

    indirect_irradiance = Inputs.file(
        description=
        'A Radiance .ill containing the indirect irradiance for each '
        'sensor. Alternatively, if the indirect-is-total input is used, then this '
        'input should be the total irradiance for each sensor.',
        path='indirect.ill',
        extensions=['ill', 'irr'])

    direct_irradiance = Inputs.file(
        description=
        'A Radiance .ill containing direct irradiance for each sensor.',
        path='direct.ill',
        extensions=['ill', 'irr'])

    ref_irradiance = Inputs.file(
        description=
        'A Radiance .ill containing ground-reflected irradiance for each '
        'sensor.',
        path='ref.ill',
        extensions=['ill', 'irr'])

    sun_up_hours = Inputs.file(
        description=
        'A sun-up-hours.txt file output by Radiance and aligns with the '
        'input irradiance files.',
        path='sun-up-hours.txt')

    contributions = Inputs.folder(
        description='An optional folder containing sub-folders of irradiance '
        'contributions from dynamic aperture groups. There should be one sub-folder '
        'per window groups and each one should contain three .ill files named '
        'direct.ill, indirect.ill and reflected.ill. If specified, these will be '
        'added to the irradiance inputs before computing shortwave MRT deltas.',
        path='dynamic',
        optional=True)

    transmittance_contribs = Inputs.folder(
        description=
        'An optional folder containing a transmittance schedule JSON '
        'and sub-folders of irradiance results that exclude the shade from the '
        'calculation. There should be one sub-folder per window groups and each '
        'one should contain three .ill files named direct.ill, indirect.ill and '
        'reflected.ill. If specified, these will be added to the irradiance inputs '
        'before computing shortwave MRT deltas.',
        path='dyn_shade',
        optional=True)

    trans_schedules = Inputs.file(
        description=
        'An optional path to a transmittance schedule JSON output by '
        'the honeybee-energy model-transmittance-schedules command, which is '
        'coordinated with the --transmittance-contribs.',
        path='trans_schedules.json',
        optional=True)

    solarcal_par = Inputs.str(
        description='A SolarCalParameter string to customize the assumptions of '
        'the SolarCal model.',
        default='--posture seated --sharp 135 '
        '--absorptivity 0.7 --emissivity 0.95')

    run_period = Inputs.str(
        description=
        'An AnalysisPeriod string to set the start and end dates of the '
        'analysis (eg. "6/21 to 9/21 between 8 and 16 @1"). If unspecified, results '
        'will be annual.',
        default='')

    indirect_is_total = Inputs.str(
        description=
        'A switch to note whether the indirect-irradiance argument is '
        'actually the total irradiance.',
        default='is-indirect',
        spec={
            'type': 'string',
            'enum': ['is-indirect', 'indirect-is-total']
        })

    @command
    def run_shortwave_map(self):
        return 'ladybug-comfort map shortwave-mrt weather.epw indirect.ill direct.ill ' \
            'ref.ill sun-up-hours.txt --contributions dynamic ' \
            '--transmittance-contribs dyn_shade --trans-schedule-json ' \
            'trans_schedules.json --solarcal-par "{{self.solarcal_par}}" ' \
            '--run-period "{{self.run_period}}" --{{self.indirect_is_total}} ' \
            '--output-file shortwave.csv'

    shortwave_mrt_map = Outputs.file(
        description='CSV file containing a map of shortwave MRT deltas.',
        path='shortwave.csv')