Beispiel #1
0
    def __convert_other(self, other):
        su = getattr(self, 'units', dimensionless)
        ou = getattr(other, 'units', dimensionless)

        if su == None and ou == None:
            u = None
        else:
            if isinstance(other, units.unit.unit):
                # Handles 5 * liters
                ou = units.unit.unit(1, other.derivation)
                other = units.convert(other.value, ou, su)
            elif isinstance(other, UnitArray):
                # Handles UnitArray or UnitScalar
                other = units.convert(numpy.array(other), ou, su)
            elif isinstance(other, numpy.ndarray):
                if len(other.shape) > 0 and hasattr(other.item(0),
                                                    'derivation'):
                    # Handles array([1,2,3] * liters)
                    ou = units.unit.unit(1, other.item(0).derivation)
                    other = units.convert(other / ou, ou, su)
            else:
                #Everything else
                other = units.convert(numpy.array(other), ou, su)
            u = su
        return other, u
    def setUp(self):
        unittest.TestCase.setUp(self)

        # Put unit adapters on either side of a masking adapter to see if they
        # cooperate. Store meters in the raw context, push fathoms through the
        # mask, and expose feet to the outside world.
        self.units = units = { 'in':meters, 'mid':fathom, 'out':feet }

        # Set up data for the contexts
        depth = Log(linspace(0.0, 100.0, 11), units=units['in'])
        lith = array(['sand']*len(depth), dtype=object)

        # Create the contexts
        self.context = PassThruContext( ReductionContext( NumericContext() ) )
        self.raw_context = self.context.context_base

        # Add data (before creating the adapters)
        self.context.update(depth=depth, lith=lith)

        # (This simplifies creating UnitConversionAdapters)
        def always(value):
            class C(dict):
                def get(self, key, default=None):
                    return value
                def __repr__(self):
                    return '{*:%r}' % value
            return C()

        # Layer multiple adapters
        self.mask = (15.0 < depth) & (depth < 55.0)
        self.convert_out = lambda x: convert(x, units['in'], units['out'])
        self.convert_in = lambda x: convert(x, units['out'], units['in'])
        self.context.get_reduction_context(OpenContext).context_filter = \
            MaskFilter( mask = self.mask )
Beispiel #3
0
    def test_convert(self):
        t1 = units.convert(60, angle.minutes, angle.degree)
        self.assertAlmostEqual(t1, 1)

        t1 = units.convert(3600, angle.seconds, angle.degree)
        self.assertAlmostEqual(t1, 1)

        t1 = units.convert(1, angle.degree, angle.radian)
        self.assertAlmostEqual(t1, numpy.pi / 180.)
Beispiel #4
0
 def _compute_force(self, mass, acc, mass_units=kg, acc_units=ms2, **unused_units):
     """
     """
     # algorithm units are
     mass_u = kg
     acc_u = ms2
     # convert into algorithm units
     mass = units.convert(mass, mass_units, mass_u)
     acc = units.convert(acc, acc_units, acc_u)
     # do the math :-)
     return mass * acc
Beispiel #5
0
 def _compute_force(self, mass, acc, mass_units=kg,
                    acc_units=ms2, **unused_units):
     """
     """
     # algorithm units are
     mass_u = kg
     acc_u = ms2
     # convert into algorithm units
     mass = units.convert(mass, mass_units, mass_u)
     acc = units.convert(acc, acc_units, acc_u)
     # do the math :-)
     return mass * acc
 def test_temperature(self):
     k = 200
     c = -73.15
     f = -99.67
     k2c = units.convert(k, kelvin, celsius)
     self.assertAlmostEqual(k2c, c)
     k2f = units.convert(k, kelvin, fahrenheit)
     self.assertAlmostEqual(k2f, f)
     f2c = units.convert(f, fahrenheit, celsius)
     self.assertAlmostEqual(f2c, c)
     t1 = units.convert(-40.0, temperature.fahrenheit, temperature.celsius)
     self.assertAlmostEqual(t1, -40.0, 6)
     t2 = units.convert(0.0, temperature.celsius, temperature.fahrenheit)
     self.assertAlmostEqual(t2, 32.0, 6)
     return
Beispiel #7
0
    def test_convert(self):
        t1 = units.convert(1, time.year, time.second)
        self.assertAlmostEqual(t1, (365.25 * 24 * 60 * 60), 6)

        t1 = units.convert(1, time.week, time.second)
        self.assertAlmostEqual(t1, (7 * 24 * 60 * 60))

        t1 = units.convert(1, time.day, time.second)
        self.assertAlmostEqual(t1, (24 * 60 * 60))

        t1 = units.convert(1, time.hour, time.second)
        self.assertAlmostEqual(t1, 60 * 60)

        t1 = units.convert(1, time.minute, time.second)
        self.assertAlmostEqual(t1, 60)
Beispiel #8
0
 def test_temperature(self):
     k = 200
     c = -73.15
     f = -99.67
     k2c = units.convert(k, kelvin, celsius)
     self.assertAlmostEqual(k2c, c)
     k2f = units.convert(k, kelvin, fahrenheit)
     self.assertAlmostEqual(k2f, f)
     f2c = units.convert(f, fahrenheit, celsius)
     self.assertAlmostEqual(f2c, c)
     t1 = units.convert(-40.0, temperature.fahrenheit, temperature.celsius)
     self.assertAlmostEqual(t1, -40.0, 6)
     t2 = units.convert(0.0, temperature.celsius, temperature.fahrenheit)
     self.assertAlmostEqual(t2, 32.0, 6)
     return
Beispiel #9
0
    def as_units(self, new_units):
        """ Convert UnitArray from its current units to a new set of units.

        """
        result = self.__class__(units.convert(self.view(numpy.ndarray), self.units, new_units))
        result.units = new_units

        return result
Beispiel #10
0
    def as_units(self, new_units):
        """ Convert UnitArray from its current units to a new set of units.

        """
        result = self.__class__(
            units.convert(self.view(numpy.ndarray), self.units, new_units))
        result.units = new_units

        return result
    def setUp(self):
        unittest.TestCase.setUp(self)

        # Put unit adapters on either side of a masking adapter to see if they
        # cooperate. Store meters in the raw context, push fathoms through the
        # mask, and expose feet to the outside world.
        self.units = units = {'in': meters, 'mid': fathom, 'out': feet}

        # Set up data for the contexts
        depth = UnitArray(linspace(0.0, 100.0, 11), units=units['in'])
        lith = array(['sand'] * len(depth), dtype=object)

        # Create the contexts
        self.context = AdaptedDataContext(subcontext=DataContext())
        self.raw_context = self.context.subcontext

        # Add data (before creating the adapters)
        self.context.update(depth=depth, lith=lith)

        # (This simplifies creating UnitConversionAdapters)
        def always(value):
            class C(dict):
                def get(self, key, default=None):
                    return value

                def __repr__(self):
                    return '{*:%r}' % value

            return C()

        # Layer multiple adapters
        d = depth.view(ndarray)
        self.mask = (15.0 < d) & (d < 55.0)
        self.convert_out = lambda x: convert(x, units['in'], units['out'])
        self.convert_in = lambda x: convert(x, units['out'], units['in'])
        #self.context.push_adapter(
        #    UnitConversionAdapter(setitem_units=always(units['in']),
        #                          getitem_units=always(units['mid'])))
        self.context.push_adapter(MaskingAdapter(mask=self.mask))
        self.context.push_adapter(
            #    UnitConversionAdapter(setitem_units=always(units['mid']),
            UnitConversionAdapter(setitem_units=always(units['in']),
                                  getitem_units=always(units['out'])))
Beispiel #12
0
def unit_array_units_converter(unit_array, new_units):
    """ Convert a UnitArray from one set of units to another.
    """
    if unit_array.units != new_units:
        # Need conversion.
        if isinstance(unit_array, ndarray) and unit_array.shape != ():
            # this is an array
            result = UnitArray(units.convert(unit_array.view(ndarray), unit_array.units,
                                   new_units))
        else:
            # this is a scalar
            result = UnitScalar(units.convert(unit_array.view(ndarray), unit_array.units,
                                   new_units))
        result.units = new_units
    else:
        # No conversion needed.  Just return the unit_array.
        result = unit_array

    return result
Beispiel #13
0
def unit_array_units_converter(unit_array, new_units):
    """ Convert a UnitArray from one set of units to another.
    """
    if unit_array.units != new_units:
        # Need conversion.
        if isinstance(unit_array, ndarray) and unit_array.shape != ():
            # this is an array
            result = UnitArray(units.convert(unit_array.view(ndarray), unit_array.units,
                                             new_units))
        else:
            # this is a scalar
            result = UnitScalar(units.convert(unit_array.view(ndarray), unit_array.units,
                                              new_units))
        result.units = new_units
    else:
        # No conversion needed.  Just return the unit_array.
        result = unit_array

    return result
    def setUp(self):
        unittest.TestCase.setUp(self)

        # Put unit adapters on either side of a masking adapter to see if they
        # cooperate. Store meters in the raw context, push fathoms through the
        # mask, and expose feet to the outside world.
        self.units = units = { 'in':meters, 'mid':fathom, 'out':feet }

        # Set up data for the contexts
        depth = UnitArray(linspace(0.0, 100.0, 11), units=units['in'])
        lith = array(['sand']*len(depth), dtype=object)

        # Create the contexts
        self.context = AdaptedDataContext(subcontext=DataContext())
        self.raw_context = self.context.subcontext

        # Add data (before creating the adapters)
        self.context.update(depth=depth, lith=lith)

        # (This simplifies creating UnitConversionAdapters)
        def always(value):
            class C(dict):
                def get(self, key, default=None):
                    return value
                def __repr__(self):
                    return '{*:%r}' % value
            return C()

        # Layer multiple adapters
        d = depth.view(ndarray)
        self.mask = (15.0 < d) & (d < 55.0)
        self.convert_out = lambda x: convert(x, units['in'], units['out'])
        self.convert_in = lambda x: convert(x, units['out'], units['in'])
        #self.context.push_adapter(
        #    UnitConversionAdapter(setitem_units=always(units['in']),
        #                          getitem_units=always(units['mid'])))
        self.context.push_adapter(MaskingAdapter(mask=self.mask))
        self.context.push_adapter(
        #    UnitConversionAdapter(setitem_units=always(units['mid']),
            UnitConversionAdapter(setitem_units=always(units['in']),
                                  getitem_units=always(units['out'])))
Beispiel #15
0
    def __convert_other(self, other):
        su = getattr(self, 'units', dimensionless)
        ou = getattr(other, 'units', dimensionless)

        if su == None and ou == None:
            u = None
        else:
            if isinstance(other, unit):
                # Handles 5 * liters
                ou = unit(1, other.derivation)
                other = convert(other.value, ou, su)
            elif isinstance(other, UnitArray):
                # Handles UnitArray or UnitScalar
                other = convert(numpy.array(other), ou, su)
            elif isinstance(other, numpy.ndarray):
                if len(other.shape) > 0 and hasattr(other.item(0), 'derivation'):
                    # Handles array([1,2,3] * liters)
                    ou = unit(1, other.item(0).derivation)
                    other = convert(other/ou, ou, su)
            u = su
        return other, u
    def test_as_units(self):
        """ Conversion from one unit system to another.
        """
        ary = numpy.array((1,2,3))
        unit_ary = UnitArray(ary, units=meters)
        new_unit_ary = unit_ary.as_units(feet)

        # Test the values are correct
        desired_array = units.convert(ary, meters, feet)
        self.assert_(numpy.all(desired_array==new_unit_ary))

        # Also, make sure the units are correctly assigned.
        self.assertEqual(new_unit_ary.units, feet)
Beispiel #17
0
    def test_as_units(self):
        """ Conversion from one unit system to another.
        """
        ary = numpy.array((1, 2, 3))
        unit_ary = UnitArray(ary, units=meters)
        new_unit_ary = unit_ary.as_units(feet)

        # Test the values are correct
        desired_array = units.convert(ary, meters, feet)
        self.assertTrue(numpy.all(desired_array == new_unit_ary))

        # Also, make sure the units are correctly assigned.
        self.assertEqual(new_unit_ary.units, feet)
Beispiel #18
0
def unit_array_units_converter(unit_array, new_units):
    """ Convert a UnitArray from one set of units to another.
    """
    if unit_array.units != new_units:
        # A conversion is needed. Must pass in a real ndarray instead of
        # a UnitArray since operations on it will also try to conversions that
        # we don't want it to do.
        result = units.convert(unit_array.view(numpy.ndarray),
                               unit_array.units, new_units).view(UnitArray)
        result.units = new_units
    else:
        # No conversion needed.  Just return the unit_array.
        result = unit_array

    return result
    def setUp(self):
        unittest.TestCase.setUp(self)

        # Put unit adapters on either side of a masking adapter to see if they
        # cooperate. Store meters in the raw context, push fathoms through the
        # mask, and expose feet to the outside world.
        self.units = units = {'in': meters, 'mid': fathom, 'out': feet}

        # Set up data for the contexts
        depth = Log(linspace(0.0, 100.0, 11), units=units['in'])
        lith = array(['sand'] * len(depth), dtype=object)

        # Create the contexts
        self.context = PassThruContext(ReductionContext(NumericContext()))
        self.raw_context = self.context.context_base

        # Add data (before creating the adapters)
        self.context.update(depth=depth, lith=lith)

        # (This simplifies creating UnitConversionAdapters)
        def always(value):
            class C(dict):
                def get(self, key, default=None):
                    return value

                def __repr__(self):
                    return '{*:%r}' % value

            return C()

        # Layer multiple adapters
        self.mask = (15.0 < depth) & (depth < 55.0)
        self.convert_out = lambda x: convert(x, units['in'], units['out'])
        self.convert_in = lambda x: convert(x, units['out'], units['in'])
        self.context.get_reduction_context(OpenContext).context_filter = \
            MaskFilter( mask = self.mask )
def unit_array_units_converter(unit_array, new_units):
    """ Convert a UnitArray from one set of units to another.
    """
    if unit_array.units != new_units:
        # A conversion is needed. Must pass in a real ndarray instead of
        # a UnitArray since operations on it will also try to conversions that
        # we don't want it to do.
        result = units.convert(unit_array.view(numpy.ndarray), unit_array.units,
            new_units).view(UnitArray)
        result.units = new_units
    else:
        # No conversion needed.  Just return the unit_array.
        result = unit_array

    return result
def convert_units(unitted_data, tgt_unit, **kwargs):
    """ Convert unitted data to the units specified by `tgt_unit`.

    Parameters
    ----------
    unitted_data : UnitScalar or UnitArray
        The data to be converted to `tgt_unit`

    tgt_unit : scimath.unit or str
        The target units for `unitted_data`.

    kwargs : dict
        Additional arguments that may be needed by custom converters for
        special units.

    Returns
    -------
    UnitScalar or UnitArray
        The converted data.
    """
    if isinstance(tgt_unit, basestring):
        tgt_unit = unit_parser.parse_unit(tgt_unit)

    if isinstance(unitted_data, UnitScalar):
        unit_klass = UnitScalar
    elif isinstance(unitted_data, UnitArray):
        unit_klass = UnitArray
    else:
        msg = "The `unitted_data` argument must be an instance of either " \
              "scimath's UnitScalar or UnitArray but got {}."
        msg = msg.format(unitted_data.__class__.__name__)
        logger.exception(msg)
        raise ValueError(msg)

    src_unit = unitted_data.units
    if (src_unit.label, tgt_unit.label) in CUSTOM_UNITS_CONVERTERS:
        converter = CUSTOM_UNITS_CONVERTERS[(src_unit.label, tgt_unit.label)]
        unitted_data = converter(unitted_data, **kwargs)
        return unit_klass(unitted_data, units=tgt_unit)

    else:
        data = np.array(unitted_data.tolist())
        data = convert(data, src_unit, tgt_unit)
        return unit_klass(data, units=tgt_unit)
Beispiel #22
0
    def add_processor(self, func, *args, **kwargs):
        """
        Add a new processor and bind it to a set of parameters.
        - func should be a function implementing the numpy ufunc class. If not,
          then the signature and types keyword arguments will be necessary.
        - args is a list of names and constants. The names link to internal
          numpy array variables that will be bound to the function. Names can
          be given in the form:
            "varname(length, type)[range]"
          The optional (length, type) field is used to initialize a new variable
          if necessary. The optional [range] field copies binds only a subrange
          of the array to the function. Non-string constant values will be
          converted to the right type and bound to the function. Constants with
          scimath time units will be converted to the internal clock unit.
        - keyword arguments include:
          - signature: broadcasting signature for a ufunc. By default, use
            func.signature
          - types: a list of strings defining the types of arrays needed for
            the func. By default, use func.types
        """

        # Get the signature and list of valid types for the function
        signature = kwargs.get("signature", None)
        if (signature == None): signature = func.signature
        if (signature == None):
            signature = '->'
            for i in range(func.nin):
                signature = ',()' + signature
            for i in range(func.nout):
                signature = signature + '(),'
            signature = signature.strip(',')

        types = kwargs.get("types", None)
        if (types == None): types = func.types.copy()
        if (types == None):
            raise TypeError("Could not find a type signature list for " +
                            func.__name__ +
                            ". Please supply a valid list of types.")
        for i, typestr in enumerate(types):
            types[i] = typestr.replace('->', '')

        # make a list of parameters from *args. Replace any strings in the list
        # with numpy objects from vars_dict, where able
        params = []
        for i, param in enumerate(args):
            if (isinstance(param, str)):
                param_val = self.get_variable(param)
                if param_val is not None:
                    param = param_val
            params.append(param)

        # Make sure arrays obey the broadcasting rules, and make a dictionary
        # of the correct dimensions
        dims_list = re.findall("\((.*?)\)", signature)
        dims_dict = {}
        outerdims = []
        # print('\nsetting param:', params[-1])
        # print('dims list is:', dims_list)
        for ipar, dims in enumerate(dims_list):
            # print(ipar, dims, params[ipar])
            if not isinstance(params[ipar], np.ndarray):
                continue

            fun_dims = outerdims + [d.strip() for d in dims.split(',') if d]
            arr_dims = list(params[ipar].shape)
            #check if arr_dims can be broadcast to match fun_dims
            for i in range(max(len(fun_dims), len(arr_dims))):
                fd = fun_dims[-i - 1] if i < len(fun_dims) else None
                ad = arr_dims[-i - 1] if i < len(arr_dims) else None
                if (isinstance(fd, str)):
                    # Define the dimension or make sure it is consistent
                    if not ad or dims_dict.setdefault(fd, ad) != ad:
                        raise ValueError(
                            "Failed to broadcast array dimensions for " +
                            func.__name__ +
                            ". Could not find consistent value for dimension "
                            + fd)
                elif not fd:
                    # if we ran out of function dimensions, add a new outer dim
                    outerdims.insert(0, ad)
                elif not ad:
                    continue
                elif fd != ad:
                    # If dimensions disagree, either insert a broadcasted array dimension or raise an exception
                    if len(fun_dims) > len(arr_dims):
                        arr_dims.insert(len(arr_dims) - i, 1)
                    elif len(fun_dims) < len(arr_dims):
                        outerdims.insert(len(fun_dims) - i, ad)
                        fun_dims.insert(len(fun_dims) - i, ad)
                    else:
                        raise ValueError(
                            "Failed to broadcast array dimensions for " +
                            func.__name__ +
                            ". Input arrays do not have consistent outer dimensions."
                        )

            # find type signatures that match type of array
            arr_type = params[ipar].dtype.char
            types = [
                type_sig for type_sig in types if arr_type == type_sig[ipar]
            ]

        # Get the type signature we are using
        if (not types):
            raise TypeError(
                "Could not find a type signature matching the types of the variables given for "
                + func.__name__)
        elif (len(types) > 1):
            self.__print(
                1,
                "Found multiple compatible type signatures for this function:",
                types, "Using signature " + types[0] + ".")
        types = [np.dtype(t) for t in types[0]]

        # Reshape variable arrays to add broadcast dimensions and allocate new arrays as needed
        for i, param, dims, dtype in zip(range(len(params)), params, dims_list,
                                         types):
            shape = outerdims + [
                dims_dict[d.strip()] for d in dims.split(',') if d
            ]
            if isinstance(param, str):
                params[i] = self.__add_var(param, dtype, shape)
            elif isinstance(param, np.ndarray):
                arshape = list(param.shape)
                for idim in range(-1, -1 - len(shape), -1):
                    if arshape[idim] != shape[idim]:
                        arshape.insert(len(arshape) + idim + 1, 1)
                params[i] = param.reshape(tuple(arshape))
            else:
                if isinstance(param, unit):
                    param = convert(1, param, self._clk)
                if np.issubdtype(dtype, np.integer):
                    params[i] = dtype.type(round(param))
                else:
                    params[i] = dtype.type(param)

        # Make strings of input variables/constants for later printing
        proc_strs = []
        for i, arg in enumerate(args):
            if isinstance(arg, str):
                proc_strs.append(arg)
            else:
                proc_strs.append(str(params[i]))
        proc_strs = tuple(proc_strs)

        self.__print(
            2, 'Added processor: ' + func.__name__ +
            str(proc_strs).replace("'", ""))

        # Add the function and bound parameters to the list of processors
        self.__proc_list.append((func, tuple(params)))
        self.__proc_strs.append(proc_strs)
        return None
Beispiel #23
0
 def test_time(self):
     t1 = units.convert(1, time.year, time.second)
     self.assertAlmostEqual(t1, (365.25 * 24 * 60 * 60), 6)
Beispiel #24
0
 def test_density(self):
     d1 = units.convert(1, density.lb_per_gal, density.grams_per_cubic_centimeter)
     self.assertAlmostEqual(d1, 0.1198284429, 6)
     return
 def test_density(self):
     d1 = units.convert(1, density.lb_per_gal,
                        density.grams_per_cubic_centimeter)
     self.assertAlmostEqual(d1, 0.1198284429, 6)
     return
Beispiel #26
0
    def __parse_expr(self, node):
        """
        helper function for get_variable that recursively evaluates the AST tree
        based on: https://stackoverflow.com/a/9558001.
        """
        if node is None:
            return None

        elif isinstance(node, ast.Num):
            return node.n

        elif isinstance(node, ast.Str):
            return node.s

        elif isinstance(node, ast.Constant):
            return node.val

        # look for name in variable dictionary
        elif isinstance(node, ast.Name):
            # check if it is a unit
            val = unit_parser.parse_unit(node.id)
            if val.is_valid():
                return convert(1, val, self._clk)

            #check if it is a variable
            val = self.__vars_dict.get(node.id, None)
            return val

        # define binary operators (+,-,*,/)
        elif isinstance(node, ast.BinOp):
            lhs = self.__parse_expr(node.left)
            rhs = self.__parse_expr(node.right)
            op = ast_ops_dict[type(node.op)]
            if isinstance(lhs, np.ndarray) or isinstance(rhs, np.ndarray):
                if not isinstance(lhs, np.ndarray):
                    if np.issubdtype(rhs.dtype, np.integer):
                        lhs = rhs.dtype.type(round(lhs))
                    else:
                        lhs = rhs.dtype.type(lhs)
                if not isinstance(rhs, np.ndarray):
                    if np.issubdtype(lhs.dtype, np.integer):
                        rhs = lhs.dtype.type(round(rhs))
                    else:
                        rhs = lhs.dtype.type(rhs)
                out = op(lhs, rhs)
                self.__proc_list.append((op, (lhs, rhs, out)))
                self.__proc_strs.append("Binary operator: " + op.__name__)
                return out
            return op(lhs, rhs)

        # define unary operators (-)
        elif isinstance(node, ast.UnaryOp):
            operand = self.__parse_expr(node.operand)
            op = ast_ops_dict[type(node.op)]
            out = op(operand)
            # if we have a np array, add to processor list
            if isinstance(out, np.ndarray):
                self.__proc_list.append((op, (operand, out)))
                self.__proc_strs.append("Unary operator: " + op.__name__)
            return out

        elif isinstance(node, ast.Subscript):
            # print(ast.dump(node))
            val = self.__parse_expr(node.value)
            if isinstance(node.slice, ast.Index):
                if isinstance(val, np.ndarray):
                    return val[..., self.__parse_expr(node.slice.value)]
                else:
                    return val[self.__parse_expr(node.slice.value)]
            elif isinstance(node.slice, ast.Slice):
                if isinstance(val, np.ndarray):
                    return val[...,
                               slice(self.__parse_expr(node.slice.lower),
                                     self.__parse_expr(node.slice.upper),
                                     self.__parse_expr(node.slice.step))]
                else:
                    print(self.__parse_expr(node.slice.upper))
                    return val[slice(self.__parse_expr(node.slice.upper),
                                     self.__parse_expr(node.slice.lower),
                                     self.__parse_expr(node.slice.step))]
            elif isinstance(node.slice, ast.ExtSlice):
                slices = tuple(node.slice.dims)
                for i, sl in enumerate(slices):
                    if isinstance(sl, ast.index):
                        slices[i] = self.__parse_expr(sl.value)
                    else:
                        slices[i] = slice(self.__parse_expr(sl.upper),
                                          self.__parse_expr(sl.lower),
                                          self.__parse_expr(sl.step))
                return val[..., slices]

        # for name.attribute
        elif isinstance(node, ast.Attribute):
            val = self.__parse_expr(node.value)
            # get shape with buffer_len dimension removed
            if node.attr == 'shape' and isinstance(val, np.ndarray):
                return val.shape[1:]

        # for func([args])
        elif isinstance(node, ast.Call):
            func = node.func.id
            # get length of 1D array variable
            if func == "len" and len(node.args) == 1 and isinstance(
                    node.args[0], ast.Name):
                var = self.__parse_expr(node.args[0])
                if isinstance(var, np.ndarray) and len(var.shape) == 2:
                    return var.shape[1]
                else:
                    raise ValueError("len(): " + node.args[0].id +
                                     "has wrong number of dims")
            elif func == "round" and len(node.args) == 1:
                var = self.__parse_expr(node.args[0])
                return int(round(var))
            # if this is a valid call to construct a new array, do so; otherwise raise an exception
            else:
                if len(node.args) == 2:
                    shape = self.__parse_expr(node.args[0])
                    if isinstance(shape, (int, np.int32, np.int64)):
                        shape = (self._block_width, shape)
                    elif isinstance(shape, tuple):
                        shape = (self._block_width, ) + shape
                    else:
                        raise ValueError(
                            "Do not recognize call to " + func +
                            " with arguments of types " +
                            str([arg.__dict__ for arg in node.args]))
                    try:
                        dtype = np.dtype(node.args[1].id)
                    except:
                        raise ValueError(
                            "Do not recognize call to " + func +
                            " with arguments of types " +
                            str([arg.__dict__ for arg in node.args]))

                    if func in self.__vars_dict:
                        var = self.__vars_dict[func]
                        if not var.shape == shape and var.dtype == dtype:
                            raise ValueError("Requested shape and type for " +
                                             func +
                                             " do not match existing values")
                        return var
                    else:
                        var = np.zeros(shape, dtype, 'F')
                        self.__vars_dict[func] = var
                        self.__print(
                            2, 'Added variable ' + func + ' with shape ' +
                            str(tuple(shape)) + ' and type ' + str(dtype))

                        return var
                else:
                    raise ValueError(
                        "Do not recognize call to " + func +
                        " with arguments " +
                        str([str(arg.__dict__) for arg in node.args]))

        raise ValueError("Cannot parse AST nodes of type " +
                         str(node.__dict__))
 def test_frequency(self):
     f1 = units.convert(1, frequency.hertz, frequency.khz)
     self.assertAlmostEqual(f1, 0.001, 6)
     return
Beispiel #28
0
 def test_frequency(self):
     f1 = units.convert(1, frequency.hertz, frequency.khz)
     self.assertAlmostEqual(f1, 0.001, 6)
     return
 def test_time(self):
     t1 = units.convert(1, time.year, time.second)
     self.assertAlmostEqual(t1, (365.25 * 24 * 60 * 60), 6)
Beispiel #30
0
 def test_speed(self):
     s1 = units.convert(55, speed.miles_per_hour, speed.meters_per_second)
     self.assertAlmostEqual(s1, 24.5872, 6)
 def test_speed(self):
     s1 = units.convert(55, speed.miles_per_hour, speed.meters_per_second)
     self.assertAlmostEqual(s1, 24.5872, 6)
Beispiel #32
0
    def __add_io_buffer(self, buff, varname, input, dtype, buffer_len, scale):
        """
        append a tuple with the buffer and variable to either the input buffer
        list (if input=true) or output buffer list (if input=false), making sure
        that buffer shapes are compatible
        """
        var = self.get_variable(varname)
        if buff is not None and not isinstance(buff, np.ndarray):
            raise ValueError("Buffers must be ndarrays.")

        # if buffer length is not defined, figure out what it should be
        if buffer_len is not None:
            if self._buffer_len is None:
                self._buffer_len = buffer_len
            elif self._buffer_len != buffer_len:
                raise ValueError(
                    "Buffer length was already set to a number different than the one provided. To change the buffer length, you must reset the buffers."
                )
        if not self._buffer_len:
            if buff is not None: self._buffer_len = buff.shape[0]
            else: self._buffer_len = self._block_width
            self.__print(
                1, "Setting i/o buffer length to " + str(self._buffer_len))

        # if a unit is given, convert it to a scaling factor
        if isinstance(scale, unit):
            scale = convert(1, scale, self._clk)

        # if no buffer was provided, make one
        returnbuffer = False
        if buff is None:
            if var is None:
                raise ValueError(
                    "Cannot make buffer for non-existent variable " + varname)
            # deduce dtype. If scale is used, force float type
            if not dtype:
                if not scale:
                    dtype = var.dtype
                else:
                    dtype = np.dtype('float' + str(var.dtype.itemsize * 8))
            buff = np.zeros((self._buffer_len, ) + var.shape[1:], dtype)
            returnbuffer = True

        # Check that the buffer length is correct. For 1D buffer, reshape
        # it if possible, assuming array of structure ordering
        if not buff.shape[0] == self._buffer_len:
            if buff.ndim == 1 and len(buff) % self._buffer_len == 0:
                buff = buff.reshape(self._buffer_len,
                                    len(buff) // self._buffer_len)
            else:
                raise ValueError("Buffer provided for " + varname +
                                 " is the wrong length.")

        # Check that shape of buffer is compatible with shape of variable.
        # If variable does not yet exist, add it here
        if var is None:
            if dtype is None:
                if not scale:
                    dtype = buff.dtype
                else:
                    dtype = np.dtype('float' + str(buff.dtype.itemsize * 8))
            var = self.__add_var(varname, dtype,
                                 (self._block_width, ) + buff.shape[1:])
        elif var.shape[1:] != buff.shape[1:]:
            raise ValueError("Provided buffer has shape " + str(buff.shape) +
                             " which is not compatible with " + str(varname) +
                             " shape " + str(var.shape))

        varname = re.search('(\w+)', varname).group(0)
        if input:
            self.__input_buffers[varname] = (buff, var, scale)
            self.__print(
                2, 'Binding input buffer of shape ' + str(buff.shape) +
                ' and type ' + str(buff.dtype) + ' to variable ' + varname +
                ' with shape ' + str(var.shape) + ' and type ' +
                str(var.dtype))
        else:
            self.__output_buffers[varname] = (buff, var, scale)
            self.__print(
                2, 'Binding output buffer of shape ' + str(buff.shape) +
                ' and type ' + str(buff.dtype) + ' to variable ' + varname +
                ' with shape ' + str(var.shape) + ' and type ' +
                str(var.dtype))

        if returnbuffer: return buff
Beispiel #33
0
def length_label(meters):
    convert = unitmap[parser.args.unit]
    value = units.convert(meters, units.length.m, convert)
    return "%i %s" % (value, convert.label)