def _get_conversion_factor(origin_unit: Enum, si_unit: Enum) -> Tuple[Union[operator.mul, operator.add], float]: """ Method to get the conversion factor (flaot) for a specific parameter :param origin_unit: origin unit enumeration of parameter :param si_unit: si unit enumeration of parameter :return: conversion factor as float """ if si_unit == SIUnit.KILOGRAM_PER_SQUARE_METER.value: # Fixed conversion factors to kg / m², as it only applies # for water with density 1 g / cm³ if origin_unit == OriginUnit.MILLIMETER.value: return operator.mul, 1 else: raise ValueError("manually set conversion factor for precipitation unit") elif si_unit == SIUnit.DEGREE_KELVIN.value: # Apply offset addition to temperature measurements # Take 0 as this is appropriate for adding on other numbers # (just the difference) degree_offset = Quantity(0, origin_unit).to(si_unit).magnitude return operator.add, degree_offset elif si_unit == SIUnit.PERCENT.value: factor = REGISTRY(str(origin_unit)).to(str(si_unit)).magnitude return operator.mul, factor else: # For multiplicative units we need to use 1 as quantity to apply the # appropriate factor factor = Quantity(1, origin_unit).to(si_unit).magnitude return operator.mul, factor
def test_pickle_definition_syntax_error(self): # OffsetUnitCalculusError raised from a custom ureg must be pickleable even if # the ureg is not registered as the application ureg ureg = UnitRegistry(filename=None) ureg.define("foo = [bar]") ureg.define("bar = 2 foo") q1 = ureg.Quantity("1 foo") q2 = ureg.Quantity("1 bar") for protocol in range(pickle.HIGHEST_PROTOCOL + 1): for ex in [ DefinitionSyntaxError("foo", filename="a.txt", lineno=123), RedefinitionError("foo", "bar"), UndefinedUnitError("meter"), DimensionalityError("a", "b", "c", "d", extra_msg=": msg"), OffsetUnitCalculusError( Quantity("1 kg")._units, Quantity("1 s")._units), OffsetUnitCalculusError(q1._units, q2._units), ]: with self.subTest(protocol=protocol, etype=type(ex)): pik = pickle.dumps(ureg.Quantity("1 foo"), protocol) with self.assertRaises(UndefinedUnitError): pickle.loads(pik) # assert False, ex.__reduce__() ex2 = pickle.loads(pickle.dumps(ex, protocol)) assert type(ex) is type(ex2) self.assertEqual(ex.args, ex2.args) self.assertEqual(ex.__dict__, ex2.__dict__) self.assertEqual(str(ex), str(ex2))
def test_measurement_2args(self): m = Measurement(Quantity(123, "foo"), Quantity(10, "bar")) self.assertEqual(m.value.magnitude, 123) self.assertEqual(m.error.magnitude, 5) self.assertEqual(str(m.units), "foo") m = pickle.loads(pickle.dumps(m)) self.assertEqual(m.value.magnitude, 123) self.assertEqual(m.error.magnitude, 5) self.assertEqual(str(m.units), "foo")
def test_measurement_2args(self, protocol): m = Measurement(Quantity(123, "kg"), Quantity(15, "kg")) self.assertEqual(m.value.magnitude, 123) self.assertEqual(m.error.magnitude, 15) self.assertEqual(str(m.units), "kilogram") m = pickle.loads(pickle.dumps(m, protocol)) self.assertEqual(m.value.magnitude, 123) self.assertEqual(m.error.magnitude, 15) self.assertEqual(str(m.units), "kilogram")
def test_measurement_2args(self, protocol): m = Measurement(Quantity(123, "foo"), Quantity(10, "bar")) assert m.value.magnitude == 123 assert m.error.magnitude == 5 assert str(m.units) == "foo" m = pickle.loads(pickle.dumps(m, protocol)) assert m.value.magnitude == 123 assert m.error.magnitude == 5 assert str(m.units) == "foo"
def test_measurement_2args(self, protocol): m = Measurement(Quantity(123, "kg"), Quantity(15, "kg")) assert m.value.magnitude == 123 assert m.error.magnitude == 15 assert str(m.units) == "kilogram" m = pickle.loads(pickle.dumps(m, protocol)) assert m.value.magnitude == 123 assert m.error.magnitude == 15 assert str(m.units) == "kilogram"
def test_offset_unit_calculus_error(self): ex = OffsetUnitCalculusError(Quantity("1 kg")._units) assert (str( ex) == "Ambiguous operation with offset unit (kilogram). See " + OFFSET_ERROR_DOCS_HTML + " for guidance.") ex = OffsetUnitCalculusError( Quantity("1 kg")._units, Quantity("1 s")._units) assert ( str(ex) == "Ambiguous operation with offset unit (kilogram, second). See " + OFFSET_ERROR_DOCS_HTML + " for guidance.")
def test_quantity_2args(self, protocol): set_application_registry(self.ureg1) q1 = Quantity(1, "foo") set_application_registry(self.ureg2) q2 = Quantity(1, "foo") q3 = pickle.loads(pickle.dumps(q1, protocol)) assert q1.dimensionality == {"[dim1]": 1} assert q2.dimensionality == {"[dim2]": 1} assert q3.dimensionality == {"[dim2]": 1} assert q1.to("bar").magnitude == 2 assert q2.to("bar").magnitude == 3 assert q3.to("bar").magnitude == 3
def test_logarithmic_unit_calculus_error(self): Quantity = UnitRegistry(autoconvert_offset_to_baseunit=True).Quantity ex = LogarithmicUnitCalculusError(Quantity("1 dB")._units) assert (str(ex) == "Ambiguous operation with logarithmic unit (decibel). See " + LOG_ERROR_DOCS_HTML + " for guidance.") ex = LogarithmicUnitCalculusError( Quantity("1 dB")._units, Quantity("1 octave")._units) assert ( str(ex) == "Ambiguous operation with logarithmic unit (decibel, octave). See " + LOG_ERROR_DOCS_HTML + " for guidance.")
def test_offset_unit_calculus_error(self): ex = OffsetUnitCalculusError(Quantity("1 kg")._units) self.assertEqual( str(ex), "Ambiguous operation with offset unit (kilogram). See " "https://pint.readthedocs.io/en/latest/nonmult.html for guidance.", ) ex = OffsetUnitCalculusError(Quantity("1 kg")._units, Quantity("1 s")._units) self.assertEqual( str(ex), "Ambiguous operation with offset unit (kilogram, second). See " "https://pint.readthedocs.io/en/latest/nonmult.html for guidance.", )
def aggregate_chunks(existing_chunks: Iterable[int], item_size: int, subdivision: int = 1): target_size_bytes = int( Quantity(config.get("array.chunk-size")).m_as("bytes")) # The optimal number of data per Dask chunk. target_size = target_size_bytes // item_size # Try to aggregate the input data into the fewest possible Dask chunks. new_chunks = [] for chunk in existing_chunks: # If this input data set will fit into the current chunk, add it. if new_chunks and new_chunks[-1] + chunk <= target_size: new_chunks[-1] += chunk # If the current chunk is full (or the chunks list is empty), add this # data set to the next chunk. elif chunk <= target_size: new_chunks.append(chunk) # If this data set is larger than the max Dask chunk size, split it # along the HDF5 data set chunk boundaries and put the pieces in # separate Dask chunks. else: n_whole_chunks, remainder = divmod(chunk, target_size) dask_chunk_size = target_size // subdivision * subdivision new_chunks += [dask_chunk_size] * n_whole_chunks + [remainder] return new_chunks
def test_quantity_1arg(self): q = Quantity("123 foo") self.assertEqual(str(q.units), "foo") self.assertEqual(q.to("bar").magnitude, 246) q = pickle.loads(pickle.dumps(q)) self.assertEqual(str(q.units), "foo") self.assertEqual(q.to("bar").magnitude, 246)
def test_quantity_2args(self, protocol): q = Quantity(123, "kg") self.assertEqual(str(q.units), "kilogram") self.assertEqual(q.to("t").magnitude, 0.123) q = pickle.loads(pickle.dumps(q, protocol)) self.assertEqual(str(q.units), "kilogram") self.assertEqual(q.to("t").magnitude, 0.123)
def get_bin(self, quantity: str) -> int: try: ph_value = self.string_to_ph(quantity) return self.quantity_binner.get_bin_index( Quantity(ph_value, u.dimensionless)) except ValueError as e: raise BinningError(quantity) from e
def test_quantity_1arg(self): q = Quantity("123 kg") self.assertEqual(str(q.units), "kilogram") self.assertEqual(q.to("t").magnitude, 0.123) q = pickle.loads(pickle.dumps(q)) self.assertEqual(str(q.units), "kilogram") self.assertEqual(q.to("t").magnitude, 0.123)
def test_quantity_2args(self, protocol): q = Quantity(123, "foo") self.assertEqual(str(q.units), "foo") self.assertEqual(q.to("bar").magnitude, 246) q = pickle.loads(pickle.dumps(q, protocol)) self.assertEqual(str(q.units), "foo") self.assertEqual(q.to("bar").magnitude, 246)
def test_measurement_2args(self): set_application_registry(self.ureg1) m1 = Measurement(Quantity(10, "foo"), Quantity(1, "foo")) set_application_registry(self.ureg2) m2 = Measurement(Quantity(10, "foo"), Quantity(1, "foo")) m3 = pickle.loads(pickle.dumps(m1)) assert m1.dimensionality == {"[dim1]": 1} assert m2.dimensionality == {"[dim2]": 1} assert m3.dimensionality == {"[dim2]": 1} self.assertEqual(m1.to("bar").value.magnitude, 20) self.assertEqual(m2.to("bar").value.magnitude, 30) self.assertEqual(m3.to("bar").value.magnitude, 30) self.assertEqual(m1.to("bar").error.magnitude, 2) self.assertEqual(m2.to("bar").error.magnitude, 3) self.assertEqual(m3.to("bar").error.magnitude, 3)
def extract_temperature(self, temperature: str) -> RxnQuantity: try: vue = get_vue(temperature) return RxnQuantity( Quantity(temperature_to_float(temperature, vue), u.degC)) except VUEParseError as e: raise TemperatureExtractionError(temperature) from e
def test_quantity_2args(self, protocol): q = Quantity(123, "kg") assert str(q.units) == "kilogram" assert q.to("t").magnitude == 0.123 q = pickle.loads(pickle.dumps(q, protocol)) assert str(q.units) == "kilogram" assert q.to("t").magnitude == 0.123
def test_datax(self): """ Test that it writes a number of variables correctly """ f = io.StringIO() printvariables(f, a = "Literal string", b = 3.141592, c = (3.141592,"\\meter"), d = (3.141592,"\\meter","%.2g"), e = (3.141592,"%.2g"), f = Quantity(3.141592,"\\meter"), ) f.seek(0) written = f.read() target ="""\ % File auto-generated by LaTeXDatax.py. Will be overwritten. \\pgfkeyssetvalue{/datax/a}{Literal string} \\pgfkeyssetvalue{/datax/b}{\\num{3.142}} \\pgfkeyssetvalue{/datax/c}{\\qty{3.142}{\\meter}} \\pgfkeyssetvalue{/datax/d}{\\qty{3.1}{\\meter}} \\pgfkeyssetvalue{/datax/e}{\\num{3.1}} \\pgfkeyssetvalue{/datax/f}{\\SI[]{3.141592}{\\meter}} """ self.assertEqual(written,target)
def test_measurement_2args(self, protocol): set_application_registry(self.ureg1) m1 = Measurement(Quantity(10, "foo"), Quantity(1, "foo")) set_application_registry(self.ureg2) m2 = Measurement(Quantity(10, "foo"), Quantity(1, "foo")) m3 = pickle.loads(pickle.dumps(m1, protocol)) assert m1.dimensionality == {"[dim1]": 1} assert m2.dimensionality == {"[dim2]": 1} assert m3.dimensionality == {"[dim2]": 1} assert m1.to("bar").value.magnitude == 20 assert m2.to("bar").value.magnitude == 30 assert m3.to("bar").value.magnitude == 30 assert m1.to("bar").error.magnitude == 2 assert m2.to("bar").error.magnitude == 3 assert m3.to("bar").error.magnitude == 3
def test_quantity_2args(self, protocol): q = Quantity(123, "foo") assert str(q.units) == "foo" assert q.to("bar").magnitude == 246 q = pickle.loads(pickle.dumps(q, protocol)) assert str(q.units) == "foo" assert q.to("bar").magnitude == 246
def get_divergence_from_beam_diameter(E, beam_diameter_fwhm): """Calculate the divergence (radian) from photon energy (eV) and beam_diameter (m)""" # The rms of the amplitude distribution (Gaussian) E = Quantity(E, Unit("eV")) beam_waist = beam_diameter_fwhm / np.sqrt(2.0 * np.log(2.0)) theta = 2.0 * hbar * c / beam_waist / E.to("joule").magnitude return float(theta)
def __init__(self, bin_boundaries: Optional[List[float]] = None, ph_for_acidic: float = 3.0, ph_for_basic: float = 11.0, ph_for_neutral: float = 7.0): """ Args: bin_boundaries: defaults to [6.5, 7.5] (i.e. 3 bins with limits at 6.5 and 7.5). ph_for_acidic: pH value to convert the adjective "acidic" to ph_for_basic: pH value to convert the adjective "basic" to ph_for_neutral: pH value to convert the adjective "neutral" to """ if bin_boundaries is None: bin_boundaries = [6.5, 7.5] self.quantity_binner = QuantityBinner( [Quantity(v, u.dimensionless) for v in bin_boundaries]) self.conversions = { 'acidic': ph_for_acidic, 'basic': ph_for_basic, 'neutral': ph_for_neutral, }
"""This module deals with units conversion in the ROSS library.""" import inspect import warnings from functools import wraps from pathlib import Path from pint import Quantity, UnitRegistry with warnings.catch_warnings(): warnings.simplefilter("ignore") Quantity([]) new_units_path = Path(__file__).parent / "new_units.txt" ureg = UnitRegistry() ureg.load_definitions(str(new_units_path)) Q_ = ureg.Quantity __all__ = ["Q_", "check_units"] units = { "E": "N/m**2", "G_s": "N/m**2", "rho": "kg/m**3", "L": "meter", "idl": "meter", "idr": "meter", "odl": "meter", "odr": "meter", "speed": "radian/second", "frequency": "radian/second", "frequency_range": "radian/second",
def _(data: pd.Series) -> Quantity: return Quantity(value=data.memory_usage(deep=True), units="byte")
def _(data: pd.DataFrame) -> Quantity: return Quantity(value=data.memory_usage(deep=True).sum(), units="byte")
def _create_conversion_factors( self, dataset ) -> Dict[str, Tuple[Union[operator.add, operator.mul], float]]: dataset = dataset.name dataset_accessor = self.stations.stations._dataset_accessor if self.stations.stations._unique_dataset: origin_units = self.stations.stations._origin_unit_tree[dataset_accessor] metric_units = self.stations.stations._si_unit_tree[dataset_accessor] else: origin_units = self.stations.stations._origin_unit_tree[dataset_accessor][ dataset ] metric_units = self.stations.stations._si_unit_tree[dataset_accessor][ dataset ] conversion_factors = {} # TODO eventually we may for origin_unit, metric_unit in zip(origin_units, metric_units): # Get parameter name parameter = origin_unit.name if self.stations.stations._unique_dataset: parameter_value = self.stations.stations._dataset_tree[ dataset_accessor ][parameter].value else: parameter_value = self.stations.stations._dataset_tree[ dataset_accessor ][dataset][parameter].value if metric_unit.value == MetricUnit.KILOGRAM_PER_SQUARE_METER.value: # Fixed conversion factors to kg / m², as it only applies # for water with density 1 g / cm³ if origin_unit.value == OriginUnit.MILLIMETER.value: conversion_factors[parameter_value] = (operator.mul, 1) else: raise ValueError( "manually set conversion factor for precipitation unit" ) elif metric_unit.value == MetricUnit.DEGREE_KELVIN.value: # Apply offset addition to temperature measurements # Take 0 as this is appropriate for adding on other numbers # (just the difference) degree_offset = ( Quantity(0, origin_unit.value).to(metric_unit.value).magnitude ) conversion_factors[parameter_value] = (operator.add, degree_offset) elif metric_unit.value == MetricUnit.PERCENT.value: factor = ( REGISTRY(str(origin_unit.value)) .to(str(metric_unit.value)) .magnitude ) conversion_factors[parameter_value] = (operator.mul, factor) else: # For multiplicative units we need to use 1 as quantity to apply the # appropriate factor conversion_factors[parameter_value] = ( operator.mul, Quantity(1, origin_unit.value).to(metric_unit.value).magnitude, ) return conversion_factors