Exemple #1
0
    def __iadd__(self, other):
        if type(other) == str:
            other = Units(other)

        if self != other:
            fatalError("Can't add units '%s' and '%s'." % (self, other))
        return self
Exemple #2
0
    def get_variable(self, variable, data_index=None):
        """
        get_variable() [public]
        Purpose:    Returns a masked data array for a variable in the file.
        Parameters: variable [type=string,tuple,list]
                        NetCDF variable to return.  Could be multiple variables in a list.
                    data_index [type=tuple,np.array]
                        Either a tuple of slice objects (created by slice()) or a numpy array of indexes that specify which data
                        to return
        Returns:    A numpy masked array containing the variable's data.
        """
        if type(variable) in [list, tuple]:
            var_data = []
            for var in variable:
                try:
                    if data_index is None:
                        var_data.append(self._df.variables[var][:])
                    else:
                        var_data.append(self._df.variables[var][data_index])
                except KeyError:
                    fatalError("DataIO: File '%s' does not contain a variable '%s'." % (self._file_name, var))
        else:
            try:
            # Assign the data to a variable to play with later ...
                if data_index is None:
                    var_data = self._df.variables[variable][:]
                else:
                    if reader.__name__ == "Nio":
                        var_data = self._df.variables[variable].get_value()[data_index]
                    else:
                        var_data = self._df.variables[variable][data_index]
            except KeyError:
                fatalError("DataIO: File '%s' does not contain a variable '%s'." % (self._file_name, variable))

        if reader.__name__ == "Nio":
            # If we're using PyNIO, it already returns a masked array, so just 
            #    return the data we already have.
            return var_data
        elif reader.__name__ in ["scipy.io.netcdf","Dataset"]:
            # If we're using scipy, we have to mask the data ourselves ...
            if type(variable) in [list, tuple]:
                var_data_masked = []
                for idx in xrange(len(var_data)):
                    try:
                        missing_value = self.get_variable_attribute(variable[idx], 'missing_value', force_exception=True)
                        mask = (var_data[idx] == missing_value) 
                    except ValueError:
                        mask = np.zeros(var_data[idx].shape)
                    var_data_masked.append(np.ma.array(var_data[idx], mask=mask))
            else:
                try:
                    missing_value = self.get_variable_attribute(variable, 'missing_value', force_exception=True)
                    mask = (var_data == missing_value) 
                except ValueError:
                    mask = np.zeros(var_data.shape)

                var_data_masked = np.ma.array(var_data, mask=mask)
            return var_data_masked
Exemple #3
0
def lookup(node):
    """lookup : AST node -> Environment"""
    try:
        return _environments[node]
    except KeyError:
        try:
            nname = node.scopedName()
        except:
            nname = repr(node)

        util.fatalError("Failed to find environment corresponding to node (%s)"
                        % nname)
Exemple #4
0
    def __isub__(self, other):
        if type(other) == str:
            other = Units(other)

        if self != other and not (len(other) == 1 and other._units[0]['unt'] in ['DK', 'DC', 'DF']):
            fatalError("Can't subtract units '%s' and '%s'." % (self, other))

        if len(other) == 1 and other._units[0]['unt'] in ['K', 'C', 'F']:
            self._units[0]['unt'] = "D%s" % self._units[0]['unt']
        elif len(other) == 1 and other._units[0]['unt'] in ['DK', 'DC', 'DF']:
            self._units[0]['unt'] = self._units[0]['unt'][-1]

        return self
Exemple #5
0
    def __sub__(self, other):
        if type(other) == str:
            other = Units(other)

        if self != other and not (len(other) == 1 and other._units[0]['unt'] in ['DK', 'DC', 'DF']):
            fatalError("Can't subtract units '%s' and '%s'." % (self, other))
        result = copy(self)

        if len(result) == 1 and result._units[0]['unt'] in ['K', 'C', 'F']:
            result._units[0]['unt'] = "D%s" % result._units[0]['unt']
        elif len(other) == 1 and other._units[0]['unt'] in ['DK', 'DC', 'DF']:
            result._units[0]['unt'] = result._units[0]['unt'][-1]

        return result
Exemple #6
0
 def get_file_attribute(self, attribute):
     """
     get_file_attribute() [public]
     Purpose:    Returns an attribute of the NetCDF file.
     Parameters:    attribute [type=string]
                     The attribute to return
     Returns:    A string containing the attribute in the file.
     """
     try:
         if reader.__name__ == "Dataset":
             return getattr(self._df, attribute)
         else:    
             return self._df.attributes[attribute]
     except KeyError:
         fatalError("DataIO: File '%s' does not contain a variable '%s'." % (self._file_name, attribute))
Exemple #7
0
    def convert(klass, value, units_from, units_to, force_exception=False):
        """
        convert() [public, static]
        Purpose:    Convert a value from one unit to another
        Parameters: value [type=int,float,np.array]
                        The value or array of values to convert
                    units_from [type=string]
                        The units of the incoming value(s)
                    units_to [type=string]
                        The units to which to convert the value(s)
        Returns:    The value in the new unit system.
        """
        if type(units_from) == str:
            units_from = Units(units_from)

        if type(units_to) == str:
            units_to = Units(units_to)

        if len(units_from) != len(units_to):
            fatalError("Cannot convert between units '%s' and '%s' (units are of different lengths)." % (units_from, units_to))

        for idx in xrange(len(units_from)):
            u_from = units_from[idx]
            u_to = units_to[idx]

            if u_from['unt'] != u_to['unt']:
                # Only attempt converting the base unit if they're different
                for idx in xrange(abs(u_from['exp'])):
                    # Do the conversion as many times as the exponent (e.g. m^2 to ft^2, need to multiply by 3.281 twice)
                    try:
                        # If the exponent is greater than 0, convert from the old to the new, otherwise, do the inverse.
                        if u_from['exp'] > 0: value = Units._imperial_conversions[u_from['unt']][u_to['unt']](value)
                        else:                 value = Units._imperial_conversions[u_to['unt']][u_from['unt']](value)
                    except KeyError:
                        # The from and to units are not in the same section of the nested dictionary, so we're trying to do something like convert
                        #   m to s or something like that.  Error.
                        if not force_exception:
                            fatalError("Cannot convert units from '%s' to '%s'." % (units_from, units_to))
                        else:
                            raise ValueError("Cannot convert units from '%s' to '%s'" % (units_from, units_to))
            # Now that we know the value is in the same unit system, do any metric prefix conversions.
            value = value * (Units._metric_prefixes[u_from['pre']] / Units._metric_prefixes[u_to['pre']]) ** u_from['exp']

        return value
Exemple #8
0
    def evaluateFunction(klass, function):
        """
        evaluateFunction()
        Purpose:    Take a combination of unit strings joined by mathematical operators (a "unit function") and, if possible, collapse it into a single unit string.
        Parameters: function [type=str]
                        The unit function string to evaluate.
        Returns:    The unit string that results from the evaluation of the function.
        """
        parenthesis_re = re.compile(r"\(([^\(\)]+)\)")

        wrap = False
        if function.find(",") > -1:
            wrap = True

        while True:
            sub_functions = parenthesis_re.findall(function)

            if sub_functions == []:
                break

            for sub_func in sub_functions:
                vec_units = re.split(r"\,[\s]+", sub_func)
                eval_sub_func = sub_func
                for vec in vec_units:
                    eval_vec = Units._evaluateSubFunction(vec)
                    eval_sub_func = eval_sub_func.replace(vec, eval_vec)
                function = function.replace("(%s)" % sub_func, eval_sub_func)

        if wrap:
            func_parts = re.split(r"\,[\s]+", function)
            all_equal = True
            for idx in xrange(len(func_parts) - 1):
                for jdy in xrange(idx + 1, len(func_parts)):
                    all_equal &= func_parts[idx] == func_parts[jdy]

            if not all_equal:
                fatalError("Vector components do not have equal units.")

            function = func_parts[0]
        else:
            function = Units._evaluateSubFunction(function)

        return function
Exemple #9
0
    def __init__(self, string):
        """
        __init__()
        Purpose:    Constuctor for the Units class (parses unit strings and stores them internally as a list of dictionaries).
        Parameters: string [type=str]
                        Units string to parse and store.
        """
        self._scalar = 1
        bit_re = re.compile("^(%s)?(%s)([\\d\\-]+)?$" % ("|".join(Units._metric_prefixes), "|".join(["|".join(Units._metric_units), "|".join(Units._imperial_units)])))
        unit_bits = re.split("[\\s]+", string)
        self._units = []


        if string == "":
            self._units.append({'pre':"", 'unt':"", 'exp':1})
        else:
            for bit in unit_bits:
                if bit in Units._replacements:
                    replacement = Units(Units._replacements[bit])
                    self._units.extend(replacement._units)
                else:
                    try:
                        self._scalar = float(bit)
                        continue
                    except ValueError:
                        try:
                            self._scalar = int(bit)
                            continue
                        except ValueError:
                            pass

                    match = bit_re.search(bit)
                    try:
                        prefix, unit, exponent = match.groups(default="")
                    except AttributeError:
                        fatalError("Bit '%s' in unit string '%s' could not be parsed." % (bit, string))
            
                    self._units.append({'pre':prefix, 'unt':unit, 'exp':int(exponent) if exponent != "" else 1})
        return
    def set(self, **kwargs):
        """
        set() [public]
        Purpose:    Sets station plot variables (such as temperature, dewpoint, etc.)
        Parameters:    Key-value pairs (station variable to value, e.g. tmpf=50.
        Returns:    [nothing]
        """

        re_value_string = re.compile("^(\\-?[\\d]+\\.?[\\d]*)[\\s]*([\\w\\d\\- ]+)$")

        for attr, value in kwargs.iteritems():
            if attr in self._valid_attrs:
                re_value_match = re_value_string.match(value)
                if re_value_match is not None:
                    obs_value, obs_units = re_value_match.groups()
                    obs_value = Units.convert(float(obs_value), obs_units, HootPyStationPlot._internal_units[attr])
                    setattr(self, "_%s" % attr, obs_value)
                else:
                    setattr(self, "_%s" % attr, value)
            else:
                fatalError("Attribute %s is not a valid attribute for this type of station plot." % attr)
        return
Exemple #11
0
 def get_variable_attribute(self, variable, attribute, force_exception=False):
     """
     get_variable_attribute() [public]
     Purpose:    Returns an attribute of a variable in the NetCDF file.
     Parameters:    variable [type=string]
                     The NetCDF variable to find an attribute from.
                 attribute [type=string]
                     The attribute to return.
                 force_exception [type=boolean]
                     Force the function to raise an exception on error, instead of just exiting.
     Returns:    A string containing the attribute of the NetCDF variable.
     """
     try:
         return getattr(self._df.variables[variable], attribute)
     except AttributeError:
         if force_exception:
             raise ValueError("DataIO: Variable '%s' in file '%s' does not have an attribute '%s'." % (variable, self._file_name, attribute))
         else:
             fatalError("DataIO: Variable '%s' in file '%s' does not have an attribute '%s'." % (variable, self._file_name, attribute))
     except KeyError:
         if force_exception:
             raise ValueError("DataIO: Variable '%s' in file '%s' does not have an attribute '%s'." % (variable, self._file_name, attribute))
         else:
             fatalError("DataIO: File '%s' does not contain a variable '%s'." % (self._file_name, variable))
Exemple #12
0
 def _cache(self, node):
     if _environments.has_key(node):
         util.fatalError("Unexpected inconsistency: encountered node " +\
                          "more than once while walking the tree")
     _environments[node] = self._env
Exemple #13
0
    # Look for PyNIO ...
    import Nio as reader
    print "Using PyNIO as data reader."
except ImportError:
    # PyNIO is not installed, so ...
    try:
        from netCDF4 import Dataset as reader
        warning("Using netCDF4-python as data reader.  NetCDF format supported only.")
    except ImportError:
        try:
            # Look for scipy's NetCDF reader ...
            import scipy.io.netcdf as reader
            warning("Using scipy.io as data reader.  NetCDF format supported only.")
        except ImportError:
            # scipy's NetCDF reader isn't installed either.  Uhoh ...
            fatalError("No scientific data reader found.  Exiting ...")

class DataIO:
    """
    DataIO
    Purpose:    Handles the reading and writing of data for HootPy using whichever reader is installed
    Started:    30 September 2010 by Tim Supinie (tsupinie#@ou.edu)
    Completed:    [not yet]
    Modified:    [not yet]
    """

    # Probably about time to write down a running list of quirks I've noticed with scipy's netcdf reader:
    # 1.    Can't have an attribute be an empty string (nc.variables['stuff'].stuff = "" will fail on file close)
    # 2.    Doesn't have a "read and write" mode, so if you want to do any sort of reading, you must open the file in read mode, close it, then open it in write mode.

    def __init__(self, file_name=None, mode=None):