def test_to_file(): wea = './tests/assets/wea/denver.wea' wea = Wea.from_file(wea) sun_mtx = SunMatrix(wea) sun_mtx_file = sun_mtx.to_file('./tests/assets/temp', mkdir=True) assert os.path.isfile(sun_mtx_file) with open(sun_mtx_file, 'r') as skyf: content = skyf.read() assert sun_mtx.to_radiance() in str(content)
def test_from_monthly_average(): wea = './tests/assets/wea/denver.wea' wea = Wea.from_file(wea) sky1 = ClimateBased.from_wea_monthly_average(wea, 1, 8) epw = './tests/assets/epw/denver.epw' epw = EPW(epw) sky2 = ClimateBased.from_epw_monthly_average(epw, 1, 8) assert sky1.direct_normal_irradiance == sky2.direct_normal_irradiance assert sky1.diffuse_horizontal_irradiance == sky2.diffuse_horizontal_irradiance
def test_global_and_direct_horizontal(): """Test the global horizontal irradiance on method.""" stat_path = './tests/assets/stat/chicago.stat' wea_from_stat = Wea.from_stat_file(stat_path) diffuse_horiz_rad = wea_from_stat.diffuse_horizontal_irradiance direct_horiz_rad = wea_from_stat.direct_horizontal_irradiance glob_horiz_rad = wea_from_stat.global_horizontal_irradiance assert [x for x in glob_horiz_rad] == pytest.approx( [x + y for x, y in zip(diffuse_horiz_rad, direct_horiz_rad)], rel=1e-3)
def test_to_and_from_dict(): wea = './tests/assets/wea/denver.wea' wea = Wea.from_file(wea) sun_mtx = SunMatrix(wea) sun_mtx_from_dict = sun_mtx.from_dict(sun_mtx.to_dict()) # update this once Wea class has equality method implemeneted assert sun_mtx.wea.location == sun_mtx_from_dict.wea.location assert sun_mtx.wea.direct_normal_irradiance.values == \ sun_mtx_from_dict.wea.direct_normal_irradiance.values assert sun_mtx.wea.direct_normal_irradiance.datetimes == \ sun_mtx_from_dict.wea.direct_normal_irradiance.datetimes
def test_global_and_direct_horizontal(self): """Test the global horizontal radiation on method.""" stat_path = './tests/stat/chicago.stat' wea_from_stat = Wea.from_stat_file(stat_path) diffuse_horiz_rad = wea_from_stat.diffuse_horizontal_radiation direct_horiz_rad = wea_from_stat.direct_horizontal_radiation glob_horiz_rad = wea_from_stat.global_horizontal_radiation assert [x.value for x in glob_horiz_rad] == pytest.approx( [x + y for x, y in zip(diffuse_horiz_rad, direct_horiz_rad)], rel=1e-3)
def test_filter_by_sun_up(): """Test the filter_by_sun_up method""" epw_path = './tests/assets/epw/chicago.epw' wea_from_epw = Wea.from_epw_file(epw_path) wea = wea_from_epw.filter_by_sun_up() assert isinstance(wea.direct_normal_irradiance, HourlyDiscontinuousCollection) assert isinstance(wea.diffuse_horizontal_irradiance, HourlyDiscontinuousCollection) assert not wea.is_annual assert not wea.is_continuous assert len(wea) == 4427 assert wea.datetimes[0].hour == 7
def test_filter_by_hoys_and_moys(): """Test the filter_by_hoys and the filter_by_moys method""" epw_path = './tests/assets/epw/chicago.epw' wea_from_epw = Wea.from_epw_file(epw_path) hoys = list(range(24)) filtered_wea = wea_from_epw.filter_by_hoys(hoys) assert len(filtered_wea) == len(hoys) moys = list(range(0, 24 * 60, 60)) filtered_wea = wea_from_epw.filter_by_moys(moys) assert len(filtered_wea) == len(moys)
def test_leap_year(): """Test clear sky with leap year.""" location = Location( 'Chicago Ohare Intl Ap', '-', 'USA', 41.98, -87.92, -6.0, 201.0) wea = Wea.from_ashrae_clear_sky(location, is_leap_year=True) assert wea.diffuse_horizontal_irradiance.datetimes[1416].month == 2 assert wea.diffuse_horizontal_irradiance.datetimes[1416].day == 29 assert wea.diffuse_horizontal_irradiance.datetimes[1416].hour == 0 assert wea.diffuse_horizontal_irradiance.datetimes[1416 + 12].month == 2 assert wea.diffuse_horizontal_irradiance.datetimes[1416 + 12].day == 29 assert wea.diffuse_horizontal_irradiance.datetimes[1416 + 12].hour == 12
def test_from_epw_fine_timestep(): """Test import from epw""" epw_path = './tests/assets/epw/chicago.epw' wea_from_epw = Wea.from_epw_file(epw_path, 2) assert wea_from_epw.location.city == 'Chicago Ohare Intl Ap' assert wea_from_epw.timestep == 2 assert wea_from_epw.direct_normal_irradiance[15] == 22 assert wea_from_epw.direct_normal_irradiance.datetimes[15].hour == 7 assert wea_from_epw.direct_normal_irradiance.datetimes[15].minute == 30 assert wea_from_epw.direct_normal_irradiance[17] == 397 assert wea_from_epw.direct_normal_irradiance.datetimes[17].hour == 8 assert wea_from_epw.direct_normal_irradiance.datetimes[17].minute == 30
def test_check_defaults(): wea = './tests/assets/wea/denver.wea' wea = Wea.from_file(wea) sun_mtx = SunMatrix(wea) assert sun_mtx.wea == wea assert sun_mtx.north == 0 assert sun_mtx.location == wea.location sun_mtx_radiance = sun_mtx.to_radiance() assert 'gendaymtx -n -D suns.mtx' in sun_mtx_radiance assert '-M suns.mod' in sun_mtx_radiance assert '-O1 in.wea' in sun_mtx_radiance assert sun_mtx.is_climate_based is True assert sun_mtx.is_point_in_time is False
def test_check_defaults(): wea = './tests/assets/wea/denver.wea' wea = Wea.from_file(wea) sky_mtx = SkyMatrix(wea) assert sky_mtx.wea == wea assert sky_mtx.north == 0 assert sky_mtx.density == 1 assert sky_mtx.location == wea.location sky_mtx_radiance = sky_mtx.to_radiance() # gendaymtx -O0 in.wea > sky.mtx assert '> sky.mtx' in sky_mtx_radiance assert '-O0 in.wea' in sky_mtx_radiance assert sky_mtx.is_climate_based is True assert sky_mtx.is_point_in_time is False
def from_epw_file(cls, epw_file, sky_density=1, north=0, hoys=None, mode=0, suffix=None): """Create sky from an epw file.""" return cls(Wea.from_epw_file(epw_file), sky_density, north, hoys, mode, suffix=suffix)
def test_from_file(): """Test import from wea file.""" wea_file = './tests/assets/wea/san_francisco_10min.wea' with pytest.raises(Exception): Wea.from_file(wea_file) # wrong timestep wea = Wea.from_file(wea_file, 6) assert isinstance(wea.direct_normal_irradiance, HourlyContinuousCollection) assert isinstance(wea.diffuse_horizontal_irradiance, HourlyContinuousCollection) assert wea.is_annual assert wea.is_continuous assert wea.direct_normal_irradiance[45] == 69 assert wea.diffuse_horizontal_irradiance[45] == 1 assert wea.direct_normal_irradiance[46] == 137 assert wea.diffuse_horizontal_irradiance[46] == 7 direct, diff = wea.get_irradiance_value(1, 1, 8) assert direct == 273 assert diff == 20 direct, diff = wea.get_irradiance_value_for_hoy(8) assert direct == 273 assert diff == 20
def from_json(cls, rec_json): """Create sky from json file { "wea": {}, // ladybug wea schema "sky_density": int, // [1] Tregenza Sky, [2] Reinhart Sky, etc. (Default: 1) "north": float, // Angle in degrees between 0-360 to indicate North "hoys": [], // List of hours for generating the sky "mode": int, // Sky mode, integer between 0 and 2 "suffix": string //Suffix for sky matrix } """ wea = Wea.from_json(rec_json["wea"]) return cls(wea, rec_json["sky_density"], rec_json["north"], \ rec_json["hoys"], rec_json["mode"], rec_json["suffix"])
def from_json(cls, rec_json): """Create sky from json file { "wea": {}, // ladybug wea schema "sky_density": int, // [1] Tregenza Sky, [2] Reinhart Sky, etc. (Default: 1) "north": float, // Angle in degrees between 0-360 to indicate North "hoys": [], // List of hours for generating the sky "mode": int, // Sky mode, integer between 0 and 2 "suffix": string //Suffix for sky matrix } """ wea = Wea.from_dict(rec_json["wea"]) return cls(wea, rec_json["sky_density"], rec_json["north"], rec_json["hoys"], rec_json["mode"], rec_json["suffix"])
def test_from_stat(): """Test import from stat""" stat_path = './tests/assets/stat/chicago.stat' wea_from_stat = Wea.from_stat_file(stat_path) assert wea_from_stat.location.city == 'Chicago Ohare Intl Ap' assert wea_from_stat.timestep == 1 assert wea_from_stat.diffuse_horizontal_irradiance[0] == \ pytest.approx(0, rel=1e-3) assert wea_from_stat.direct_normal_irradiance[0] == \ pytest.approx(0, rel=1e-3) assert wea_from_stat.diffuse_horizontal_irradiance[12] == \ pytest.approx(87.44171, rel=1e-3) assert wea_from_stat.direct_normal_irradiance[12] == \ pytest.approx(810.693919, rel=1e-3)
def test_directional_irradiance(): """Test the directional irradiance method.""" stat_path = './tests/assets/stat/chicago.stat' wea_from_stat = Wea.from_stat_file(stat_path) srf_total, srf_direct, srf_diffuse, srf_reflect = \ wea_from_stat.directional_irradiance(90) diffuse_horiz_rad = wea_from_stat.diffuse_horizontal_irradiance direct_horiz_rad = wea_from_stat.direct_horizontal_irradiance glob_horiz_rad = wea_from_stat.global_horizontal_irradiance assert srf_total.values == pytest.approx(glob_horiz_rad.values, rel=1e-3) assert srf_direct.values == pytest.approx(direct_horiz_rad.values, rel=1e-3) assert srf_diffuse.values == pytest.approx(diffuse_horiz_rad.values, rel=1e-3) assert srf_reflect.values == pytest.approx([0] * 8760, rel=1e-3)
def test_from_clear_sky(): """Test from original clear sky""" location = Location( 'Chicago Ohare Intl Ap', '-', 'USA', 41.98, -87.92, -6.0, 201.0) wea_from_clear_sky = Wea.from_ashrae_clear_sky(location) assert wea_from_clear_sky.location.city == 'Chicago Ohare Intl Ap' assert wea_from_clear_sky.timestep == 1 assert wea_from_clear_sky.diffuse_horizontal_irradiance[0] == \ pytest.approx(0, rel=1e-3) assert wea_from_clear_sky.direct_normal_irradiance[0] == \ pytest.approx(0, rel=1e-3) assert wea_from_clear_sky.diffuse_horizontal_irradiance[12] == \ pytest.approx(60.72258, rel=1e-3) assert wea_from_clear_sky.direct_normal_irradiance[12] == \ pytest.approx(857.00439, rel=1e-3)
def test_body_dir_from_dir_normal(): """Test body_solar_flux_from_parts gainst its horizontal counterpart.""" wea_obj = Wea.from_epw_file('./tests/epw/chicago.epw') diff_hr = wea_obj.diffuse_horizontal_irradiance.values dir_nr = wea_obj.direct_normal_irradiance.values dir_hr = wea_obj.direct_horizontal_irradiance.values dts = wea_obj.datetimes sp = Sunpath.from_location(wea_obj.location) for i in xrange(8760): sun = sp.calculate_sun_from_date_time(dts[i]) alt, az = sun.altitude, sun.azimuth sharp = sharp_from_solar_and_body_azimuth(az, 180) sflux1 = body_solar_flux_from_parts(diff_hr[i], dir_nr[i], alt, sharp) sflux2 = body_solar_flux_from_horiz_solar(diff_hr[i], dir_hr[i], alt, sharp) assert sflux1 == pytest.approx(sflux2, rel=1e-2)
def test_estimate_illuminance(): """Test the directional irradiance method.""" epw_path = './tests/assets/epw/chicago.epw' epw = EPW(epw_path) wea = Wea.from_epw_file(epw_path) glob_ill, dir_ill, diff_ill, zen_lum = \ wea.estimate_illuminance_components(epw.dew_point_temperature) assert glob_ill.bounds[0] == pytest.approx(0, rel=1e-3) assert 100000 < glob_ill.bounds[1] < 125000 assert dir_ill.bounds[0] == pytest.approx(0, rel=1e-3) assert 75000 < dir_ill.bounds[1] < 125000 assert diff_ill.bounds[0] == pytest.approx(0, rel=1e-3) assert 50000 < diff_ill.bounds[1] < 100000 assert zen_lum.bounds[0] == pytest.approx(0, rel=1e-3) assert zen_lum.bounds[1] < 35000
def test_filter_by_analysis_period(): """Test the filter_by_analysis_period method""" epw_path = './tests/assets/epw/chicago.epw' wea_from_epw = Wea.from_epw_file(epw_path) a_period = AnalysisPeriod(12, 21, 0, 3, 21, 23) filtered_wea = wea_from_epw.filter_by_analysis_period(a_period) assert len(filtered_wea) == len(filtered_wea.diffuse_horizontal_irradiance.values) \ == len(a_period) assert not filtered_wea.is_annual assert filtered_wea.is_continuous wea_path = './tests/assets/wea/chicago_winter.wea' filtered_wea.write(wea_path) assert os.path.isfile(wea_path) assert os.stat(wea_path).st_size > 1 os.remove(wea_path)
def test_from_zhang_huang(self): """Test from zhang huang solar model""" location = Location('Chicago Ohare Intl Ap', 'USA', 41.98, -87.92, -6.0, 201.0) cc = [0.5] * 8760 rh = [50] * 8760 dbt = [20] * 8760 ws = [2] * 8760 wea_from_zh = Wea.from_zhang_huang_solar_model(location, cc, rh, dbt, ws) assert wea_from_zh.location.city == 'Chicago Ohare Intl Ap' assert wea_from_zh.timestep == 1 assert wea_from_zh.global_horizontal_radiation[0].value == \ pytest.approx(0, rel=1e-3) assert wea_from_zh.global_horizontal_radiation[12].value == \ pytest.approx(281.97887, rel=1e-3)
def epw_to_wea(epw_file, analysis_period, timestep, output_file): """Translate an .epw file to a .wea file. \b Args: epw_file: Path to an .epw file. """ try: wea_obj = Wea.from_epw_file(epw_file, timestep) analysis_period = _load_analysis_period_str(analysis_period) if analysis_period is not None: wea_obj = wea_obj.filter_by_analysis_period(analysis_period) output_file.write(wea_obj.to_file_string()) except Exception as e: _logger.exception('Wea translation failed.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def wea_to_constant(wea_file, value, output_file): """Convert a Wea file to have a constant value for each datetime. This is useful in workflows where hourly irradiance values are inconsequential to the analysis and one is only using the Wea as a format to pass location and datetime information (eg. for direct sun hours). \b Args: wea_file: Full path to .wea file. """ try: output_file.write(Wea.to_constant_value(wea_file, value)) except Exception as e: _logger.exception('Wea translation failed.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def solar_tracking(folder, sun_up_hours, wea, north, tracking_increment, sub_folder): """Postprocess a list of result folders to account for dynamic solar tracking. \b This function essentially takes .ill files for each state of a dynamic tracking system and produces a single .ill file that models the tracking behavior. \b Args: folder: Results folder containing sub-folders that each represent a state of the dynamic solar tracking system. Each sub-folder should contain .ill files for that state and the names of these .ill files should be the same across all sub-folders. sun_up_hours: The .txt file containing the sun-up hours that were simulated. wea: The .wea file that was used in the simulation. This will be used to determine the solar positions. """ try: # load all of the result sub-folders in the folder and sort them models = [f for f in os.listdir(folder) if os.path.isdir(os.path.join(folder, f)) and os.path.isfile(os.path.join(folder, f, 'grids_info.json'))] model_num = [int(''.join([i for i in f if i.isdigit()])) for f in models] sorted_models = [x for _, x in sorted(zip(model_num, models))] models = [os.path.join(folder, f) for f in sorted_models] dest_folder = os.path.join(folder, sub_folder) if len(models) == 1: # not a dynamic system; just copy the files if not os.path.isdir(dest_folder): os.mkdir(dest_folder) for f in os.listdir(models[0]): shutil.copyfile( os.path.join(models[0], f), os.path.join(dest_folder, f)) else: wea_obj = Wea.from_file(wea) post_process_solar_tracking( models, sun_up_hours, wea_obj.location, north, tracking_increment, dest_folder) except Exception: _logger.exception('Failed to compute irradiance metrics.') sys.exit(1) else: sys.exit(0)
def test_from_epw(): """Test import from epw""" epw_path = './tests/epw/chicago.epw' wea_from_epw = Wea.from_epw_file(epw_path) assert wea_from_epw.location.city == 'Chicago Ohare Intl Ap' assert wea_from_epw.timestep == 1 assert wea_from_epw.direct_normal_irradiance[7] == 22 assert wea_from_epw.direct_normal_irradiance.datetimes[7].hour == 7 assert wea_from_epw.direct_normal_irradiance.datetimes[7].minute == 0 assert wea_from_epw.direct_normal_irradiance[8] == 397 assert wea_from_epw.direct_normal_irradiance.datetimes[8].hour == 8 assert wea_from_epw.direct_normal_irradiance.datetimes[8].minute == 0 # diffuse horizontal irradiance assert wea_from_epw.diffuse_horizontal_irradiance[7] == 10 assert wea_from_epw.diffuse_horizontal_irradiance.datetimes[7].hour == 7 assert wea_from_epw.diffuse_horizontal_irradiance.datetimes[7].minute == 0 assert wea_from_epw.diffuse_horizontal_irradiance[8] == 47 assert wea_from_epw.diffuse_horizontal_irradiance.datetimes[8].hour == 8 assert wea_from_epw.diffuse_horizontal_irradiance.datetimes[8].minute == 0
def test_from_zhang_huang(self): """Test from zhang huang solar model""" path = './tests/epw/chicago.epw' epw = EPW(path) wea_from_zh = Wea.from_zhang_huang_solar( epw.location, epw.total_sky_cover.values, epw.relative_humidity.values, epw.dry_bulb_temperature.values, epw.wind_speed.values, epw.atmospheric_station_pressure.values) assert wea_from_zh.location.city == 'Chicago Ohare Intl Ap' assert wea_from_zh.timestep == 1 assert wea_from_zh.global_horizontal_irradiance[0] == \ pytest.approx(0, rel=1e-1) assert wea_from_zh.global_horizontal_irradiance[12] == \ pytest.approx(417.312, rel=1e-1) assert wea_from_zh.direct_normal_irradiance[12] == \ pytest.approx(654.52, rel=1e-1) assert wea_from_zh.diffuse_horizontal_irradiance[12] == \ pytest.approx(144.51, rel=1e-1)
def test_directional_radiation(self): """Test the directinal radiation method.""" stat_path = './tests/stat/chicago.stat' wea_from_stat = Wea.from_stat_file(stat_path) srf_total, srf_direct, srf_diffuse, srf_reflect = \ wea_from_stat.directional_radiation(90) diffuse_horiz_rad = wea_from_stat.diffuse_horizontal_radiation direct_horiz_rad = wea_from_stat.direct_horizontal_radiation glob_horiz_rad = wea_from_stat.global_horizontal_radiation assert [x.value for x in srf_total ] == pytest.approx([x.value for x in glob_horiz_rad], rel=1e-3) assert [x.value for x in srf_direct ] == pytest.approx([x.value for x in direct_horiz_rad], rel=1e-3) assert [x.value for x in srf_diffuse ] == pytest.approx([x.value for x in diffuse_horiz_rad], rel=1e-3) assert [x.value for x in srf_reflect] == pytest.approx([0] * 8760, rel=1e-3)
def test_from_file_discontinuous(): """Test import from wea file with discontinuous data.""" wea_file = './tests/assets/wea/chicago_filtered.wea' wea = Wea.from_file(wea_file) assert isinstance(wea.direct_normal_irradiance, HourlyDiscontinuousCollection) assert isinstance(wea.diffuse_horizontal_irradiance, HourlyDiscontinuousCollection) assert not wea.is_annual assert not wea.is_continuous assert len(wea) == 4427 assert wea.datetimes[0].hour == 7 with pytest.raises(ValueError): direct, diff = wea.get_irradiance_value(1, 1, 5) # non-existent date direct, diff = wea.get_irradiance_value(1, 1, 8) assert direct == 397 assert diff == 47 direct, diff = wea.get_irradiance_value_for_hoy(8) assert direct == 397 assert diff == 47
def test_zhang_huang_accuracy(): """Test zhang huang solar model to ensure that average error is within 25% of actual solar.""" path = './tests/fixtures/epw/chicago.epw' epw = EPW(path) wea = Wea.from_zhang_huang_solar(epw.location, epw.total_sky_cover, epw.relative_humidity, epw.dry_bulb_temperature, epw.wind_speed, epw.atmospheric_station_pressure) # test global horizontal radiation glob_horiz_error = [ abs(i - j) for i, j in zip(epw.global_horizontal_radiation, wea.global_horizontal_irradiance) ] avg_glob_horiz_error = sum(glob_horiz_error) / sum( epw.global_horizontal_radiation) assert (sum(glob_horiz_error) / 8760) < 50 assert avg_glob_horiz_error < 0.5 # test direct normal radiation dir_normal_error = [ abs(i - j) for i, j in zip(epw.direct_normal_radiation, wea.direct_normal_irradiance) ] avg_dir_normal_error = sum(dir_normal_error) / sum( epw.direct_normal_radiation) assert sum(dir_normal_error) / 8760 < 100 assert avg_dir_normal_error < 0.5 # test diffuse horizontal radiation dif_horiz_error = [ abs(i - j) for i, j in zip(epw.diffuse_horizontal_radiation, wea.diffuse_horizontal_irradiance) ] avg_dif_horiz_error = sum(dif_horiz_error) / sum( epw.diffuse_horizontal_radiation) assert sum(dif_horiz_error) / 8760 < 50 assert avg_dif_horiz_error < 0.5
def from_dict(cls, input_dict): """Create the sky from a dictionary. Args: input_dict: A python dictionary in the following format .. code-block:: python { 'type': 'SunMatrix', 'wea': {}, 'north': 0.0 # optional } """ if 'type' not in input_dict or input_dict['type'] != 'SunMatrix': raise ValueError('Input dict "type" must be "SunMatrix".') if 'north' in input_dict: sky = cls(Wea.from_dict(input_dict['wea']), input_dict['north']) else: sky = cls(input_dict['wea']) return sky
def from_epw_file(cls, epw_file, sky_density=1, north=0, hoys=None, mode=0, suffix=None): """Create sky from an epw file.""" return cls(Wea.from_epw_file(epw_file), sky_density, north, hoys, mode, suffix=suffix)
def from_epw_file(cls, epw_file, north=0, hoys=None, output_type=0, suffix=None): """Create sun matrix from an epw file.""" return cls(Wea.from_epw_file(epw_file), north, hoys, output_type, suffix)