示例#1
0
 def __init__(self,
              value=None,
              units='',
              uncertainty=None,
              uncertainty_type='+|-'):
     Units.__init__(self, units)
     self.value = value if value is not None else np.array([0.0])
     self.uncertainty_type = uncertainty_type
     if uncertainty is None or np.array_equal(uncertainty, np.array([0.0])):
         self.uncertainty = np.zeros_like(self.value)
     elif isinstance(uncertainty, (int, float)):
         self.uncertainty = np.ones_like(self.value) * uncertainty
     else:
         uncertainty = np.array(uncertainty)
         if uncertainty.ndim != self.value.ndim:
             raise QuantityError(
                 'The given uncertainty has {0:d} dimensions, while the given value has {1:d}'
                 ' dimensions.'.format(uncertainty.ndim, self.value.ndim))
         for i in range(self.value.ndim):
             if self.value.shape[i] != uncertainty.shape[i]:
                 raise QuantityError(
                     'Dimension {0:d} has {1:d} elements for the given value, but {2:d} elements for'
                     ' the given uncertainty.'.format(
                         i, self.value.shape[i], uncertainty.shape[i]))
         else:
             self.uncertainty = uncertainty
示例#2
0
    def __call__(self, *args, **kwargs):
        # Make a ScalarQuantity or ArrayQuantity object out of the given parameter
        quantity = Quantity(*args, **kwargs)
        if quantity is None:
            return quantity

        units = quantity.units

        # If the units are in the common units, then we can do the conversion
        # very quickly and avoid the slow calls to the quantities package
        if units == self.units or units in self.common_units:
            return quantity

        # Check that the units are consistent with this unit type
        # This uses the quantities package (slow!)
        units = pq.Quantity(1.0, units)
        dimensionality = units.simplified.dimensionality
        if dimensionality == self.dimensionality:
            pass
        elif dimensionality in self.extra_dimensionality:
            quantity.value_si *= self.extra_dimensionality[dimensionality]
            quantity.units = self.units
        else:
            raise QuantityError(
                'Invalid units {0!r}. Try common units: {1}'.format(
                    quantity.units, self.common_units))

        # Return the Quantity or ArrayQuantity object object
        return quantity
示例#3
0
 def uncertainty_type(self, v):
     """
     Check the uncertainty type is valid, then set it.
     """
     if v not in ['+|-', '*|/']:
         raise QuantityError('Unexpected uncertainty type "{0}"; valid values are "+|-" and "*|/".'.format(v))
     self._uncertainty_type = v
示例#4
0
 def uncertainty_type(self, v):
     """
     Check the uncertainty type is valid, then set it.
     
     If you set the uncertainty then change the type, we have no idea what to do with 
     the units. This ensures you set the type first.
     """
     if v not in ['+|-', '*|/']:
         raise QuantityError('Unexpected uncertainty type "{0}"; valid values are "+|-" and "*|/".'.format(v))
     self._uncertainty_type = v
示例#5
0
def SurfaceRateCoefficient(*args, **kwargs):
    # Make a ScalarQuantity or ArrayQuantity object out of the given parameter
    quantity = Quantity(*args, **kwargs)
    if quantity is None:
        return quantity

    units = quantity.units

    # If the units are in the common units, then we can do the conversion
    # very quickly and avoid the slow calls to the quantities package
    if units in SURFACERATECOEFFICIENT_COMMON_UNITS:
        return quantity

    dimensionality = pq.Quantity(1.0, quantity.units).simplified.dimensionality
    try:
        factor = SURFACERATECOEFFICIENT_CONVERSION_FACTORS[dimensionality]
        quantity.value_si *= factor
    except KeyError:
        raise QuantityError('Invalid units {0!r}.'.format(quantity.units))

    # Return the Quantity or ArrayQuantity object object
    return quantity
示例#6
0
def Quantity(*args, **kwargs):
    """
    Create a :class:`ScalarQuantity` or :class:`ArrayQuantity` object for a
    given physical quantity. The physical quantity can be specified in several
    ways:
    
    * A scalar-like or array-like value (for a dimensionless quantity)
    
    * An array of arguments (including keyword arguments) giving some or all of
      the `value`, `units`, `uncertainty`, and/or `uncertainty_type`.
    
    * A tuple of the form ``(value,)``, ``(value,units)``, 
      ``(value,units,uncertainty)``, or 
      ``(value,units,uncertainty_type,uncertainty)``
    
    * An existing :class:`ScalarQuantity` or :class:`ArrayQuantity` object, for
      which a copy is made
    
    """
    # Initialize attributes
    value = None
    units = ''
    uncertainty_type = '+|-'
    uncertainty = None

    if len(args) == 1 and len(kwargs) == 0 and args[0] is None:
        return None

    # Unpack args if necessary
    if isinstance(args, tuple) and len(args) == 1 and isinstance(
            args[0], tuple):
        args = args[0]

    # Process args
    n_args = len(args)
    if n_args == 1 and isinstance(args[0], (ScalarQuantity, ArrayQuantity)):
        # We were given another quantity object, so make a (shallow) copy of it
        other = args[0]
        value = other.value
        units = other.units
        uncertainty_type = other.uncertainty_type
        uncertainty = other.uncertainty
    elif n_args == 1:
        # If one parameter is given, it should be a single value
        value, = args
    elif n_args == 2:
        # If two parameters are given, it should be a value and units
        value, units = args
    elif n_args == 3:
        # If three parameters are given, it should be a value, units and uncertainty
        value, units, uncertainty = args
    elif n_args == 4:
        # If four parameters are given, it should be a value, units, uncertainty type, and uncertainty
        value, units, uncertainty_type, uncertainty = args
    elif n_args != 0:
        raise QuantityError(
            'Invalid parameters {0!r} passed to ArrayQuantity.__init__() method.'
            .format(args))

    # Process kwargs
    for k, v in kwargs.items():
        if k == 'value':
            if len(args) >= 1:
                raise QuantityError(
                    'Multiple values for argument {0} passed to ArrayQuantity.__init__() method.'
                    .format(k))
            else:
                value = v
        elif k == 'units':
            if len(args) >= 2:
                raise QuantityError(
                    'Multiple values for argument {0} passed to ArrayQuantity.__init__() method.'
                    .format(k))
            else:
                units = v
        elif k == 'uncertainty':
            if len(args) >= 3:
                raise QuantityError(
                    'Multiple values for argument {0} passed to ArrayQuantity.__init__() method.'
                    .format(k))
            else:
                uncertainty = v
        elif k == 'uncertainty_type':
            if len(args) >= 4:
                raise QuantityError(
                    'Multiple values for argument {0} passed to ArrayQuantity.__init__() method.'
                    .format(k))
            else:
                uncertainty_type = v
        else:
            raise QuantityError(
                'Invalid keyword argument {0} passed to ArrayQuantity.__init__() method.'
                .format(k))

    # Process units and uncertainty type parameters
    if uncertainty_type not in ['+|-', '*|/']:
        raise QuantityError(
            'Unexpected uncertainty type "{0}"; valid values are "+|-" and "*|/".'
            .format(uncertainty_type))

    if isinstance(value, (list, tuple, np.ndarray)):
        return ArrayQuantity(value, units, uncertainty, uncertainty_type)

    try:
        value = float(value)
    except TypeError:
        return ArrayQuantity(value, units, uncertainty, uncertainty_type)

    uncertainty = 0.0 if uncertainty is None else float(uncertainty)
    return ScalarQuantity(value, units, uncertainty, uncertainty_type)