Example #1
0
def two_matrix_operations(
    first_mtx, second_mtx, operator, keep_header, conversion, output_mtx,
    output_format, dry_run
        ):
    """Operations between two Radiance matrices.

    \b
    args:
        first-mtx: Path to fist matrix.
        second-mtx: Path to second matrix.

    """
    try:
        cmd = 'rmtxop -f{output_format} "{first_mtx}" {operator} "{second_mtx}"'.format(
            output_format=output_format, first_mtx=first_mtx,
            operator=handle_operator(operator), second_mtx=second_mtx
        )

        if conversion and conversion.strip():
            cmd = cmd + ' -c {conversion}'.format(conversion=conversion)

        if not keep_header:
            cmd = cmd + ' | getinfo - '
        if output_mtx:
            cmd = cmd + ' > "%s"' % output_mtx
        if dry_run:
            click.echo(cmd)
            sys.exit(0)

        run_command(cmd, env=folders.env)
    except Exception:
        _logger.exception('Operation on two Radiance matrix failed.')
        sys.exit(1)
    else:
        sys.exit(0)
def three_phase_calc(sky_vector, view_matrix, t_matrix, daylight_matrix,
                     output_matrix, options, dry_run):
    """Matrix multiplication for view matrix, transmission matrix, daylight matrix and
    sky matrix."""

    try:
        base_options = DctimestepOptions()
        options = options.strip() if options else None
        if options:
            base_options.update_from_string(options)

        cmd = Dctimestep.three_phase_calc(sky_vector=sky_vector,
                                          view_matrix=view_matrix,
                                          t_matrix=t_matrix,
                                          daylight_matrix=daylight_matrix,
                                          output=output_matrix,
                                          options=base_options)
        if dry_run:
            click.echo(cmd)
        else:
            run_command(cmd.to_radiance(), env=folders.env)
    except OSError:
        os.system(cmd.to_radiance())
    except Exception:
        _logger.exception(
            'Failed to run matrix multiplication calculations with '
            'dctimestep')
        sys.exit(1)
    else:
        sys.exit(0)
Example #3
0
def sunpath_from_wea_rad(wea, north, sky_type, sky_density, output_format,
                         hourly, visible, all_hours, folder, name, log_file,
                         dry_run):
    """Generate a climate-based sky matrix from a Wea file using radiance's gendaymtx.

    \b
    Args:
        wea: Path to a wea file.
    """
    try:
        if not os.path.exists(folder):
            os.makedirs(folder)
        output = os.path.join(folder, '%s.mtx' % name)
        opt = GendaymtxOptions()
        opt.r = north
        opt.O = '0' if visible else '1'
        if sky_type == 'total':
            pass
        elif sky_type == 'sun-only':
            opt.d = True
        elif sky_type == 'no-sun':
            opt.s = True

        if output_format == 'ASCII':
            pass
        elif output_format == 'float':
            opt.o = 'f'
        elif output_format == 'double':
            opt.o = 'd'

        if not hourly:
            opt.A = True

        if not all_hours:
            opt.u = True
        if sky_density > 1:
            opt.m = sky_density

        cmd = Gendaymtx(wea=wea, options=opt, output=output)
        if dry_run:
            print(cmd.to_radiance())
            sys.exit(0)

        try:
            run_command(cmd.to_radiance(), env=folders.env)
        except RuntimeError as e:  # likely a nighttime Wea; write blank .mtx file
            with open(output, 'w') as wf:
                wf.write('')
        files = [{
            'path': os.path.relpath(output, folder),
            'full_path': output
        }]
        log_file.write(json.dumps(files))

    except Exception:
        _logger.exception('Failed to generate sunpath.')
        sys.exit(1)
    else:
        sys.exit(0)
Example #4
0
def rcontrib_command_with_postprocess(
        octree, sensor_grid, modifiers, sensor_count, rad_params, rad_params_locked,
        output, coeff, conversion, output_format, dry_run
):
    """Run rcontrib command for an input octree and a sensor grid.

    octree: Path to octree file.

    sensor-grid: Path to sensor grid file.

    modifiers: Path to modifiers file.

    """
    try:
        options = RcontribOptions()
        # parse input radiance parameters
        if rad_params:
            options.update_from_string(rad_params.strip())
        # overwrite input values with protected ones
        if rad_params_locked:
            options.update_from_string(rad_params_locked.strip())

        if not sensor_count:
            raise ValueError('for time-being sensor count must be provided.')

        if coeff:
            options.update_from_string('-aa 0.0 -V- -y {}'.format(sensor_count))
        else:
            options.update_from_string('-aa 0.0 -V+ -y {}'.format(sensor_count))

        options.M = modifiers
        # create command.
        rcontrib = Rcontrib(
            options=options, octree=octree, sensors=sensor_grid
        )
        cmd = rcontrib.to_radiance().replace('\\', '/')
        if conversion and conversion.strip():
            # pass the values to rmtxop
            cmd = '{command} | rmtxop -f{output_format} - -c {conversion}'.format(
                command=cmd, output_format=output_format, conversion=conversion
            )
        if output:
            cmd = '{command} > {output}'.format(command=cmd, output=output)

        if dry_run:
            click.echo(cmd)
        else:
            # rcontrib.run(env=env)
            run_command(cmd, env=folders.env)
    except Exception:
        _logger.exception('Failed to run ray-tracing command.')
        sys.exit(1)
    else:
        sys.exit(0)
Example #5
0
def rfluxmtx_command_with_postprocess(
        octree, sensor_grid, sky_dome, sky_mtx, sensor_count, rad_params,
        rad_params_locked, output, conversion, output_format, dry_run
):
    """Run rfluxmtx command and pass the results to rmtxop.

    octree: Path to octree file.

    sensor-grid: Path to sensor grid file.

    sky-dome: Path to sky dome for coefficient calculation.

    sky-mtx: Path to sky matrix.

    """
    try:
        options = RfluxmtxOptions()
        # parse input radiance parameters
        if rad_params.strip():
            options.update_from_string(rad_params.strip())
        # overwrite input values with protected ones
        if rad_params_locked.strip():
            options.update_from_string(rad_params_locked.strip())

        if not sensor_count:
            raise ValueError('Number of sensors in senor grid must be provided!')

        options.update_from_string('-aa 0.0 -faf -y {}'.format(sensor_count))

        # create command.
        cmd_template = 'rfluxmtx {rad_params} - {sky_dome} -i {octree} < ' \
            '{sensors} | rmtxop -f{output_format} - {sky_mtx}'

        if conversion and conversion.strip():
            cmd_template = cmd_template + ' -c %s' % conversion

        if output:
            cmd_template = cmd_template + ' > {output}'.format(output=output)

        cmd = cmd_template.format(
            rad_params=options.to_radiance(), sky_dome=sky_dome, octree=octree,
            sensors=sensor_grid, output_format=output_format, sky_mtx=sky_mtx
        )

        if dry_run:
            click.echo(cmd)
        else:
            run_command(cmd, env=folders.env)
    except Exception:
        _logger.exception('Failed to run rfluxmtx command.')
        sys.exit(1)
    else:
        sys.exit(0)
Example #6
0
def three_matrix_operations(
    first_mtx, second_mtx, third_mtx, operator_one, operator_two, keep_header,
    conversion, output_mtx, output_format, dry_run
        ):
    """Operations between two Radiance matrices.

    \b
    Args:
        first-mtx: Path to fist matrix.
        second-mtx: Path to second matrix.
        third-mtx: Path to third matrix.
    """
    try:
        # first check to be sure there are sun-up hours; if so, write a blank file
        if os.path.getsize(first_mtx) == 0 or os.path.getsize(second_mtx) == 0 \
                or os.path.getsize(third_mtx) == 0:
            if output_mtx is not None:
                with open(output_mtx, 'w') as wf:
                    wf.write('')
            return

        cmd = 'rmtxop -f{output_format} "{first_mtx}" {operator_one} "{second_mtx}" ' \
            ' {operator_two} "{third_mtx}"'.format(
                output_format=output_format, first_mtx=first_mtx,
                operator_one=handle_operator(operator_one), second_mtx=second_mtx,
                operator_two=handle_operator(operator_two), third_mtx=third_mtx
            )

        if conversion and conversion.strip():
            cmd = cmd + ' -c {conversion}'.format(conversion=conversion)

        if not keep_header:
            cmd = cmd + ' | getinfo - '

        if output_mtx:
            cmd = cmd + ' > "%s"' % output_mtx

        if dry_run:
            click.echo(cmd)
            sys.exit(0)

        run_command(cmd, env=folders.env)
    except Exception:
        _logger.exception('Operation on three Radiance matrix failed.')
        sys.exit(1)
    else:
        sys.exit(0)
Example #7
0
def sunpath_from_wea_rad(wea, north, folder, name, visible, log_file, dry_run):
    """Generate a climate-based sunpath from a Wea file using radiance's gendaymtx.

    This command also generates a mod file which includes all the modifiers in sunpath.
    mod file is usually used with rcontrib command to indicate the list of modifiers.
    Since rcontrib command has a hard limit of 10,000 modifiers in a single run the files
    will be broken down into multiple files if number of modifiers is more than 10000
    modifiers.

    \b
    Args:
        wea: Path to a wea file.

    """
    try:
        if not os.path.exists(folder):
            os.makedirs(folder)
        opt = GendaymtxOptions()
        opt.n = True
        opt.D = os.path.join(folder, name + '.mtx').replace('\\', '//')
        opt.M = os.path.join(folder, name + '.mod').replace('\\', '//')
        opt.r = north
        opt.O = '0' if visible else '1'

        cmd = Gendaymtx(wea=wea, options=opt)

        if dry_run:
            print(cmd.to_radiance())
            sys.exit(0)

        run_command(cmd.to_radiance(), env=folders.env)
        files = [{
            'path': os.path.relpath(path, folder),
            'full_path': path
        } for path in (opt.D.value, opt.M.value)]

        log_file.write(json.dumps(files))
    except Exception:
        _logger.exception('Failed to generate sunpath.')
        sys.exit(1)
    else:
        sys.exit(0)
Example #8
0
def transpose_mtx(input_mtx, output_mtx, dry_run):
    """Transpose a Radiance matrix.

    \b
    Args:
        input_mtx: Path to input matrix file.
    """
    try:
        cmd = 'rcollate -t "%s" ' % input_mtx
        if output_mtx:
            cmd = cmd + ' > "%s"' % output_mtx
        if dry_run:
            click.echo(cmd)
            sys.exit(0)
        run_command(cmd, env=folders.env)
    except Exception:
        _logger.exception('Matrix transpose command failed.')
        sys.exit(1)
    else:
        sys.exit(0)
def three_phase_rmtxop(view_matrix, t_matrix, daylight_matrix, sky_vector,
                       output_matrix, output_format, illuminance,
                       remove_header, dry_run):
    """Matrix multiplication for view matrix, transmission matrix, daylight matrix and
    sky matrix."""

    try:
        options = RmtxopOptions()
        options.f = output_format
        matrices = [view_matrix, t_matrix, daylight_matrix, sky_vector]

        if illuminance:
            # rmtxop concatenation
            calc = Rmtxop(matrices=matrices)

            cmd = Rmtxop(options=options)
            cmd.transforms = [['47.4', '119.9', '11.6']]
            cmd.matrices = calc
        else:
            cmd = Rmtxop(options=options, matrices=matrices)

        if remove_header:
            getinfo = Getinfo.remove_header(output=output_matrix)
            cmd.pipe_to = getinfo
        else:
            cmd.output = output_matrix

        if dry_run:
            click.echo(cmd)
        else:
            run_command(cmd.to_radiance(), env=folders.env)
    except OSError:
        os.system(cmd.to_radiance())
    except Exception:
        _logger.exception(
            'Failed to run matrix multiplication calculations with rmtxop')
        sys.exit(1)
    else:
        sys.exit(0)
Example #10
0
def rcontrib_command_with_postprocess(octree, sensor_grid, modifiers,
                                      sensor_count, rad_params,
                                      rad_params_locked, output, coeff,
                                      conversion, multiply_by, output_format,
                                      order_by_sensor, keep_header, dry_run):
    """Run rcontrib command for an input octree and a sensor grid.

    \b
    Args:
        octree: Path to octree file.
        sensor-grid: Path to sensor grid file.
        modifiers: Path to modifiers file.
    """
    try:
        # first check to be sure there are sun-up hours; if so, write a blank file
        if os.path.getsize(modifiers) == 0:
            if output is not None:
                with open(output, 'w') as wf:
                    wf.write('')
            return

        options = RcontribOptions()
        # parse input radiance parameters
        if rad_params:
            options.update_from_string(rad_params.strip())
        # overwrite input values with protected ones
        if rad_params_locked:
            options.update_from_string(rad_params_locked.strip())

        if not sensor_count:
            sensor_count = sensor_count_from_file(sensor_grid)

        if coeff:
            options.update_from_string(
                '-aa 0.0 -V- -y {}'.format(sensor_count))
        else:
            options.update_from_string(
                '-aa 0.0 -V+ -y {}'.format(sensor_count))

        options.M = modifiers
        # create command.
        rcontrib = Rcontrib(options=options,
                            octree=octree,
                            sensors=sensor_grid)
        cmd = rcontrib.to_radiance().replace('\\', '/')

        if conversion and conversion.strip():
            if multiply_by != 1:
                conversion = ' '.join(
                    str(c * multiply_by) for c in conversion.split())
            # pass the values to rmtxop
            cmd = '{command} | rmtxop -f{output_format} - -c {conversion}'.format(
                command=cmd,
                output_format=output_format,
                conversion=conversion)
        elif multiply_by != 1:
            conversion = '{mult} {mult} {mult}'.format(mult=multiply_by)
            cmd = '{command} | rmtxop -f{output_format} - -c {conversion}'.format(
                command=cmd,
                output_format=output_format,
                conversion=conversion)

        if order_by_sensor is not True:
            cmd = cmd + ' -t '
        if not keep_header:
            cmd = cmd + ' | getinfo - '
        if output:
            cmd = '{command} > {output}'.format(command=cmd, output=output)

        if dry_run:
            click.echo(cmd)
        else:
            # rcontrib.run(env=env)
            run_command(cmd, env=folders.env)
    except Exception:
        _logger.exception('Failed to run ray-tracing command.')
        sys.exit(1)
    else:
        sys.exit(0)
Example #11
0
def rfluxmtx_command_with_postprocess(octree, sensor_grid, sky_dome, sky_mtx,
                                      sensor_count, rad_params,
                                      rad_params_locked, output, conversion,
                                      multiply_by, output_format,
                                      order_by_sensor, keep_header, dry_run):
    """Run rfluxmtx command and pass the results to rmtxop.

    octree: Path to octree file.

    sensor-grid: Path to sensor grid file.

    sky-dome: Path to sky dome for coefficient calculation.

    sky-mtx: Path to sky matrix.

    """
    try:
        # first check to be sure there are sun-up hours; if so, write a blank file
        if os.path.getsize(sky_mtx) == 0:
            if output is not None:
                with open(output, 'w') as wf:
                    wf.write('')
            return

        options = RfluxmtxOptions()
        # parse input radiance parameters
        if rad_params:
            options.update_from_string(rad_params.strip())
        # overwrite input values with protected ones
        if rad_params_locked:
            options.update_from_string(rad_params_locked.strip())

        if not sensor_count:
            sensor_count = sensor_count_from_file(sensor_grid)

        options.update_from_string('-aa 0.0 -faf -y {}'.format(sensor_count))

        # create command.
        cmd_template = 'rfluxmtx {rad_params} - "{sky_dome}" -i """{octree}""" < ' \
            '"{sensors}" | rmtxop -f{output_format} - "{sky_mtx}"'

        if conversion and conversion.strip():
            if multiply_by != 1:
                conversion = ' '.join(
                    str(c * multiply_by) for c in conversion.split())
            cmd_template = cmd_template + ' -c %s' % conversion
        elif multiply_by != 1:
            conversion = '{mult} {mult} {mult}'.format(mult=multiply_by)
            cmd_template = cmd_template + ' -c %s' % conversion

        if not order_by_sensor:
            cmd_template = cmd_template + ' -t '

        if not keep_header:
            cmd_template = cmd_template + ' | getinfo - '
        if output:
            cmd_template = cmd_template + ' > "{output}"'.format(output=output)

        cmd = cmd_template.format(rad_params=options.to_radiance(),
                                  sky_dome=sky_dome,
                                  octree=octree,
                                  sensors=sensor_grid,
                                  output_format=output_format,
                                  sky_mtx=sky_mtx)

        if dry_run:
            click.echo(cmd)
        else:
            run_command(cmd, env=folders.env)
    except Exception:
        _logger.exception('Failed to run rfluxmtx command.')
        sys.exit(1)
    else:
        sys.exit(0)
Example #12
0
def create_view_factor_modifiers(model_file, exclude_sky, exclude_ground,
                                 individual_shades, triangulate, folder, name):
    """Translate a Model into an Octree and corresponding modifier list for view factors.

    \b
    Args:
        model_file: Full path to a Model JSON file (HBJSON) or a Model pkl (HBpkl) file.
    """
    try:
        # create the directory if it's not there
        if not os.path.isdir(folder):
            preparedir(folder)

        # load the model and ensure the properties align with the energy model
        model = Model.from_file(model_file)
        original_units = None
        if model.units != 'Meters':
            original_units = model.units
            model.convert_to_units('Meters')
        for room in model.rooms:
            room.remove_colinear_vertices_envelope(tolerance=0.01,
                                                   delete_degenerate=True)
        if original_units is not None:
            model.convert_to_units(original_units)

        # triangulate the sub-faces if requested
        if triangulate:
            apertures, parents_to_edit = model.triangulated_apertures()
            for tri_aps, edit_infos in zip(apertures, parents_to_edit):
                if len(edit_infos) == 3:
                    for room in model._rooms:
                        if room.identifier == edit_infos[2]:
                            break
                    for face in room._faces:
                        if face.identifier == edit_infos[1]:
                            break
                    for i, ap in enumerate(face._apertures):
                        if ap.identifier == edit_infos[0]:
                            break
                    face._apertures.pop(i)  # remove the aperture to replace
                    face._apertures.extend(tri_aps)
            doors, parents_to_edit = model.triangulated_doors()
            for tri_drs, edit_infos in zip(doors, parents_to_edit):
                if len(edit_infos) == 3:
                    for room in model._rooms:
                        if room.identifier == edit_infos[2]:
                            break
                    for face in room._faces:
                        if face.identifier == edit_infos[1]:
                            break
                    for i, dr in enumerate(face._doors):
                        if dr.identifier == edit_infos[0]:
                            break
                    face._doors.pop(i)  # remove the doors to replace
                    face._doors.extend(tri_drs)

        # set values to be used throughout the modifier assignment
        offset = model.tolerance * -1
        white_plastic = Plastic('white_plastic', 1, 1, 1)
        geo_strs, mod_strs, mod_names = [], [], []

        def _add_geo_and_modifier(hb_obj):
            """Add a honeybee object to the geometry and modifier strings."""
            mod_name = '%s_mod' % hb_obj.identifier
            mod_names.append(mod_name)
            white_plastic.identifier = mod_name
            rad_poly = Polygon(hb_obj.identifier, hb_obj.vertices,
                               white_plastic)
            geo_strs.append(rad_poly.to_radiance(False, False, False))
            mod_strs.append(white_plastic.to_radiance(True, False, False))

        # loop through all geometry in the model and get radiance strings
        for room in model.rooms:
            for face in room.faces:
                if not isinstance(face.type, AirBoundary):
                    if isinstance(face.boundary_condition, Surface):
                        face.move(face.normal * offset)
                    _add_geo_and_modifier(face)
                for ap in face.apertures:
                    _add_geo_and_modifier(ap)
                for dr in face.doors:
                    _add_geo_and_modifier(dr)
        all_shades = model.shades + model._orphaned_faces + \
            model._orphaned_apertures + model._orphaned_doors
        if individual_shades:
            for shade in all_shades:
                _add_geo_and_modifier(shade)
        else:
            white_plastic.identifier = 'shade_plastic_mod'
            mod_names.append(white_plastic.identifier)
            mod_strs.append(white_plastic.to_radiance(True, False, False))
            for shade in all_shades:
                rad_poly = Polygon(shade.identifier, shade.vertices,
                                   white_plastic)
                geo_strs.append(rad_poly.to_radiance(False, False, False))

        # add the ground and sky domes if requested
        if not exclude_sky:
            mod_names.append('sky_glow_mod')
            mod_strs.append('void glow sky_glow_mod 0 0 4 1 1 1 0')
            geo_strs.append('sky_glow_mod source sky_dome 0 0 4 0 0 1 180')
        if not exclude_ground:
            mod_names.append('ground_glow_mod')
            mod_strs.append('void glow ground_glow_mod 0 0 4 1 1 1 0')
            geo_strs.append(
                'ground_glow_mod source ground_dome 0 0 4 0 0 -1 180')

        # write the radiance strings to the output folder
        geo_file = os.path.join(folder, '{}.rad'.format(name))
        mod_file = os.path.join(folder, '{}.mod'.format(name))
        oct_file = os.path.join(folder, '{}.oct'.format(name))
        with open(geo_file, 'w') as gf:
            gf.write('\n\n'.join(mod_strs + geo_strs))
        with open(mod_file, 'w') as mf:
            mf.write('\n'.join(mod_names))

        # use the radiance files to create an octree
        cmd = Oconv(output=oct_file, inputs=[geo_file])
        cmd.options.f = True
        run_command(cmd.to_radiance(), env=folders.env)
    except Exception as e:
        _logger.exception('Model translation failed.\n{}'.format(e))
        sys.exit(1)
    else:
        sys.exit(0)
Example #13
0
def rcontrib_command_with_view_postprocess(octree, sensor_grid, modifiers,
                                           ray_count, rad_params,
                                           rad_params_locked, folder, name):
    """Run rcontrib to get spherical view factors from a sensor grid.

    \b
    Args:
        octree: Path to octree file.
        sensor-grid: Path to sensor grid file.
        modifiers: Path to modifiers file.
    """
    try:
        # create the directory if it's not there
        if not os.path.isdir(folder):
            preparedir(folder)

        # generate the ray vectors to be used in the view factor calculation
        if ray_count == 6:
            rays = ((1, 0, 0), (0, 1, 0), (0, 0, 1), (-1, 0, 0), (0, -1, 0),
                    (0, 0, -1))
        else:
            rays = _fibonacci_spiral(ray_count)
        ray_str = [' {} {} {}\n'.format(*ray) for ray in rays]

        # create a new .pts file with the view vectors
        ray_file = os.path.abspath(os.path.join(folder, '{}.pts'.format(name)))
        total_rays = 0
        with open(sensor_grid) as sg_file:
            with open(ray_file, 'w') as r_file:
                for line in sg_file:
                    for ray in ray_str:
                        try:
                            r_file.write(' '.join(line.split()[:3]) + ray)
                            total_rays += 1
                        except Exception:
                            pass  # we are at the end of the file

        # set up the Rcontrib options
        options = RcontribOptions()
        if rad_params:  # parse input radiance parameters
            options.update_from_string(rad_params.strip())
        if rad_params_locked:  # overwrite input values with protected ones
            options.update_from_string(rad_params_locked.strip())
        # overwrite specific options that would otherwise break the command
        options.M = modifiers
        options.update_from_string('-I -V- -y {}'.format(total_rays))

        # create the rcontrib command and run it
        mtx_file = os.path.abspath(os.path.join(folder, '{}.mtx'.format(name)))
        rcontrib = Rcontrib(options=options, octree=octree, sensors=ray_file)
        cmd = rcontrib.to_radiance().replace('\\', '/')
        cmd = '{} | rmtxop -fa - -c .333 .333 .334'.format(cmd)
        cmd = '{}  | getinfo - > {}'.format(cmd, mtx_file.replace('\\', '/'))
        run_command(cmd, env=folders.env)

        # load the resulting matrix and process the results into view factors
        view_fac_mtx = []
        with open(mtx_file) as mtx_data:
            while True:
                sens_lines = list(islice(mtx_data, ray_count))
                if not sens_lines:
                    break
                sens_mtx = ((float(v) for v in ln.strip().split())
                            for ln in sens_lines)
                s_facs = []
                for sens_facs in zip(*sens_mtx):
                    s_facs.append(sum(sens_facs) / (math.pi * ray_count))
                view_fac_mtx.append(s_facs)

        # write the final view factors into a CSV file
        view_file = os.path.join(folder, '{}.csv'.format(name))
        with open(view_file, 'w') as v_file:
            for facs in view_fac_mtx:
                v_file.write(','.join((str(v) for v in facs)) + '\n')
    except Exception:
        _logger.exception('Failed to comput view factor contributions.')
        sys.exit(1)
    else:
        sys.exit(0)