Exemple #1
0
    def to_radiance(self, output_type=1, wea_file=None, output_name=None):
        """Return Radiance command to generate the sky.

        Note that you need to write the wea to a file (in.wea) before running this
        command.

        Alternatively you can use write method which will write the wea data to a file.

        Args:
            output_type: An integer between 0 to 1 for output type.
                * 0 = output in W/m2/sr visible
                * 1 = output in W/m2/sr solar (default)
            wea_file: Path to wea file (default: in.wea).
            output_name: A name for output files (default: suns).
        """
        output_type = typing.int_in_range(output_type, 0, 1,
                                          'SunMatrix output type')
        wea_file = wea_file or 'in.wea'
        output_name = output_name or 'suns'
        if self.north == 0:
            command = 'gendaymtx -n -D {0}.mtx -M {0}.mod -O{1} {2}'.format(
                output_name, output_type, wea_file)
        else:
            command = 'gendaymtx -n -D {0}.mtx -M {0}.mod -O{1} -r {3} {2}'.format(
                output_name, output_type, wea_file, self.north)

        return command
Exemple #2
0
    def __init__(self,
                 identifier,
                 values,
                 schedule_type_limit=None,
                 timestep=1,
                 start_date=Date(1, 1),
                 placeholder_value=0,
                 interpolate=False):
        """Initialize Schedule FixedInterval."""
        self._locked = False  # unlocked by default

        # set all of the properties that impact how many values can be assigned
        self._timestep = int_in_range(timestep, 1, 60, 'schedule timestep')
        assert self._timestep in self.VALIDTIMESTEPS, 'ScheduleFixedInterval timestep ' \
            '"{}" is invalid. Must be one of the following:\n{}'.format(
                timestep, self.VALIDTIMESTEPS)
        start_date = Date(1, 1) if start_date is None else start_date
        assert isinstance(start_date, Date), 'Expected ladybug Date for ' \
            'ScheduleFixedInterval start_date. Got {}.'.format(type(start_date))
        self._start_date = start_date

        # set the values and all properties that can be re-set
        self.identifier = identifier
        self._display_name = None
        self.values = values
        self.schedule_type_limit = schedule_type_limit
        self.placeholder_value = placeholder_value
        self.interpolate = interpolate
Exemple #3
0
    def __init__(self,
                 name,
                 values,
                 schedule_type_limit=None,
                 timestep=1,
                 start_date=Date(1, 1),
                 placeholder_value=0,
                 interpolate=False):
        """Initialize Schedule FixedInterval.

        Args:
            name: Text string for the schedule name. Must be <= 100 characters.
                Can include spaces but special characters will be stripped out.
            values: A list of values occuring at a fixed interval over the simulation.
                Typically, this should be a list of 8760 values for each hour of the
                year but it can be a shorter list if you don't plan on using it in
                an annual simulation. In this case, the start_date should probably be
                different than the default 1 Jan (it should instead be the start date
                of your simulation). This list can also have a length much greater
                than 8760 if a timestep greater than 1 is used.
            schedule_type_limit: A ScheduleTypeLimit object that will be used to
                validate schedule values against upper/lower limits and assign units
                to the schedule values. If None, no validation will occur.
            timestep: An integer for the number of steps per hour that the input
                values correspond to.  For example, if each value represents 30
                minutes, the timestep is 2. For 15 minutes, it is 4. Default is 1,
                meaning each value represents a single hour. Must be one of the
                following: (1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60).
            start_date: A ladybug Date object to note when the the input values begin
                to take effect. Default is 1 Jan for a non-leap year. Note that this
                default usually should not be changed unless you plan to run a
                simulation that is much shorter than a year and/or you plan to run
                the simulation for a leap year.
            placeholder_value: A value that will be used for all times not covered
                by the input values. Typically, your simulation should not need to
                use this value if the input values completely cover the simulation
                period. However, a default value may still be necessary for EnergyPlus
                to run. Default: 0.
            interpolate: Boolean to note whether values in between intervals should be
                linearly interpolated or whether successive values should take effect
                immediately upon the beginning time corrsponding to them. Default: False
        """
        self._locked = False  # unlocked by default

        # set all of the properties that impact how many values can be assigned
        self._timestep = int_in_range(timestep, 1, 60, 'schedule timestep')
        assert self._timestep in self.VALIDTIMESTEPS, 'ScheduleFixedInterval timestep ' \
            '"{}" is invalid. Must be one of the following:\n{}'.format(
                timestep, self.VALIDTIMESTEPS)
        assert isinstance(start_date, Date), 'Expected ladybug Date for ' \
            'ScheduleFixedInterval start_date. Got {}.'.format(type(start_date))
        self._start_date = start_date

        # set the values and all properties that can be re-set
        self.name = name
        self.values = values
        self.schedule_type_limit = schedule_type_limit
        self.placeholder_value = placeholder_value
        self.interpolate = interpolate
Exemple #4
0
    def to_files(self, folder, count, base_name=None, mkdir=False):
        """Split this sensor grid and write them to several files.

        Args:
            folder: Target folder.
            count: Number of files.
            base_name: Optional text for a unique base_name for sensor files.
                (Default: self.display_name)
            mkdir: A boolean to indicate if the folder should be created in case it
                doesn't exist already (Default: False).

        Returns:
            A list of dicts containing the grid name, path to the grid and full path
            to the grid.
        """
        count = typing.int_in_range(count, 1, input_name='file count')
        base_name = base_name or self.display_name
        if count == 1 or self.count == 0:
            name = '%s_0000' % base_name
            full_path = self.to_file(folder, name, mkdir)
            return [
                {'name': name if not name.endswith('.pts') else name.replace('.pts', ''),
                 'path': name + '.pts' if not name.endswith('.pts') else name,
                 'full_path': full_path,
                 'count': self.count}
            ]
        # calculate sensor count in each file
        sc = int(round(self.count / count))
        sensors = iter(self._sensors)
        for fc in range(count - 1):
            name = '%s_%04d.pts' % (base_name, fc)
            content = '\n'.join((next(sensors).to_radiance() for _ in range(sc)))
            futil.write_to_file_by_name(folder, name, content + '\n', mkdir)

        # write whatever is left to the last file
        name = '%s_%04d.pts' % (base_name, count - 1)
        content = '\n'.join((sensor.to_radiance() for sensor in sensors))
        futil.write_to_file_by_name(folder, name, content + '\n', mkdir)

        grids_info = []

        for c in range(count):
            name = '%s_%04d' % (base_name, c)
            path = '%s.pts' % name
            full_path = os.path.join(folder, path)

            grids_info.append({
                'name': name,
                'path': path,
                'full_path': full_path,
                'count': sc
            })

        # adjust the count for the last grid
        grids_info[-1]['count'] = self.count - sc * (count - 1)

        return grids_info
Exemple #5
0
    def to_radiance(self,
                    output_type=0,
                    wea_file=None,
                    output_name=None,
                    cumulative=False,
                    components=0):
        """Return Radiance command to generate the sky.

        Note that you need to write the wea to a file (in.wea) before running this
        command.

        Alternatively you can use write method which will write the wea data to a file.

        Args:
            output_type: An integer between 0 to 1 for output type.
                * 0 = output in W/m2/sr visible (default)
                * 1 = output in W/m2/sr solar
            wea_file: Path to wea file (default: in.wea).
            output_name: A name for output files (default: sky_mtx).
            cumulative: A boolean to generate cumulative sky. This option is only
                available in Radiance 5.3 and higher versions (default: False).
            components: An integer between 0-2 to note the distribution of which
                components should be included. 0 might be used to include both sun and
                sky contribution. 1 may be used to produce a sun-only matrix, with no sky
                contributions.  Alternatively, 2 may be used to exclude any sun component
                from the output.  If there is a sun in the description, gendaymtx will
                include its contribution in the four nearest sky patches, distributing
                energy according to centroid proximity (default: 0).
        """
        output_type = typing.int_in_range(output_type, 0, 1,
                                          'SkyMatrix output type')
        wea_file = wea_file or 'in.wea'
        output_name = output_name or 'sky'

        options = ['-O{}'.format(output_type)]
        if self.density != 1:
            options.append('-m %d' % self.density)
        if self.north != 0:
            options.append('-r {}'.format(self.north))
        if cumulative:
            options.append('-A')
        if components == 1:
            # sun-only
            options.append('-d')
        elif components == 2:
            # sky only
            options.append('-s')
        options.append(wea_file)
        # add all the other options here
        command = 'gendaymtx {0} > {1}.mtx'.format(' '.join(options),
                                                   output_name)

        return command
Exemple #6
0
def test_int_in_range():
    """Test the float_in_range method."""
    assert isinstance(int_in_range(2.0, 0, 10), int)
    assert isinstance(int_in_range(2, 0, 10), int)
    assert isinstance(int_in_range('2', 0, 10), int)

    with pytest.raises(AssertionError):
        assert isinstance(int_in_range(2, 0, 1), float)
    with pytest.raises(TypeError):
        assert isinstance(int_in_range('two', 0, 10), float)
    with pytest.raises(TypeError):
        assert isinstance(int_in_range([2], 0, 10), float)

    try:
        int_in_range(2, 0, 1, 'test number')
    except AssertionError as e:
        assert 'test number' in str(e)
    def to_radiance(self, output_type=0):
        """Return Radiance description of the sky.

        Args:
            output_type: An integer between 0 to 2 for output type.
                * 0 = output in W/m2/sr visible (default)
                * 1 = output in W/m2/sr solar
                * 2 = output in lm/m2/sr luminance
        """
        output = typing.int_in_range(output_type, 0, 2, 'Sky output type')
        command = '!gendaylit -ang %.6f %.6f -O %d -W %d %d -g %.3f' % (
            self.altitude, self.azimuth - 180.0, output,
            self.direct_normal_irradiance, self._diffuse_horizontal_irradiance,
            self.ground_reflectance)

        return '%s\n\n%s\n\n%s\n' % (command, self.sky_hemisphere,
                                     self.ground_hemisphere)
Exemple #8
0
    def to_radiance(self, density=1):
        """Radiance definition for SkyDome.

        Args:
            density: Sky patch subdivision density. This values is similar to -m option
                in gendaymtx command. Default is 1 which means 145 sky patches and 1
                patch for the ground.

                One can add to the resolution typically by factors of two (2, 4, 8, ...)
                which yields a higher resolution sky using the Reinhart patch subdivision
                For example, setting density to 4 yields a sky with 2305 patches plus one
                patch for the ground.
        """
        density = typing.int_in_range(density,
                                      1,
                                      input_name='Sky subdivision density')
        return '#@rfluxmtx h=u u=Y\n%s\n\n#@rfluxmtx h=r%d u=Y\n%s\n' % (
            self.ground_hemisphere, density, self.sky_hemisphere)
Exemple #9
0
 def workers(self, value):
     self._workers = int_in_range(value, mi=1, input_name='recipe workers')
Exemple #10
0
 def density(self, value):
     typing.int_in_range(value,
                         1,
                         input_name='SkyMatrix subdivision density')
     self._density = value
Exemple #11
0
 def end_month(self, value):
     if value == autocalculate:
         self._end_month = None
     else:
         self._end_month = \
             int_in_range(value, 1, 12, 'end_month')
Exemple #12
0
    def values_at_timestep(self, timestep=1, start_date=None, end_date=None):
        """Get a list of sequential schedule values over the year at a given timestep.

        Note that there are two possible ways that these values can be mapped to
        corresponding times:

        * The EnergyPlus interpretation that uses "time until"
        * The Ladybug Tools interpretation that uses "time of beginning"

        The EnergyPlus interpretation should be used when aligning the schedule
        with EnergyPlus results while the Ladybug Tools interpretation should be
        used when aligning the schedule with ladybug DataCollections or other
        ladybug objects. See the ScheduleDay.values_at_timestep method
        documentation for a complete description of these two interpretations.

        Args:
            timestep: An integer for the number of steps per hour at which to return
                the resulting values.
            start_date: An optional ladybug Date object for when to start the list
                of values. Default: 1 Jan with a leap year equal to self.start_date.
            end_date: An optional ladybug Date object for when to end the list
                of values. Default: 31 Dec with a leap year equal to self.start_date.
        """
        # ensure that the input start_date and end_date are valid
        if start_date is None:
            start_date = Date(1, 1, self.is_leap_year)
        else:
            if start_date.leap_year is not self.is_leap_year:
                start_date = Date(start_date.month, start_date.day,
                                  self.is_leap_year)
        if end_date is None:
            end_date = Date(12, 31, self.is_leap_year)
        else:
            if end_date.leap_year is not self.is_leap_year:
                end_date = Date(end_date.month, end_date.day,
                                self.is_leap_year)
        assert start_date <= end_date, 'ScheduleFixedInterval values_at_timestep()' \
            'start_date must come before end_date. {} comes after {}.'.format(
                start_date, end_date)

        # convert the schedule's values to the desired timestep
        timestep = int_in_range(timestep, 1, 60, 'schedule timestep')
        assert timestep in self.VALIDTIMESTEPS, 'ScheduleFixedInterval timestep ' \
            '"{}" is invalid. Must be one of the following:\n{}'.format(
                timestep, self.VALIDTIMESTEPS)
        if timestep == self.timestep:
            vals_at_step = list(self._values)
        elif timestep < self.timestep:
            assert self.timestep % timestep == 0, \
                'Schedule timestep({}) must be evenly divisible by target timestep({})' \
                .format(self.timestep, timestep)
            vals_at_step = []
            ind = 0
            step_ratio = self.timestep / timestep
            for i in xrange(int(len(self._values) / step_ratio)):
                vals_at_step.append(self._values[int(ind)])
                ind += step_ratio
        else:
            assert timestep % self.timestep == 0, \
                'Target timestep({}) must be evenly divisible by schedule timestep({})' \
                .format(timestep, self.timestep)
            vals_at_step = []
            if self.interpolate:
                data_len = len(self._values)
                for d in xrange(data_len):
                    for _v in self._xxrange(self[d], self[(d + 1) % data_len],
                                            timestep):
                        vals_at_step.append(_v)
            else:
                n_step = int(timestep / self.timestep)
                for val in self._values:
                    for stp in xrange(n_step):
                        vals_at_step.append(val)

        # build up the full list of values accounting for start and end dates
        end_dt = self.end_date_time
        if self.start_date.doy <= end_dt.doy:
            start_filler = []
            end_filler = []
            if start_date < self.start_date:
                num_vals = int(
                    (self.start_date.doy - start_date.doy) * 24 * timestep)
                start_filler = [
                    self.placeholder_value for i in xrange(num_vals)
                ]
            elif start_date > self.start_date:
                start_i = int(
                    (start_date.doy - self.start_date.doy) * 24 * timestep)
                vals_at_step = vals_at_step[start_i:]
            if ((end_dt.int_hoy + 1) / 24) < end_date.doy:
                num_vals = int((end_date.doy * 24 * timestep) - 1 -
                               (end_dt.hoy * timestep))
                end_filler = [self.placeholder_value for i in xrange(num_vals)]
            elif ((end_dt.int_hoy + 1) / 24) > end_date.doy:
                end_diff = int((end_dt.hoy * timestep) -
                               (end_date.doy * 24 * timestep))
                end_i = len(vals_at_step) - end_diff - 1
                vals_at_step = vals_at_step[:end_i]
            return start_filler + vals_at_step + end_filler
        else:
            n_dpy = 365 if not self.is_leap_year else 366
            start_yr_i = int((n_dpy - self.start_date.doy + 1) * 24 * timestep)
            n_mid = (8760 * timestep) - len(vals_at_step)
            end_vals = vals_at_step[:start_yr_i]
            start_vals = vals_at_step[start_yr_i:]
            mid_vals = [self.placeholder_value for i in xrange(n_mid)]
            all_vals = start_vals + mid_vals + end_vals
            start_i = (start_date.doy - 1) * 24 * timestep
            end_i = end_date.doy * 24 * timestep
            return all_vals[start_i:end_i]
Exemple #13
0
 def multiplier(self, value):
     self._multiplier = int_in_range(value, 1, input_name='room multiplier')
Exemple #14
0
 def sky_density(self, v):
     density = typing.int_in_range(v,
                                   1,
                                   input_name='Sky subdivision density')
     self._sky_density = density
Exemple #15
0
 def maximum_figures(self, value):
     self._maximum_figures = int_in_range(
         value, 200, input_name='shadow calculation maximum figures')
Exemple #16
0
 def calculation_frequency(self, value):
     self._calculation_frequency = int_in_range(
         value, 1, input_name='shadow calculation calculation frequency')
Exemple #17
0
 def start_month(self, value):
     if value == autocalculate:
         self._start_month = None
     else:
         self._start_month = \
             int_in_range(value, 1, 12, 'start_month')
Exemple #18
0
 def sky_type(self, value):
     value = typing.int_in_range(value, 0, 5, 'CIE sky type')
     self._sky_type = value
Exemple #19
0
 def workers(self, value):
     if value is not None:
         value = int_in_range(value, mi=1, input_name='recipe workers')
     self._workers = value
Exemple #20
0
 def simulation_step(self, value):
     if value is not None:
         value = int_in_range(value, 0,
                              len(self._base_collection) - 1,
                              'simulation_step')
     self._simulation_step = value