diff options
author | pikusa <pikusa@man.poznan.pl> | 2013-04-03 13:18:17 (GMT) |
---|---|---|
committer | pikusa <pikusa@man.poznan.pl> | 2013-04-03 13:18:17 (GMT) |
commit | 2f2a3a129c91de540e66c3bfbe30b0df1942cd4b (patch) | |
tree | 2d313cdf0068af368d4de6067d676be16f6a6464 /Monitoring/MonitoringService/DataProcessing/Dimension.py | |
parent | ff8aa232b071a9b54dff833714a870fd0aec0b30 (diff) | |
download | novi-public-2f2a3a129c91de540e66c3bfbe30b0df1942cd4b.zip novi-public-2f2a3a129c91de540e66c3bfbe30b0df1942cd4b.tar.gz novi-public-2f2a3a129c91de540e66c3bfbe30b0df1942cd4b.tar.bz2 |
project commit and dir tree change
Diffstat (limited to 'Monitoring/MonitoringService/DataProcessing/Dimension.py')
-rw-r--r-- | Monitoring/MonitoringService/DataProcessing/Dimension.py | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/Monitoring/MonitoringService/DataProcessing/Dimension.py b/Monitoring/MonitoringService/DataProcessing/Dimension.py new file mode 100644 index 0000000..0365ee2 --- /dev/null +++ b/Monitoring/MonitoringService/DataProcessing/Dimension.py @@ -0,0 +1,309 @@ +''' +Created on Feb 27, 2012 + +@author: steger +''' +from Unit import UnitManager +from DataProcessing.MeasurementLevel import MeasurementLevel, Interval, Ratio +from DataProcessing.DataError import DimensionError + +class DimensionManager(object): + ''' + @summary: the dimension container + @ivar dimenstions: the container of the known dimensions + @type dimensions: dict(str: L{Dimension}) + @ivar unitmanager: reference to the unit manager + @type unitmanager: L{UnitManager} + ''' + class Dimension(object): + ''' + @summary: a skeleton class for all the dimensions handled by L{DimensionManager} + @ivar manager: back reference to the dimension manager + @type manager: L{DimensionManager} + @ivar unitmanager: a reference to the unit manager + @type unitmanager: L{UnitManager} + @ivar reference: the unique identifier of the dimension + @ivar name: the name of the dimension + @type name: str + @ivar unit: the default unit of the dimension + @type unit: L{Unit} + @ivar basin: the set of units which are valid for this dimension + @type basin: set(L{Unit}) + ''' + def __init__(self, dimensionmanager, reference, name, unit, level): + ''' + @summary: constructor + @param dimensionmanager: reference to the dimension manager + @type dimensionmanager: L{DimensionManager} + @param reference: the reference to the dimension + @type reference: str + @param unit: the default unit of the dimension + @type unit: L{Unit} + @param level: the measurement level of the dimension + @type level: L{MeasurementLevel} + @note: the level is not a class instance + @raise L{DimensionError}: Wrong type of unit / Wrong type of level + ''' + if not isinstance(unit, UnitManager.Unit): + raise DimensionError("Wrong type of unit %s" % unit) + try: + if not issubclass(level, MeasurementLevel): + raise DimensionError("Wrong type of level %s" % level) + except TypeError: + raise DimensionError("Wrong type of level %s" % level) + self._data = (dimensionmanager, reference, name, unit) + self._level = level + @property + def manager(self): + return self._data[0] + @property + def unitmanager(self): + return self._data[0].unitmanager + @property + def reference(self): + return self._data[1] + @property + def name(self): + return self._data[2] + @property + def unit(self): + return self._data[3] + @property + def basin(self): + return self.unitmanager.getBasinByUnit(self.unit) + def level(self, level): + ''' + @summary: check measurement level against the given level + @param level: measurement level + @type level: L{MeasurementLevel} + @return: True if the measurement level given as a parameter + is the same or looser than the level of the dimension + @rtype: bool + @raise L{DimensionError}: Wrong type of level + ''' + if not issubclass(level, MeasurementLevel): + raise DimensionError("Wrong type of level %s" % level) + return issubclass(self._level, level) + def __str__(self): + return "%s [%s]" % (self.name, self.unit) + def __eq__(self, d): + if not isinstance(d, DimensionManager.Dimension): + raise DimensionError("wrong type") + return self._level == d._level and self.containsUnit(d.unit) + def containsUnit(self, unit): + ''' + @summary: checks if a given unit is in the basin of this dimension + @param unit: the unit to check + @type unit: L{Unit} + @return: true if the unit is applicable for this dimension + @rtype: bool + ''' + return unit in self.unitmanager.getBasinByUnit(self.unit) + + class BaseDimension(Dimension): + ''' + @summary: a dimension axiom + ''' + pass + + class DerivedDimension(Dimension): + ''' + @summary: a skeleton for dimensions, which are deriving from other already known dimensions + ''' + def ancestors(self): + ''' + @summary: iterate over all ancestors this dimension is derived from + @return: generator over ancestors + @rtype: L{Dimension} + ''' + for d in self._ancestor: + yield d + + class DifferenceDimension(DerivedDimension): + ''' + @summary: a dimension defined by subtracting two individuals of a known dimension + ''' + def __init__(self, dimensionmanager, reference, name, unit, derivedfrom): + ''' + @summary: constructor + @param dimensionmanager: reference to the dimension manager + @type dimensionmanager: L{DimensionManager} + @param reference: the reference to the dimension + @param unit: the default unit of the dimension + @type unit: L{Unit} + @param derivedfrom: the ancestor dimension this dimension is derived from + @type derivedfrom: L{Dimension} + @raise L{DimensionError}: Wrong type of derivedfrom + ''' + if not isinstance(derivedfrom, DimensionManager.Dimension): + raise DimensionError("Wrong type of derivedfrom") + if not derivedfrom.level(Interval): + raise DimensionError("Cannot subtract %s" % derivedfrom) + DimensionManager.Dimension.__init__(self, dimensionmanager, reference, name, unit, Ratio) + self._ancestor = derivedfrom + + class PowerDimension(DerivedDimension): + ''' + @summary: a dimension defined by raising an existing dimension to a given power + @ivar exponent: the power + @type exponent: int + ''' + def __init__(self, dimensionmanager, reference, name, unit, derivedfrom, exponent): + ''' + @summary: constructor + @param dimensionmanager: reference to the dimension manager + @type dimensionmanager: L{DimensionManager} + @param reference: the reference to the dimension + @param unit: the default unit of the dimension + @type unit: L{Unit} + @param derivedfrom: the ancestor dimension this dimension is derived from + @type derivedfrom: L{Dimension} + @param exponent: dimension is a derivative of the derivedfrom dimension, by raising to power exponent + @type exponent: int + @raise DimensionError: Wrong type of derivedfrom / Cannot power + ''' + if not isinstance(derivedfrom, DimensionManager.Dimension): + raise DimensionError("Wrong type of derivedfrom") + if not derivedfrom.level(Ratio): + raise DimensionError("Cannot power %s" % derivedfrom) + DimensionManager.Dimension.__init__(self, dimensionmanager, reference, name, unit, Ratio) + self._ancestor = (derivedfrom,) + self._exponent = exponent + @property + def exponent(self): + return self._exponent + + class ProductDimension(DerivedDimension): + ''' + @summary: dimension defined by multiplying at least two known different dimensions + ''' + def __init__(self, dimensionmanager, reference, name, unit, derivedfrom): + ''' + @summary: constructor + @param dimensionmanager: reference to the dimension manager + @type dimensionmanager: L{DimensionManager} + @param reference: the reference to the dimension + @param unit: the default unit of the dimension + @type unit: L{Unit} + @param derivedfrom: the set of dimensions that compose this dimension + @type derivedfrom: tuple(L{Dimension}) + @raise L{DimensionError}: Wrong type of derivedfrom / ProductDimension is derived from more than 2 Dimensions / Cannot be a factor + ''' + if not isinstance(derivedfrom, tuple): + raise DimensionError("Wrong type of derivedfrom") + if len(derivedfrom) < 2: + raise DimensionError("ProductDimension is derived from more than 2 Dimensions, got %d instead" % len(derivedfrom)) + for d in derivedfrom: + if not d.level(Ratio): + raise DimensionError("%s cannot be a factor" % d) + DimensionManager.Dimension.__init__(self, dimensionmanager, reference, name, unit, Ratio) + self._ancestor = derivedfrom + + class RatioDimension(DerivedDimension): + ''' + @summary: dimension defined by dividing two known dimensions + ''' + def __init__(self, dimensionmanager, reference, name, unit, derivedfrom): + ''' + @summary: constructor + @param dimensionmanager: reference to the dimension manager + @type dimensionmanager: L{DimensionManager} + @param reference: the reference to the dimension + @param unit: the default unit of the dimension + @type unit: L{Unit} + @param derivedfrom: the set of dimensions that compose this dimension + @type derivedfrom: tuple(L{Dimension}) + @raise L{DimensionError}: Wrong type of derivedfrom / Cannot be a factor + ''' + if not isinstance(derivedfrom, DimensionManager.Dimension): + raise DimensionError("Wrong type of derivedfrom") + if not derivedfrom.level(Ratio): + raise DimensionError("%s cannot be a factor" % derivedfrom) + DimensionManager.Dimension.__init__(self, dimensionmanager, reference, name, unit, Ratio) + self._ancestor = (derivedfrom,) + + def __init__(self, unitmanager): + ''' + @summary: constructor + @param unitmanager: the unit manager needs to be referenced, to check the basins of a unit + @type unitmanager: L{UnitManager} + ''' + self.dimensions = {} + self.unitmanager = unitmanager + + def __len__(self): + ''' + @summary: the number of dimension known by the L{DimensionManager} + @return: the number of dimension known by the L{DimensionManager} + @rtype: int + ''' + return len(self.dimensions) + + def __iter__(self): + ''' + @summary: an iterator over known dimensions + @return: the next known dimension + @rtype: L{Dimension} + ''' + for d in self.dimensions.values(): + yield d + + def newBaseDimension(self, reference, name, unit, level): + ''' + @summary: generate a new dimension + @param reference: the reference to the dimension + @type reference: str + @param unit: the default unit of the dimension + @type unit: L{Unit} + @param level: the measurement level of the dimension + @type level: L{MeasurementLevel} + @note: the level is not a class instance + @return: the new dimension + @rtype: L{Dimension} + @raise L{DimensionError}: Dimension with reference already exists / Wrong type of unit / Wrong type of level / Wrong type of dimension / + Expecting derivedfrom set / Wrong number of derived from Dimensions + ''' + if self.dimensions.has_key(reference): + raise DimensionError("Dimension with reference %s already exists" % reference) + dimension = self.BaseDimension(self, reference, name, unit, level) + self.dimensions[reference] = dimension + return dimension + + def newDerivedDimension(self, reference, name, unit, derivedfrom, dimtype, **kw): + ''' + @summary: generate a new dimension + @param reference: the reference to the dimension + @param unit: the default unit of the dimension + @type unit: L{Unit} + @param derivedfrom: the set of dimensions that compose this dimension + @type derivedfrom: tuple(L{Dimension}) or L{Dimension} + @param dimtype: possible dimension types are L{DifferenceDimension}, L{PowerDimension}, L{ProductDimension}, L{RatioDimension} + @note: dimtype parameter is not an instance, but a class scheme + @type dimtype: L{Dimension} + @return: the new dimension + @rtype: L{Dimension} + @keyword kw: L{PowerDimension} expects an integer valued parameter: exponent + @raise L{DimensionError}: Dimension with reference already exists / Wrong type of dimension + ''' + if self.dimensions.has_key(reference): + raise DimensionError("Dimension with reference %s already exists" % reference) + if issubclass(dimtype, self.DifferenceDimension)or issubclass(dimtype, self.ProductDimension) or issubclass(dimtype, self.RatioDimension): + dimension = dimtype(self, reference, name, unit, derivedfrom) + elif issubclass(dimtype, self.PowerDimension): + dimension = dimtype(self, reference, name, unit, derivedfrom, kw.get('exponent')) + else: + raise DimensionError("Wrong type of dimension %s" % dimtype) + self.dimensions[reference] = dimension + return dimension + + def __getitem__(self, reference): + ''' + @summary: look up the prefix in the DimensionManager based on its reference + @param reference: the reference to the dimension + @return: the dimension if found + @rtype: L{Dimension} + @raise L{DimensionError}: Dimension with reference not found + ''' + if not self.dimensions.has_key(reference): + raise DimensionError("Dimension with reference %s not found" % reference) + return self.dimensions[reference] |