Source code for hvl_ccb.utils.conversion.unit

#  Copyright (c) ETH Zurich, SIS ID and HVL D-ITET
#

"""
Unit conversion, within in the same group of units, for example Kelvin <-> Celsius
"""

from __future__ import annotations

import logging
from abc import abstractmethod
from enum import Enum
from typing import Union

from hvl_ccb.utils.typing import ConvertableTypes

from .utils import preserve_type

logger = logging.getLogger(__name__)


[docs] class Unit(Enum): @classmethod @abstractmethod @preserve_type def convert(cls, value: ConvertableTypes, source, target) -> ConvertableTypes: pass # pragma: no cover
[docs] class Temperature(Unit): K = "K" C = "C" F = "F" KELVIN = K CELSIUS = C FAHRENHEIT = F @classmethod @preserve_type def convert( cls, value: ConvertableTypes, source: Union[str, Temperature] = KELVIN, target: Union[str, Temperature] = CELSIUS, ) -> ConvertableTypes: try: source = Temperature(source) target = Temperature(target) except ValueError: logger.warning( "One unit or both units for source and / or target temperature " "are not valid." ) raise ValueError if source == target: return value # convert source to kelvin if source == cls.CELSIUS: value = value + 273.15 # type: ignore elif source == cls.FAHRENHEIT: value = (value - 32) / 1.8 + 273.15 # type: ignore # convert kelvin to target if target == cls.CELSIUS: value = value - 273.15 # type: ignore elif target == cls.FAHRENHEIT: value = (value - 273.15) * 1.8 + 32 # type: ignore return value
[docs] class Pressure(Unit): PA = "Pa" BAR = "bar" ATM = "atm" PSI = "psi" MMHG = "mmHg" TORR = "torr" PASCAL = PA ATMOSPHERE = ATM POUNDS_PER_SQUARE_INCH = PSI MILLIMETER_MERCURY = MMHG @classmethod @preserve_type def convert( cls, value: ConvertableTypes, source: Union[str, Pressure] = BAR, target: Union[str, Pressure] = PASCAL, ) -> ConvertableTypes: try: source = Pressure(source) target = Pressure(target) except ValueError: logger.warning( "One unit or both units for source and / or target pressure " "are not valid." ) raise ValueError if source == target: return value # convert source to Pascal if source == cls.BAR: value = value * 1e5 # type: ignore elif source == cls.ATMOSPHERE: value = value * 101_325 # type: ignore elif source == cls.TORR: value = value * 101_325 / 760 # type: ignore elif source == cls.MMHG: value = value * 101_325 / 760 * 1.000_000_142_466 # type: ignore elif source == cls.PSI: value = value * 6_894.75728 # type: ignore # convert from Pascal to target if target == cls.BAR: value = value / 1e5 # type: ignore elif target == cls.ATMOSPHERE: value = value / 101_325 # type: ignore elif target == cls.TORR: value = value / 101_325 * 760 # type: ignore elif target == cls.MMHG: value = value / 101_325 * 760 / 1.000_000_142_466 # type: ignore elif target == cls.PSI: value = value / 6_894.75728 # type: ignore return value