def test_utci_collection_comfort_percent_outputs(): """Test the is_comfortable and percent outputs of the UTCI collection.""" relative_path = './tests/epw/chicago.epw' epw = EPW(relative_path) utci_obj = UTCI(epw.dry_bulb_temperature, epw.relative_humidity, wind_speed=epw.wind_speed) assert utci_obj.percent_comfortable == pytest.approx(35.6849315, rel=1e-3) assert utci_obj.percent_uncomfortable == pytest.approx(64.31506849, rel=1e-3) assert utci_obj.percent_neutral == pytest.approx(35.6849315, rel=1e-3) assert utci_obj.percent_hot == pytest.approx(3.3447488, rel=1e-3) assert utci_obj.percent_cold == pytest.approx(60.970319, rel=1e-3) assert utci_obj.percent_extreme_cold_stress == pytest.approx(0.35388127, rel=1e-3) assert utci_obj.percent_very_strong_cold_stress == pytest.approx( 4.37214611, rel=1e-3) assert utci_obj.percent_strong_cold_stress == pytest.approx(16.541095, rel=1e-3) assert utci_obj.percent_moderate_cold_stress == pytest.approx(23.8356164, rel=1e-3) assert utci_obj.percent_slight_cold_stress == pytest.approx(15.8675799, rel=1e-3) assert utci_obj.percent_slight_heat_stress == pytest.approx(1.826484, rel=1e-3) assert utci_obj.percent_moderate_heat_stress == pytest.approx(1.312785, rel=1e-3) assert utci_obj.percent_strong_heat_stress == pytest.approx(0.2054794, rel=1e-3) assert utci_obj.percent_very_strong_heat_stress == 0.0 assert utci_obj.percent_extreme_heat_stress == 0.0
def test_get_universal_thermal_climate_index_with_sun_and_wind(): """Test the get_universal_thermal_climate_index method with wind and sun.""" utci_obj = UTCI.from_epw(epw, True, True) assert utci_obj.percent_neutral == pytest.approx(31.4269406, rel=1e-3) assert utci_obj.percent_hot == pytest.approx(11.4611872, rel=1e-3) assert utci_obj.percent_cold == pytest.approx(57.111872, rel=1e-3)
def test_utci_collection_defaults(): """Test the default inputs assigned to the UTCI collection.""" calc_length = 24 air_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) air_temp = HourlyContinuousCollection(air_temp_header, [24] * calc_length) utci_obj = UTCI(air_temp, 50) assert isinstance(utci_obj.rad_temperature, HourlyContinuousCollection) assert len(utci_obj.rad_temperature.values) == calc_length assert utci_obj.rad_temperature[0] == utci_obj.air_temperature[0] assert isinstance(utci_obj.wind_speed, HourlyContinuousCollection) assert len(utci_obj.wind_speed.values) == calc_length assert utci_obj.wind_speed[0] == 0.1 assert isinstance(utci_obj.comfort_parameter, UTCIParameter) default_par = UTCIParameter() assert utci_obj.comfort_parameter.cold_thresh == default_par.cold_thresh assert utci_obj.comfort_parameter.heat_thresh == default_par.heat_thresh assert utci_obj.comfort_parameter.extreme_cold_thresh == default_par.extreme_cold_thresh assert utci_obj.comfort_parameter.very_strong_cold_thresh == default_par.very_strong_cold_thresh assert utci_obj.comfort_parameter.strong_cold_thresh == default_par.strong_cold_thresh assert utci_obj.comfort_parameter.moderate_cold_thresh == default_par.moderate_cold_thresh assert utci_obj.comfort_parameter.moderate_heat_thresh == default_par.moderate_heat_thresh assert utci_obj.comfort_parameter.strong_heat_thresh == default_par.strong_heat_thresh assert utci_obj.comfort_parameter.very_strong_heat_thresh == default_par.very_strong_heat_thresh assert utci_obj.comfort_parameter.extreme_heat_thresh == default_par.extreme_heat_thresh
def test_get_universal_thermal_climate_index_with_sun(): """Test the get_universal_thermal_climate_index method with sun.""" utci_obj = UTCI.from_epw(epw, False, True) assert utci_obj.percent_neutral == pytest.approx(40.730593, rel=1e-3) assert utci_obj.percent_hot == pytest.approx(20.4223744, rel=1e-3) assert utci_obj.percent_cold == pytest.approx(38.8470319, rel=1e-3)
def test_get_universal_thermal_climate_index_with_wind(): """Test the get_universal_thermal_climate_index method with wind.""" utci_obj = UTCI.from_epw(epw, True, False) assert utci_obj.percent_neutral == pytest.approx(35.6849315, rel=1e-3) assert utci_obj.percent_hot == pytest.approx(3.3447488, rel=1e-3) assert utci_obj.percent_cold == pytest.approx(60.970319, rel=1e-3)
def test_get_universal_thermal_climate_index(): """Test the get_universal_thermal_climate_index method.""" calc_length = 8760 utci_obj = UTCI.from_epw(epw, False, False) assert isinstance(utci_obj, UTCI) assert isinstance(utci_obj.air_temperature, HourlyContinuousCollection) assert len(utci_obj.air_temperature.values) == calc_length assert utci_obj.air_temperature[0] == -6.1 assert isinstance(utci_obj.rel_humidity, HourlyContinuousCollection) assert len(utci_obj.rel_humidity.values) == calc_length assert utci_obj.rel_humidity[0] == 81 assert isinstance(utci_obj.universal_thermal_climate_index, HourlyContinuousCollection) assert len(utci_obj.universal_thermal_climate_index.values) == calc_length assert utci_obj.universal_thermal_climate_index[0] == pytest.approx( -5.367017, rel=1e-3) assert isinstance(utci_obj.thermal_condition_eleven_point, HourlyContinuousCollection) assert len(utci_obj.thermal_condition_eleven_point.values) == calc_length assert utci_obj.thermal_condition_eleven_point[0] == -2 assert utci_obj.percent_neutral == pytest.approx(47.488584, rel=1e-3) assert utci_obj.percent_hot == pytest.approx(9.38356164, rel=1e-3) assert utci_obj.percent_cold == pytest.approx(43.1278538, rel=1e-3)
def utci(result_sql, enclosure_info, epw_file, total_irradiance, direct_irradiance, ref_irradiance, sun_up_hours, wind_speed, run_period, comfort_par, solarcal_par, folder, log_file): """Get CSV files with maps of UTCI comfort from EnergyPlus and Radiance results. \b Args: result_sql: Path to an SQLite file that was generated by EnergyPlus. This file must contain hourly or sub-hourly results for zone comfort variables. enclosure_info: Path to a JSON file containing information about the radiant enclosure that sensor points belong to. epw_file: Path to an .epw file, used to estimate conditions for any outdoor sensors and to provide sun positions. """ try: # load the EPW object, run period, air speed, and other parameters epw_obj = EPW(epw_file) run_period = _load_analysis_period_str(run_period) wind_speed = _load_values(wind_speed) solarcal_par = _load_solarcal_par_str(solarcal_par) comfort_par = _load_utci_par_str(comfort_par) # load and align the thermal results from the result_sql file pt_air_temps, pt_rad_temps, pt_humids, pt_speeds, _ = _parse_enclosure_info( enclosure_info, result_sql, epw_obj, run_period, wind_speed, include_humidity=True, use_10m_wind_speed=True) # adjust the radiant temperature for shortwave solar pt_rad_temps = shortwave_mrt_map(epw_obj.location, pt_rad_temps, sun_up_hours, total_irradiance, direct_irradiance, ref_irradiance, solarcal_par) # run the collections through the UTCI model and output results temperature, condition, condition_intensity = [], [], [] for t_a, rh, t_r, vel in zip(pt_air_temps, pt_humids, pt_rad_temps, pt_speeds): utci_obj = UTCI(t_a, rh, t_r, vel, comfort_parameter=comfort_par) temperature.append(utci_obj.universal_thermal_climate_index) condition.append(utci_obj.thermal_condition) condition_intensity.append(utci_obj.thermal_condition_eleven_point) # write out the final results to CSV files result_file_dict = _thermal_map_csv(folder, result_sql, temperature, condition, condition_intensity) log_file.write(json.dumps(result_file_dict)) except Exception as e: _logger.exception( 'Failed to run Adaptive model comfort map.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def test_utci_collection_immutability(): """Test that the UTCI collection is immutable.""" calc_length = 24 air_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) air_temp = HourlyContinuousCollection(air_temp_header, [24] * calc_length) utci_obj = UTCI(air_temp, 50) # check that editing the original collection does not mutate the object air_temp[0] = 26 assert utci_obj.air_temperature[0] == 24 # check that editing collection properties does not mutate the object with pytest.raises(Exception): utci_obj.air_temperature[0] = 26 with pytest.raises(Exception): utci_obj.air_temperature.values = [26] * calc_length with pytest.raises(Exception): utci_obj.air_temperature = air_temp with pytest.raises(Exception): utci_obj.universal_thermal_climate_index[0] = 20 with pytest.raises(Exception): utci_obj.universal_thermal_climate_index.values = [20] * calc_length # check that properties cannot be edited directly with pytest.raises(Exception): utci_obj.universal_thermal_climate_index = air_temp with pytest.raises(Exception): utci_obj.comfort_parameter = UTCIParameter()
def test_utci_collection_comfort_outputs(): """Test the is_comfortable and thermal_condition outputs of the UTCI collection.""" calc_length = 24 air_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) air_temp = HourlyContinuousCollection(air_temp_header, range(5, 5 + calc_length)) utci_obj = UTCI(air_temp, 50) assert isinstance(utci_obj.is_comfortable, HourlyContinuousCollection) assert len(utci_obj.is_comfortable.values) == calc_length assert utci_obj.is_comfortable[0] == 0 assert utci_obj.is_comfortable[12] == 1 assert utci_obj.is_comfortable[23] == 0 assert isinstance(utci_obj.thermal_condition, HourlyContinuousCollection) assert len(utci_obj.thermal_condition.values) == calc_length assert utci_obj.thermal_condition[0] == -1 assert utci_obj.thermal_condition[12] == 0 assert utci_obj.thermal_condition[23] == 1 assert isinstance(utci_obj.thermal_condition_five_point, HourlyContinuousCollection) assert len(utci_obj.thermal_condition_five_point.values) == calc_length assert utci_obj.thermal_condition_five_point[0] == -1 assert utci_obj.thermal_condition_five_point[12] == 0 assert utci_obj.thermal_condition_five_point[23] == 1 assert isinstance(utci_obj.thermal_condition_seven_point, HourlyContinuousCollection) assert len(utci_obj.thermal_condition_seven_point.values) == calc_length assert utci_obj.thermal_condition_seven_point[0] == -1 assert utci_obj.thermal_condition_seven_point[12] == 0 assert utci_obj.thermal_condition_seven_point[23] == 1 assert isinstance(utci_obj.thermal_condition_nine_point, HourlyContinuousCollection) assert len(utci_obj.thermal_condition_nine_point.values) == calc_length assert utci_obj.thermal_condition_nine_point[0] == -1 assert utci_obj.thermal_condition_nine_point[12] == 0 assert utci_obj.thermal_condition_nine_point[22] == 1 assert utci_obj.thermal_condition_nine_point[23] == 2 assert isinstance(utci_obj.thermal_condition_eleven_point, HourlyContinuousCollection) assert len(utci_obj.thermal_condition_eleven_point.values) == calc_length assert utci_obj.thermal_condition_eleven_point[0] == -1 assert utci_obj.thermal_condition_eleven_point[12] == 0 assert utci_obj.thermal_condition_eleven_point[22] == 1 assert utci_obj.thermal_condition_eleven_point[23] == 2 assert isinstance(utci_obj.original_utci_category, HourlyContinuousCollection) assert len(utci_obj.original_utci_category.values) == calc_length assert utci_obj.original_utci_category[0] == 4 assert utci_obj.original_utci_category[12] == 5 assert utci_obj.original_utci_category[23] == 6
def test_init_utci_collection_epw(): """Test the initialization of the UTCI collection with EPW input.""" calc_length = 8760 relative_path = './tests/epw/chicago.epw' epw = EPW(relative_path) utci_obj = UTCI(epw.dry_bulb_temperature, epw.relative_humidity) assert len(utci_obj.air_temperature.values) == calc_length assert utci_obj.air_temperature[0] == -6.1 assert len(utci_obj.rel_humidity.values) == calc_length assert utci_obj.rel_humidity[0] == 81 assert len(utci_obj.universal_thermal_climate_index.values) == calc_length assert utci_obj.universal_thermal_climate_index[0] == pytest.approx(-5.367017, rel=1e-3) assert len(utci_obj.thermal_condition_eleven_point.values) == calc_length assert utci_obj.thermal_condition_eleven_point[0] == -2
def test_init_utci_collection_full_collection_input(): """Test initialization of the UTCI collection will all inputs as collections.""" calc_length = 24 air_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) air_temp = HourlyContinuousCollection(air_temp_header, [24] * calc_length) rel_humid_header = Header(RelativeHumidity(), '%', AnalysisPeriod(end_month=1, end_day=1)) rel_humid = HourlyContinuousCollection(rel_humid_header, [50] * calc_length) rad_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) rad_temp = HourlyContinuousCollection(rad_temp_header, [22] * calc_length) wind_speed_header = Header(AirSpeed(), 'm/s', AnalysisPeriod(end_month=1, end_day=1)) wind_speed = HourlyContinuousCollection(wind_speed_header, [0.5] * calc_length) utci_obj = UTCI(air_temp, rel_humid, rad_temp, wind_speed) assert utci_obj.air_temperature[0] == 24 assert utci_obj.rel_humidity[0] == 50 assert utci_obj.rad_temperature[0] == 22 assert utci_obj.wind_speed[0] == 0.5
def utci(epw_file, include_wind, include_sun, csv, output_file): """Get a data collection for UTCI from an EPW weather file. \b Args: epw_file: Path to an .epw file. """ try: epw_obj = EPW(epw_file) utci_obj = UTCI.from_epw(epw_obj, include_wind, include_sun) utci_data = utci_obj.universal_thermal_climate_index if csv: output_file.write('\n'.join([str(v) for v in utci_data.values])) else: output_file.write(json.dumps(utci_data.to_dict())) except Exception as e: _logger.exception('Failed to get UTCI from EPW file.\n{}'.format(e)) sys.exit(1) else: sys.exit(0)
def test_init_utci_collection(): """Test the initialization of the UTCI collection and basic outputs.""" calc_length = 24 air_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) air_temp = HourlyContinuousCollection(air_temp_header, [24] * calc_length) utci_obj = UTCI(air_temp, 50) assert utci_obj.comfort_model == 'Universal Thermal Climate Index' assert utci_obj.calc_length == calc_length str(utci_obj) # test that the string representation is ok assert isinstance(utci_obj.air_temperature, HourlyContinuousCollection) assert len(utci_obj.air_temperature.values) == calc_length assert utci_obj.air_temperature[0] == 24 assert isinstance(utci_obj.rel_humidity, HourlyContinuousCollection) assert len(utci_obj.rel_humidity.values) == calc_length assert utci_obj.rel_humidity[0] == 50 assert isinstance(utci_obj.universal_thermal_climate_index, HourlyContinuousCollection) assert len(utci_obj.universal_thermal_climate_index.values) == calc_length assert utci_obj.universal_thermal_climate_index[0] == pytest.approx(23.8110341, rel=1e-3)
def test_init_utci_collection_full_input(): """Test the initialization of the UTCI collection will all inputs.""" calc_length = 24 air_temp_header = Header(Temperature(), 'C', AnalysisPeriod(end_month=1, end_day=1)) air_temp = HourlyContinuousCollection(air_temp_header, [24] * calc_length) custom_par = UTCIParameter(8, 25, -41, -28, -14, -1, 27, 31, 37, 45) utci_obj = UTCI(air_temp, 50, 22, 0.5, custom_par) assert utci_obj.air_temperature[0] == 24 assert utci_obj.rel_humidity[0] == 50 assert utci_obj.rad_temperature[0] == 22 assert utci_obj.wind_speed[0] == 0.5 assert utci_obj.comfort_parameter.cold_thresh == 8 assert utci_obj.comfort_parameter.heat_thresh == 25 assert utci_obj.comfort_parameter.extreme_cold_thresh == -41 assert utci_obj.comfort_parameter.very_strong_cold_thresh == -28 assert utci_obj.comfort_parameter.strong_cold_thresh == -14 assert utci_obj.comfort_parameter.moderate_cold_thresh == -1 assert utci_obj.comfort_parameter.moderate_heat_thresh == 27 assert utci_obj.comfort_parameter.strong_heat_thresh == 31 assert utci_obj.comfort_parameter.very_strong_heat_thresh == 37 assert utci_obj.comfort_parameter.extreme_heat_thresh == 45
def universal_thermal_climate_index( epw_file: str, mean_radiant_temperature: HourlyContinuousCollection, wind: int = 1, evaporative_cooling: bool = False): """ Calculate the Universal Thermal Climate Index :param epw_file: Weather-file with location and climatic conditions for simulation :param mean_radiant_temperature: Mean radiant temperature hourly collection :param wind: 0 if no wind to be included (0.01m/s), 1 if wind speed should use the values in the EPW file, or 2+ is wind is fixed at a speed of 2m/s+ :return universal_thermal_climate_index: """ # Read weather-file epw = EPW(epw_file) # Get wind-speed values based on user choice wind_speed = 0.01 if wind == 0 else epw.wind_speed if wind == 1 else wind # Recalculate dry-bulb temperature if evaporative cooling is to be introduced if evaporative_cooling: wbt = np.array( _wbt(epw.dry_bulb_temperature.values, epw.relative_humidity, epw.atmospheric_station_pressure.values)) dbt_ec = np.array(epw.dry_bulb_temperature.values) - ( (np.array(epw.dry_bulb_temperature.values) - wbt) * 0.7) epw.dry_bulb_temperature.values = dbt_ec # Calculate UTCI values utci = UTCI(epw.dry_bulb_temperature, epw.relative_humidity, mean_radiant_temperature, wind_speed).universal_thermal_climate_index print("Universal Thermal Climate Index calculation completed") return utci
except ValueError as e: raise TypeError('input {} is not valid. Expected float or ' 'DataCollection. Got {}'.format( input, type(input))) return input_list, data_colls if all_required_inputs(ghenv.Component) and _run is True: # Process inputs and assign defaults. input_list = [_air_temp, _mrt_, _wind_vel_, _rel_humid] input, data_colls = extract_collections(input_list) if data_colls == []: # The inputs are all individual values. utci = universal_thermal_climate_index(input[0], float(input[1]), input[2], input[3]) utci_par = UTCIParameter() comfort = utci_par.is_comfortable(utci) condition = utci_par.thermal_condition(utci) category = utci_par.thermal_condition_eleven_point(utci) else: # The inputs include Data Collections. if not isinstance(_air_temp, BaseCollection): _air_temp = data_colls[0].get_aligned_collection( float(_air_temp), Temperature(), 'C') comf_obj = UTCI(_air_temp, _rel_humid, _mrt_, _wind_vel_) utci = comf_obj.universal_thermal_climate_index comfort = comf_obj.is_comfortable condition = comf_obj.thermal_condition category = comf_obj.thermal_condition_eleven_point