# -*- coding: UTF-8 -*-
#####################################################################
# #
# UnitConversionBase.py #
# #
# Copyright 2013, Monash University #
# #
# This file is part of the labscript suite (see #
# http://labscriptsuite.org) and is licensed under the Simplified #
# BSD License. See the license.txt file in the root of the project #
# for the full license. #
# #
#####################################################################
import copy
from types import MethodType
import math
from numpy import iterable, array
class _MultiplicativeConversion(object):
"""Callable for conversion functions that are just multiplicative
transformations of another conversion function"""
def __init__(self, name, unprefixed_method, factor, to_base):
self.unprefixed_method = unprefixed_method
self.factor = float(factor)
self.to_base = bool(to_base)
self.__name__ = name
def __get__(self, instance, class_):
"""Bind like an instance method"""
return MethodType(self, instance)
def __call__(self, value):
if self.to_base:
return self.unprefixed_method(value * self.factor)
else:
return self.unprefixed_method(value) / self.factor
[docs]
def vectorise(method):
def f(instance, arg):
if iterable(arg):
return array([method(instance, el) for el in arg])
else:
return method(instance, arg)
return f
[docs]
class UnitConversion(object):
_magnitude_list = {'p': 1e-12,'n':1e-9, 'u':1e-6,'m': 1e-3,
'k': 1e3, 'M': 1e6,'G': 1e9,'T': 1e12}
unit_list = _magnitude_list # alias for backward compat
[docs]
def __init__(self, params):
magnitudes = params.get('magnitudes', [])
# Convert any unicode 'mu' symbol to a 'u':
magnitudes = [p if p != '\u03bc' else 'u' for p in magnitudes]
self._magnitudes = {prefix: self._magnitude_list[prefix] for prefix in magnitudes}
# A list of tuples we will use to sort the list of derived units once
# we produce the units for the provided magnitudes:
derived_units_sortlist = []
for i, derived_unit in enumerate(self.derived_units):
# Append the unit magnitude derived unit to the list:
sortinfo = (i, 1)
derived_units_sortlist.append((sortinfo, derived_unit))
# Dynamically create instance methods for each other magnitude:
unprefixed_to_base = getattr(self, derived_unit + "_to_base")
unprefixed_from_base = getattr(self, derived_unit + "_from_base")
for prefix, factor in self._magnitudes.items():
unit = prefix + derived_unit
to_base_name = unit + "_to_base"
from_base_name = unit + "_from_base"
self.__dict__[to_base_name] = _MultiplicativeConversion(to_base_name, unprefixed_to_base, factor, to_base=True)
self.__dict__[from_base_name] = _MultiplicativeConversion(from_base_name, unprefixed_from_base, factor, to_base=False)
# Append to the sortlist:
sortinfo = (i, factor)
derived_units_sortlist.append((sortinfo, unit))
# Sort derived units first by position of the unit in the original
# list of derived_units without prefixes, then by magnitude:
derived_units_sortlist.sort()
self.derived_units = [unit for sortinfo, unit in derived_units_sortlist]
self.units = self._magnitudes # alias for backward compat