Source code for ladybug_pandas.accessors.psychrometrics

from typing import Union

import pandas as pd

from ladybug import psychrometrics
from ladybug.datatype import TYPESDICT

from ..extension_types.arraytype import LadybugArrayType
from ..extension_types.dtype import LadybugDType


[docs]@pd.api.extensions.register_dataframe_accessor("psychro") class PsychrometricsAccessor: """A pandas Dataframe accessor to perform psychrometric calculation operations Use this "psychro" accessor and pass in the name of a column in your dataframe, a Series or an int/float value to perform as psychormetric operation and return a Series. Warning: If using a Dataframe column or a Series you must ensure that it is an instance of a LadybugArrayType. This is because the Psychrometric accessor runs type checks to convert a data type to the right unit if necessary. Example: .. code-block:: python import ladybug_pandas as lbp from ladybug.epw import EPW epw_path = 'tests/assets/epw/tokyo.epw' epw = EPW(epw_path) df = lbp.dataframe_from_epw(epw) df['Humidity Ratio'] = df.psychro.humid_ratio_from_db_rh( db_temp='Dry Bulb Temperature', rel_humid='Relative Humidity' ) """ def __init__(self, pandas_obj): self._obj = pandas_obj def _build_psychro_function(self, function, input_kwargs, output_type, output_unit, **kwargs): input_df = pd.DataFrame() function_inputs = {} for k, v in input_kwargs.items(): input_value = kwargs.get(k) if isinstance(input_value, str): series = self._obj[input_value] input_type = TYPESDICT[v['input_type']] assert isinstance(series.values.dtype.data_type, input_type), \ f'Cannot use array of type {series.values.dtype.data_type} for {k}. Must be a {v["input_type"]}' input_df[k] = series.values.to_unit(v['input_unit']) elif isinstance(input_value, float) or isinstance(input_value, int): function_inputs[k] = input_value values = [] if len(input_df) == 0: values.append(function(**function_inputs)) else: for _, row in input_df.iterrows(): function_inputs.update(row.to_dict()) values.append(function(**function_inputs)) dtype = LadybugDType(TYPESDICT[output_type](), output_unit) return pd.Series( data=LadybugArrayType(values, dtype), index=self._obj.index, )
[docs] def saturated_vapor_pressure(self, t_kelvin: Union[str, float, int, LadybugArrayType]) -> pd.Series: return self._build_psychro_function( function=psychrometrics.saturated_vapor_pressure, input_kwargs={ 't_kelvin': { 'input_type': 'Temperature', 'input_unit': 'K' }, }, output_type='Pressure', output_unit='Pa', t_kelvin=t_kelvin )
[docs] def humid_ratio_from_db_rh(self, db_temp, rel_humid, b_press=101325): """Humidity ratio (kg water/kg air) from air temperature (C) and relative humidity (%). Args: db_temp: Dry bulb temperature (C). rel_humid: Relative humidity (%). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Humidity ratio (kg water/kg air). Note: [1] ASHRAE Handbook - Fundamentals (2017) ch. 1 eqn 20 [2] Meyer et al., (2019). PsychroLib: a library of psychrometric functions to calculate thermodynamic properties of air. Journal of Open Source Software, 4(33), 1137, https://doi.org/10.21105/joss.01137 https://github.com/psychrometrics/psychrolib/blob/master/src/python/psychrolib.py """ return self._build_psychro_function( function=psychrometrics.humid_ratio_from_db_rh, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'rel_humid': { 'input_type': 'RelativeHumidity', 'input_unit': '%' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='HumidityRatio', output_unit='%', db_temp=db_temp, rel_humid=rel_humid, b_press=b_press, )
[docs] def enthalpy_from_db_hr(self, db_temp, humid_ratio, reference_temp=0): """Enthalpy (kJ/kg) at a given humidity ratio (water/air) and dry bulb temperature (C). Args: db_temp: Dry bulb temperature (C). humid_ratio: Humidity ratio (kg water/kg air). reference_temp: Reference dry air temperature (C). Default is 0C, which is standard practice for SI enthalpy values. However, for IP enthalpy, this is typically at 0F (-17.78C). Alternatively, for aboslute thermodynamic enthalpy, one can input 0K (-273.15). Returns: Enthalpy (kJ/kg). Note: [1] ASHRAE Handbook - Fundamentals (2017) ch. 1 eqn 30 [2] Meyer et al., (2019). PsychroLib: a library of psychrometric functions to calculate thermodynamic properties of air. Journal of Open Source Software, 4(33), 1137, https://doi.org/10.21105/joss.01137 https://github.com/psychrometrics/psychrolib/blob/master/src/python/psychrolib.py """ return self._build_psychro_function( function=psychrometrics.enthalpy_from_db_hr, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'humid_ratio': { 'input_type': 'HumidityRatio', 'input_unit': '%' }, 'reference_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' } }, output_type='Enthalpy', output_unit='kJ/kg', db_temp=db_temp, humid_ratio=humid_ratio, reference_temp=reference_temp, )
[docs] def dew_point_from_db_rh(self, db_temp, rel_humid): """Dew point temperature (C) from air temperature (C) and relative humidity (%). The dew point temperature is solved by inverting the equation giving water vapor pressure at saturation from temperature, which is relatively slow but ensures high accuracy down to 0.1 C at a wide range of dry bulb temperatures. The Newton-Raphson (NR) method is used on the logarithm of water vapour pressure as a function of temperature, which is a very smooth function Convergence is usually achieved in 3 to 5 iterations. Args: db_temp: Dry bulb temperature (C). rel_humid: Relative humidity (%). Returns: Dew point temperature (C). Note: [1] ASHRAE Handbook - Fundamentals (2017) ch. 1 eqn. 5 and 6 [2] Meyer et al., (2019). PsychroLib: a library of psychrometric functions to calculate thermodynamic properties of air. Journal of Open Source Software, 4(33), 1137, https://doi.org/10.21105/joss.01137 https://github.com/psychrometrics/psychrolib/blob/master/src/python/psychrolib.py """ return self._build_psychro_function( function=psychrometrics.dew_point_from_db_rh, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'rel_humid': { 'input_type': 'RelativeHumidity', 'input_unit': '%' } }, output_type='DewPointTemperature', output_unit='C', db_temp=db_temp, rel_humid=rel_humid, )
[docs] def wet_bulb_from_db_rh(self, db_temp, rel_humid, b_press=101325): """Wet bulb temperature (C) from air temperature (C) and relative humidity (%). Args: db_temp: Dry bulb temperature (C). rel_humid: Relative humidity (%). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Wet bulb temperature (C). Note: [1] ASHRAE Handbook - Fundamentals (2017) ch. 1 eqn 33 and 35 [2] Meyer et al., (2019). PsychroLib: a library of psychrometric functions to calculate thermodynamic properties of air. Journal of Open Source Software, 4(33), 1137, https://doi.org/10.21105/joss.01137 https://github.com/psychrometrics/psychrolib/blob/master/src/python/psychrolib.py """ return self._build_psychro_function( function=psychrometrics.wet_bulb_from_db_rh, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'rel_humid': { 'input_type': 'RelativeHumidity', 'input_unit': '%' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='WetBulbTemperature', output_unit='C', db_temp=db_temp, rel_humid=rel_humid, b_press=b_press, )
[docs] def rel_humid_from_db_hr(self, db_temp, humid_ratio, b_press=101325): """Relative Humidity (%) from humidity ratio (water/air) and air temperature (C). Args: db_temp: Dry bulb temperature (C). humid_ratio: Humidity ratio (kg water/kg air). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Relative humidity (%). """ return self._build_psychro_function( function=psychrometrics.rel_humid_from_db_hr, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'humid_ratio': { 'input_type': 'HumidityRatio', 'input_unit': '%' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='RelativeHumidity', output_unit='%', db_temp=db_temp, humid_ratio=humid_ratio, b_press=b_press, )
[docs] def rel_humid_from_db_enth(self, db_temp, enthalpy, b_press=101325, reference_temp=0): """Relative Humidity (%) from air temperature (C) and enthalpy (kJ/kg). Args: db_temp: Dry bulb temperature (C). enthalpy: Enthalpy (kJ/kg). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). reference_temp: Reference dry air temperature (C). Default is 0C, which is standard practice for SI enthalpy values. However, for IP enthalpy, this is typically at 0F (-17.78C). Alternatively, for aboslute thermodynamic enthalpy, one can input 0K (-273.15). Returns: Relative humidity (%). """ return self._build_psychro_function( function=psychrometrics.rel_humid_from_db_enth, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'enthalpy': { 'input_type': 'Enthalpy', 'input_unit': 'kJ/kg' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' }, 'reference_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' } }, output_type='RelativeHumidity', output_unit='%', db_temp=db_temp, enthalpy=enthalpy, b_press=b_press, reference_temp=reference_temp, )
[docs] def rel_humid_from_db_dpt(self, db_temp, dew_pt): """Relative humidity (%) from dry bulb temperature (C), and dew point temperature (C). Args: db_temp: Dry bulb temperature (C). dew_pt: Dew point temperature (C). Returns: Relative humidity (%). """ return self._build_psychro_function( function=psychrometrics.dew_point_from_db_rh, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'dew_pt': { 'input_type': 'DewPointTemperature', 'input_unit': 'C' } }, output_type='RelativeHumidity', output_unit='%', db_temp=db_temp, dew_pt=dew_pt, )
[docs] def rel_humid_from_db_wb(self, db_temp, wet_bulb, b_press=101325): """Relative humidity (%) from dry bulb temperature (C), and wet bulb temperature (C). Args: db_temp: Dry bulb temperature (C). wet_bulb: Wet bulb temperature (C). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Relative humidity (%). """ return self._build_psychro_function( function=psychrometrics.rel_humid_from_db_wb, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'wet_bulb': { 'input_type': 'WetBulbTemperature', 'input_unit': 'C' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='RelativeHumidity', output_unit='%', db_temp=db_temp, wet_bulb=wet_bulb, b_press=b_press, )
[docs] def dew_point_from_db_hr(self, db_temp, humid_ratio, b_press=101325): """Dew Point Temperature (C) from air temperature (C) and humidity ratio (water/air). Args: db_temp: Dry bulb temperature (C). humid_ratio: Humidity ratio (kg water/kg air). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Dew point temperature (C). """ return self._build_psychro_function( function=psychrometrics.dew_point_from_db_hr, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'humid_ratio': { 'input_type': 'HumidityRatio', 'input_unit': '%' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='DewPointTemperature', output_unit='C', db_temp=db_temp, humid_ratio=humid_ratio, b_press=b_press, )
[docs] def dew_point_from_db_enth(self, db_temp, enthalpy, b_press=101325, reference_temp=0): """Dew point temperature (C) from air temperature (C) and enthalpy (kJ/kg). Args: db_temp: Dry bulb temperature (C). enthalpy: Enthalpy (kJ/kg). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). reference_temp: Reference dry air temperature (C). Default is 0C, which is standard practice for SI enthalpy values. However, for IP enthalpy, this is typically at 0F (-17.78C). Alternatively, for aboslute thermodynamic enthalpy, one can input 0K (-273.15). Returns: Dew point temperature (C). """ return self._build_psychro_function( function=psychrometrics.dew_point_from_db_enth, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'enthalpy': { 'input_type': 'Enthalpy', 'input_unit': 'kJ/kg' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' }, 'reference_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' } }, output_type='DewPointTemperature', output_unit='C', db_temp=db_temp, enthlpy=enthalpy, b_press=b_press, reference_temp=reference_temp, )
[docs] def dew_point_from_db_wb(self, db_temp, wet_bulb, b_press=101325): """Dew point temperature (C) from dry bulb (C) and wet bulb temperature (C). Args: db_temp: Dry bulb temperature (C). wet_bulb: Wet bulb temperature (C). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Dew point temperature (C). """ return self._build_psychro_function( function=psychrometrics.dew_point_from_db_wb, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'wet_bulb': { 'input_type': 'WetBulbTemperature', 'input_unit': 'C' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='DewPointTemperature', output_unit='C', db_temp=db_temp, wet_bulb=wet_bulb, b_press=b_press, )
[docs] def humid_ratio_from_db_wb(self, db_temp, wb_temp, b_press=101325): """Humidity ratio from air temperature (C) and wet bulb temperature (C). Args: db_temp: Dry bulb temperature (C). wb_temp: Wet bulb temperature (C). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Humidity ratio (kg water / kg air). Note: [1] ASHRAE Handbook - Fundamentals (2017) ch. 1 eqn 36, solved for W """ return self._build_psychro_function( function=psychrometrics.humid_ratio_from_db_wb, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'wb_temp': { 'input_type': 'WetBulbTemperature', 'input_unit': 'C' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='HumidityRatio', output_unit='%', db_temp=db_temp, wb_temp=wb_temp, b_press=b_press, )
[docs] def db_temp_from_enth_hr(self, enthalpy, humid_ratio, reference_temp=0): """Dry bulb temperature (C) from enthalpy (kJ/kg) and humidity ratio (water/air). Args: enthalpy: Enthalpy (kJ/kg). humid_ratio: Humidity ratio (kg water/kg air). reference_temp: Reference dry air temperature (C). Default is 0C, which is standard practice for SI enthalpy values. However, for IP enthalpy, this is typically at 0F (-17.78C). Alternatively, for aboslute thermodynamic enthalpy, one can input 0K (-273.15). Returns: Dry bulb temperature (C). Note: [1] ASHRAE Handbook - Fundamentals (2017) ch. 1 eqn 30 """ return self._build_psychro_function( function=psychrometrics.db_temp_from_enth_hr, input_kwargs={ 'enthalpy': { 'input_type': 'Enthalpy', 'input_unit': 'kJ/kg' }, 'humid_ratio': { 'input_type': 'HumidityRatio', 'input_unit': '%' }, 'reference_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' } }, output_type='DryBulbTemperature', output_unit='C', enthalpy=enthalpy, humid_ratio=humid_ratio, reference_temp=reference_temp, )
[docs] def dew_point_from_db_rh_fast(self, db_temp, rel_humid): """Dew point temperature (C) from air temperature (C) and relative humidity (%). Note that the formula here is fast but is only accurate up to 90C. For accurate values at extreme temperatures, the dew_point_from_db_rh function should be used. Args: db_temp: Dry bulb temperature (C). rel_humid: Relative humidity (%). Returns: Dew point temperature (C). Note: [1] J. Sullivan and L. D. Sanders. "Method for obtaining wet-bulb temperatures by modifying the psychrometric formula." Center for Experiment Design and Data Analysis. NOAA - National Oceanic and Atmospheric Administration. https://www.weather.gov/epz/wxcalc_rh """ return self._build_psychro_function( function=psychrometrics.dew_point_from_db_rh_fast, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'rel_humid': { 'input_type': 'RelativeHumidity', 'input_unit': '%' }, }, output_type='DewPointTemperature', output_unit='C', db_temp=db_temp, rel_humid=rel_humid, )
[docs] def wet_bulb_from_db_rh_fast(self, db_temp, rel_humid, b_press=101325): """Wet bulb temperature (C) from air temperature (C) and relative humidity (%). Note that the formula here is fast but is only accurate around temperatures of 20C and lower. For accurate values at extreme temperatures, the wet_bulb_from_db_rh function should be used. Args: db_temp: Dry bulb temperature (C). rel_humid: Relative humidity (%). b_press: Air pressure (Pa). Default is pressure at sea level (101325 Pa). Returns: Wet bulb temperature (C). Note: [1] J. Sullivan and L. D. Sanders. "Method for obtaining wet-bulb temperatures by modifying the psychrometric formula." Center for Experiment Design and Data Analysis. NOAA - National Oceanic and Atmospheric Administration. https://www.weather.gov/epz/wxcalc_rh """ return self._build_psychro_function( function=psychrometrics.wet_bulb_from_db_rh_fast, input_kwargs={ 'db_temp': { 'input_type': 'DryBulbTemperature', 'input_unit': 'C' }, 'rel_humid': { 'input_type': 'RelativeHumidity', 'input_unit': '%' }, 'b_press': { 'input_type': 'Pressure', 'input_unit': 'Pa' } }, output_type='WetBulbTemperature', output_unit='C', db_temp=db_temp, rel_humid=rel_humid, b_press=b_press, )
def _d_ln_p_ws(self, db_temp): """Helper function returning the derivative of the natural log of the saturation vapor pressure as a function of dry-bulb temperature. Args: db_temp : Dry bulb temperature (C). Returns: Derivative of natural log of vapor pressure of saturated air in Pa. """ return self._build_psychro_function( function=psychrometrics._d_ln_p_ws, input_kwargs={ 'db_temp': { 'input_type': 'WetBulbTemperature', 'input_unit': 'C' }, }, output_type='Pressure', output_unit='Pa', db_temp=db_temp, rel_humid=rel_humid, b_press=b_press, )