From f25778951ac38eb548941993e217df95e017402c Mon Sep 17 00:00:00 2001 From: Kyle Qianli Ma <41385391+KyleQianliMa@users.noreply.github.com> Date: Mon, 18 Nov 2024 15:47:33 -0500 Subject: [PATCH] pyre.unit incorporation (#7) * pyre.unit incorporation * port singleton over --------- Co-authored-by: Kyle Ma Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- src/histogram/_units.py | 2 +- src/histogram/utils/Singleton.py | 36 ++++ src/histogram/utils/units/SI.py | 96 ++++++++++ src/histogram/utils/units/__init__.py | 28 +++ src/histogram/utils/units/angle.py | 28 +++ src/histogram/utils/units/area.py | 38 ++++ src/histogram/utils/units/density.py | 21 ++ src/histogram/utils/units/energy.py | 61 ++++++ src/histogram/utils/units/force.py | 25 +++ src/histogram/utils/units/length.py | 65 +++++++ src/histogram/utils/units/mass.py | 48 +++++ src/histogram/utils/units/power.py | 29 +++ src/histogram/utils/units/pressure.py | 51 +++++ src/histogram/utils/units/speed.py | 29 +++ src/histogram/utils/units/substance.py | 27 +++ src/histogram/utils/units/temperature.py | 26 +++ src/histogram/utils/units/time.py | 48 +++++ src/histogram/utils/units/unit.py | 211 +++++++++++++++++++++ src/histogram/utils/units/unitparser.py | 89 +++++++++ src/histogram/utils/units/volume.py | 38 ++++ tests/histogram/Histogram_TestCase.py | 2 +- tests/histogram/NdArrayDataset_TestCase.py | 3 +- 22 files changed, 997 insertions(+), 4 deletions(-) create mode 100644 src/histogram/utils/Singleton.py create mode 100644 src/histogram/utils/units/SI.py create mode 100644 src/histogram/utils/units/__init__.py create mode 100644 src/histogram/utils/units/angle.py create mode 100644 src/histogram/utils/units/area.py create mode 100644 src/histogram/utils/units/density.py create mode 100644 src/histogram/utils/units/energy.py create mode 100644 src/histogram/utils/units/force.py create mode 100644 src/histogram/utils/units/length.py create mode 100644 src/histogram/utils/units/mass.py create mode 100644 src/histogram/utils/units/power.py create mode 100644 src/histogram/utils/units/pressure.py create mode 100644 src/histogram/utils/units/speed.py create mode 100644 src/histogram/utils/units/substance.py create mode 100644 src/histogram/utils/units/temperature.py create mode 100644 src/histogram/utils/units/time.py create mode 100644 src/histogram/utils/units/unit.py create mode 100644 src/histogram/utils/units/unitparser.py create mode 100644 src/histogram/utils/units/volume.py diff --git a/src/histogram/_units.py b/src/histogram/_units.py index 7edf186..3aa3720 100644 --- a/src/histogram/_units.py +++ b/src/histogram/_units.py @@ -1,5 +1,5 @@ import numpy as N -from pyre.units import unit, parser, length +from histogram.utils.units import length, unit, parser import sys diff --git a/src/histogram/utils/Singleton.py b/src/histogram/utils/Singleton.py new file mode 100644 index 0000000..7fa5518 --- /dev/null +++ b/src/histogram/utils/Singleton.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + + +# adapted from GvR's Singleton implementation + + +class Singleton(object): + def __new__(cls, *args, **kwds): + it = cls.__dict__.get("__it__") + if it is not None: + return it + + cls.__it__ = it = object.__new__(cls) + it.init(*args, **kwds) + return it + + def init(self, *args, **kwds): + """constructor substitute for initializing the singleton""" + return + + +# version +__id__ = "$Id: Singleton.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# End of file diff --git a/src/histogram/utils/units/SI.py b/src/histogram/utils/units/SI.py new file mode 100644 index 0000000..fae06d7 --- /dev/null +++ b/src/histogram/utils/units/SI.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .unit import unit, dimensionless + + +# basic SI units + +meter = unit(1.0, (1, 0, 0, 0, 0, 0, 0)) +kilogram = unit(1.0, (0, 1, 0, 0, 0, 0, 0)) +second = unit(1.0, (0, 0, 1, 0, 0, 0, 0)) +ampere = unit(1.0, (0, 0, 0, 1, 0, 0, 0)) +kelvin = unit(1.0, (0, 0, 0, 0, 1, 0, 0)) +mole = unit(1.0, (0, 0, 0, 0, 0, 1, 0)) +candela = unit(1.0, (0, 0, 0, 0, 0, 0, 1)) + +# the 22 derived SI units with special names + +radian = dimensionless # plane angle +steradian = dimensionless # solid angle + +hertz = 1 / second # frequency + +newton = meter * kilogram / second**2 # force +pascal = newton / meter**2 # pressure +joule = newton * meter # work, heat +watt = joule / second # power, radiant flux + +coulomb = ampere * second # electric charge +volt = watt / ampere # electric potential difference +farad = coulomb / volt # capacitance +ohm = volt / ampere # electric resistance +siemens = ampere / volt # electric conductance +weber = volt * second # magnetic flux +tesla = weber / meter**2 # magnetic flux density +henry = weber / ampere # inductance + +celcius = kelvin # Celcius temperature + +lumen = candela * steradian # luminus flux +lux = lumen / meter**2 # illuminance + +becquerel = 1 / second # radioactivity +gray = joule / kilogram # absorbed dose +sievert = joule / kilogram # dose equivalent +katal = mole / second # catalytic activity + +# prefixes + +yotta = 1e24 +zetta = 1e21 +exa = 1e18 +peta = 1e15 +tera = 1e12 +giga = 1e9 +mega = 1e6 +kilo = 1000 +hecto = 100 +deka = 10 +deci = 0.1 +centi = 0.01 +milli = 0.001 +micro = 1e-6 +nano = 1e-9 +pico = 1e-12 +femto = 1e-15 +atto = 1e-18 +zepto = 1e-21 +yocto = 1e-24 + +# binary prefixes +# Thanks to Elaine Chapin for pointing them out + +kibi = 2**10 +mebi = kibi**2 +gibi = kibi**3 +tebi = kibi**4 +pebi = kibi**5 +exbi = kibi**6 + + +# version +__id__ = "$Id: SI.py,v 1.1.1.1 2006-11-27 00:10:06 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/__init__.py b/src/histogram/utils/units/__init__.py new file mode 100644 index 0000000..bfb4f9a --- /dev/null +++ b/src/histogram/utils/units/__init__.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +""" +See physics.nist.gov/ccu/Units for details +""" + + +def parser(): + from . import unitparser + + return unitparser.parser() + + +# version +__id__ = "$Id: __init__.py,v 1.1.1.1 2006-11-27 00:10:06 aivazis Exp $" + +# End of file diff --git a/src/histogram/utils/units/angle.py b/src/histogram/utils/units/angle.py new file mode 100644 index 0000000..7a275aa --- /dev/null +++ b/src/histogram/utils/units/angle.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from math import pi +from .SI import radian + +degree = pi / 180 * radian +arcminute = degree / 60 +arcsecond = arcminute / 60 + +deg = degree +rad = radian + +# version +__id__ = "$Id: angle.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/area.py b/src/histogram/utils/units/area.py new file mode 100644 index 0000000..8b98b06 --- /dev/null +++ b/src/histogram/utils/units/area.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .length import meter, centimeter, inch, foot, mile + + +# +# Definitions of common area units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +square_meter = meter**2 +square_centimeter = centimeter**2 + +square_foot = foot**2 +square_inch = inch**2 +square_mile = mile**2 + +acre = 43560 * square_foot +hectare = 10000 * square_meter + +barn = 1e-28 * square_meter + +# version +__id__ = "$Id: area.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/density.py b/src/histogram/utils/units/density.py new file mode 100644 index 0000000..5b5435d --- /dev/null +++ b/src/histogram/utils/units/density.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .mass import * +from .volume import * + +# version +__id__ = "$Id: density.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/energy.py b/src/histogram/utils/units/energy.py new file mode 100644 index 0000000..a70446b --- /dev/null +++ b/src/histogram/utils/units/energy.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import joule, kilo, mega, giga, milli + + +# +# Definitions of common energy units +# +# Data taken from +# +# Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 +# +# The NIST Reference on Constants, Units and Uncertainty, +# http://physics.nist.gov/cuu +# + + +Btu = 1055 * joule +erg = 1e-7 * joule +foot_pound = 1.356 * joule +horse_power_hour = 2.685e6 * joule + +calorie = 4.1858 * joule +Calorie = 1000 * calorie +kilowatt_hour = 3.6e6 * joule + +electron_volt = 1.60218e-19 * joule + + +# aliases + +J = joule +kJ = kilo * joule +MJ = mega * joule + +eV = electron_volt +meV = milli * eV +MeV = mega * eV +GeV = giga * eV + +cal = calorie +kcal = kilo * calorie + + +# version +__id__ = "$Id: energy.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/force.py b/src/histogram/utils/units/force.py new file mode 100644 index 0000000..598a4ef --- /dev/null +++ b/src/histogram/utils/units/force.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + + +from .SI import meter, second + + +gal = 0.01 * meter / second**2 + + +# version +__id__ = "$Id: force.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/length.py b/src/histogram/utils/units/length.py new file mode 100644 index 0000000..8514710 --- /dev/null +++ b/src/histogram/utils/units/length.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import meter +from .SI import kilo, centi, milli, micro, nano + + +# +# Definitions of common length units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +nanometer = nano * meter +micrometer = micro * meter +millimeter = milli * meter +centimeter = centi * meter +kilometer = kilo * meter + + +# aliases + +m = meter +nm = nanometer +um = micrometer +micron = micrometer +mm = millimeter +cm = centimeter +km = kilometer + + +# British units + +inch = 2.540 * centimeter +foot = 12 * inch +yard = 3 * foot +mile = 5280 * foot + +fathom = 6 * foot +nautical_mile = 1852 * meter + +# others + +angstrom = 1e-10 * meter +fermi = 1e-15 * meter + +astronomical_unit = 1.49598e11 * meter +light_year = 9.460e12 * kilometer +parsec = 3.084e13 * kilometer + + +# version +__id__ = "$Id: length.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/mass.py b/src/histogram/utils/units/mass.py new file mode 100644 index 0000000..f804598 --- /dev/null +++ b/src/histogram/utils/units/mass.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import kilogram +from .SI import kilo, centi, milli + +# +# Definitions of common mass units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +gram = kilogram / kilo +centigram = centi * gram +milligram = milli * gram + + +# aliases + +kg = kilogram +g = gram +cg = centigram +mg = milligram + + +# other + +metric_ton = 1000 * kilogram + +ounce = 28.35 * gram +pound = 16 * ounce +ton = 2000 * pound + + +# version +__id__ = "$Id: mass.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/power.py b/src/histogram/utils/units/power.py new file mode 100644 index 0000000..2776d5e --- /dev/null +++ b/src/histogram/utils/units/power.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import watt, kilo + +# +# Definitions of common power units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +kilowatt = kilo * watt +horsepower = 745.7 * watt + + +# version +__id__ = "$Id: power.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/pressure.py b/src/histogram/utils/units/pressure.py new file mode 100644 index 0000000..ab3ab63 --- /dev/null +++ b/src/histogram/utils/units/pressure.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import pascal, kilo, mega, giga + +# +# Definitions of common pressure units +# +# Data taken from +# Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 +# +# The NIST Reference on Constants, Units and Uncertainty, +# http://physics.nist.gov/cuu +# + + +# aliases + +Pa = pascal +kPa = kilo * pascal +MPa = mega * pascal +GPa = giga * pascal + + +# others + +bar = 1e5 * pascal +millibar = 100 * pascal + +torr = 133.3 * pascal +atmosphere = 101325 * pascal + +atm = atmosphere + + +# version +__id__ = "$Id: pressure.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/speed.py b/src/histogram/utils/units/speed.py new file mode 100644 index 0000000..ea15a84 --- /dev/null +++ b/src/histogram/utils/units/speed.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .time import hour +from .length import nautical_mile + +# +# Definitions of common speed units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +knot = nautical_mile / hour + + +# version +__id__ = "$Id: speed.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/substance.py b/src/histogram/utils/units/substance.py new file mode 100644 index 0000000..72edb92 --- /dev/null +++ b/src/histogram/utils/units/substance.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import mole, kilo + + +# Aliases + +mol = mole +kmol = kilo * mole + + +# version +__id__ = "$Id: substance.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/temperature.py b/src/histogram/utils/units/temperature.py new file mode 100644 index 0000000..2fa391f --- /dev/null +++ b/src/histogram/utils/units/temperature.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import kelvin + + +# alias + +K = kelvin + + +# version +__id__ = "$Id: temperature.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/time.py b/src/histogram/utils/units/time.py new file mode 100644 index 0000000..d28dfbd --- /dev/null +++ b/src/histogram/utils/units/time.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .SI import second +from .SI import pico, nano, micro, milli + + +# +# Definitions of common time units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +picosecond = pico * second +nanosecond = nano * second +microsecond = micro * second +millisecond = milli * second + +# aliases + +s = second +ps = picosecond +ns = nanosecond +us = microsecond +ms = millisecond + +# other common units + +minute = 60 * second +hour = 60 * minute +day = 24 * hour +year = 365.25 * day + + +# version +__id__ = "$Id: time.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/unit.py b/src/histogram/utils/units/unit.py new file mode 100644 index 0000000..5d2b9c2 --- /dev/null +++ b/src/histogram/utils/units/unit.py @@ -0,0 +1,211 @@ +from __future__ import division + +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from functools import total_ordering +import operator + + +@total_ordering +class unit(object): + _labels = ("m", "kg", "s", "A", "K", "mol", "cd") + _zero = (0,) * len(_labels) + _negativeOne = (-1,) * len(_labels) + + def __init__(self, value, derivation): + self.value = value + self.derivation = derivation + return + + def __add__(self, other): + if not self.derivation == other.derivation: + raise IncompatibleUnits("add", self, other) + + return unit(self.value + other.value, self.derivation) + + def __sub__(self, other): + if not self.derivation == other.derivation: + raise IncompatibleUnits("subtract", self, other) + + return unit(self.value - other.value, self.derivation) + + def __mul__(self, other): + if isinstance(other, int) or isinstance(other, float): + return unit(other * self.value, self.derivation) + + value = self.value * other.value + derivation = tuple(map(operator.add, self.derivation, other.derivation)) + + if derivation == self._zero: + return value + + return unit(value, derivation) + + def __truediv__(self, other): + if isinstance(other, int) or isinstance(other, float): + return unit(self.value / other, self.derivation) + value = self.value / other.value + derivation = tuple(map(operator.sub, self.derivation, other.derivation)) + + if derivation == self._zero: + return value + + return unit(value, derivation) + + __div__ = __truediv__ # py2 + + def __pow__(self, other): + if (not isinstance(other, int)) and (not isinstance(other, float)): + raise InvalidOperation("**", self, other) + + value = self.value**other + derivation = tuple(map(operator.mul, [other] * 7, self.derivation)) + + return unit(value, derivation) + + def __pos__(self): + return self + + def __neg__(self): + return unit(-self.value, self.derivation) + + def __abs__(self): + return unit(abs(self.value), self.derivation) + + def __invert__(self): + value = 1.0 / self.value + derivation = tuple(map(operator.mul, self._negativeOne, self.derivation)) + return unit(value, derivation) + + def __rmul__(self, other): + if (not isinstance(other, int)) and (not isinstance(other, float)): + raise InvalidOperation("*", other, self) + + return unit(other * self.value, self.derivation) + + def __rtruediv__(self, other): + if (not isinstance(other, int)) and (not isinstance(other, float)): + raise InvalidOperation("/", other, self) + + value = other / self.value + derivation = tuple(map(operator.mul, self._negativeOne, self.derivation)) + return unit(value, derivation) + + __rdiv__ = __rtruediv__ # py2 + + def __float__(self): + if self.derivation == self._zero: + return self.value + raise InvalidConversion(self) + + """def __cmp__(self, other): + return cmp(self.value, other.value)""" + + def __eq__(self, other): + return self.value == other.value + + def __ne__(self, other): + return not (self == other) + + def __lt__(self, other): + return self.value < other.value + + def __str__(self): + str = "{0:g}".format(self.value) + derivation = self._strDerivation() + if not derivation: + return str + + return str + "*" + derivation + + def __repr__(self): + str = "{0:g}".format(self.value) + derivation = self._strDerivation() + if not derivation: + return str + + return str + "*" + derivation + + def _strDerivation(self): + return _strDerivation(self._labels, self.derivation) + + +# instances + +one = dimensionless = unit(1, unit._zero) + + +# helpers + + +def _strDerivation(labels, exponents): + dimensions = filter(None, map(_strUnit, labels, exponents)) + return "*".join(dimensions) + + +def _strUnit(label, exponent): + if exponent == 0: + return None + if exponent == 1: + return label + return label + "**{0:g}".format(exponent) + + +# exceptions + + +class InvalidConversion(Exception): + def __init__(self, operand): + self._op = operand + return + + def __str__(self): + str = "dimensional quantities ('{0!s}') ".format(self._op._strDerivation()) + str = str + "cannot be converted to scalars" + return str + + +class InvalidOperation(Exception): + def __init__(self, op, operand1, operand2): + self._op = op + self._op1 = operand1 + self._op2 = operand2 + return + + def __str__(self): + str = "Invalid expression: {0!s} {1!s} {2!s}".format( + self._op1, self._op, self._op2 + ) + return str + + +class IncompatibleUnits(Exception): + def __init__(self, op, operand1, operand2): + self._op = op + self._op1 = operand1 + self._op2 = operand2 + return + + def __str__(self): + str = "Cannot {0!s} quanitites with units of '{1!s}' and '{2!s}'".format( + self._op, self._op1._strDerivation(), self._op2._strDerivation() + ) + return str + + +# version +__id__ = "$Id: unit.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/src/histogram/utils/units/unitparser.py b/src/histogram/utils/units/unitparser.py new file mode 100644 index 0000000..0624990 --- /dev/null +++ b/src/histogram/utils/units/unitparser.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +# factory method + + +def parser(): + return Parser() + + +# implementation of the Parser singleton + +from histogram.utils.Singleton import Singleton + + +class Parser(Singleton): + def extend(self, *modules): + for module in modules: + self.context.update(module.__dict__) + return + + def parse(self, string): + return eval(string, self.context) + + def init(self, *args, **kwds): + self.context = self._initializeContext() + return + + def _initializeContext(self): + context = {} + + modules = self._loadModules() + for module in modules: + context.update(module.__dict__) + + return context + + def _loadModules(self): + from . import SI + from . import angle + from . import area + from . import density + from . import energy + from . import force + from . import length + from . import mass + from . import power + from . import pressure + from . import speed + from . import substance + from . import temperature + from . import time + from . import volume + + modules = [ + SI, + angle, + area, + density, + energy, + force, + length, + mass, + power, + pressure, + speed, + substance, + temperature, + time, + volume, + ] + + return modules + + +# version +__id__ = "$Id: unitparser.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# End of file diff --git a/src/histogram/utils/units/volume.py b/src/histogram/utils/units/volume.py new file mode 100644 index 0000000..c2ca706 --- /dev/null +++ b/src/histogram/utils/units/volume.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Michael A.G. Aivazis +# California Institute of Technology +# (C) 1998-2005 All Rights Reserved +# +# +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# + +from .length import meter, centimeter, foot, inch + +# +# Definitions of common volume units +# Data taken from Appendix F of Halliday, Resnick, Walker, "Fundamentals of Physics", +# fourth edition, John Willey and Sons, 1993 + +cubic_meter = meter**3 +cubic_centimeter = centimeter**3 +cubic_foot = foot**3 +cubic_inch = inch**3 + +liter = 1000 * cubic_centimeter + +us_fluid_ounce = 231.0 / 128 * cubic_inch +us_pint = 16 * us_fluid_ounce +us_fluid_quart = 2 * us_pint +us_fluid_gallon = 4 * us_fluid_quart + + +# version +__id__ = "$Id: volume.py,v 1.1.1.1 2006-11-27 00:10:08 aivazis Exp $" + +# +# End of file diff --git a/tests/histogram/Histogram_TestCase.py b/tests/histogram/Histogram_TestCase.py index 5b52ecc..e4edfa8 100755 --- a/tests/histogram/Histogram_TestCase.py +++ b/tests/histogram/Histogram_TestCase.py @@ -222,7 +222,7 @@ def testSetItem(self): h[1] = 10, 10 h = histogram("h", [("a", [1, 2, 3])], unit="meter") - from pyre.units.length import meter + from histogram.utils.units.length import meter h[1] = 10 * meter, 10 * meter * meter return diff --git a/tests/histogram/NdArrayDataset_TestCase.py b/tests/histogram/NdArrayDataset_TestCase.py index 90cc5de..1944b8d 100755 --- a/tests/histogram/NdArrayDataset_TestCase.py +++ b/tests/histogram/NdArrayDataset_TestCase.py @@ -12,8 +12,7 @@ # -from pyre.units.length import meter - +from histogram.utils.units.length import meter import unittest from unittestX import TestCase