From 4ddb2a1da1d8e9b60bbf92faa3acf24f764da12a Mon Sep 17 00:00:00 2001 From: Kevin Paul Date: Wed, 30 Aug 2017 17:46:30 -0600 Subject: [PATCH] Adding updated documentation --- docs/.doctrees/dataflow.doctree | Bin 20648 -> 21419 bytes docs/.doctrees/datasets.doctree | Bin 85290 -> 87718 bytes docs/.doctrees/environment.pickle | Bin 184774 -> 205981 bytes docs/.doctrees/flownodes.doctree | Bin 54378 -> 61490 bytes docs/.doctrees/functions.doctree | Bin 79062 -> 79632 bytes docs/.doctrees/physarray.doctree | Bin 44090 -> 64643 bytes docs/_modules/pyconform/dataflow.html | 285 ++++++----- docs/_modules/pyconform/datasets.html | 91 ++-- docs/_modules/pyconform/flownodes.html | 154 +++++- docs/_modules/pyconform/functions.html | 60 ++- docs/_modules/pyconform/physarray.html | 232 ++++++++- docs/datasets.html | 21 +- docs/flownodes.html | 30 +- docs/functions.html | 2 +- docs/genindex.html | 74 ++- docs/objects.inv | Bin 1397 -> 1478 bytes docs/physarray.html | 67 +++ docs/searchindex.js | 2 +- docs/sphinx/manual.rst | 666 ------------------------- 19 files changed, 793 insertions(+), 891 deletions(-) diff --git a/docs/.doctrees/dataflow.doctree b/docs/.doctrees/dataflow.doctree index fc79289041d48cc1f4a4348127dbf963a2da4999..ed2bd0d3f4602e3b084cdccd60e520c8df7cc6d0 100644 GIT binary patch literal 21419 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 VY80(NcgcJNFTQyg&%w^N{|B4?@X!DN literal 85290 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 AJ^%m! diff --git a/docs/.doctrees/environment.pickle b/docs/.doctrees/environment.pickle index 5b1c485495cbc4803489a0a36215382522a4f5d2..0783f4329702ebf8333e05e08896b289e9052eb8 100644 GIT binary patch delta 45950 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 F_%Gre>>mIC delta 32173 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 diff --git a/docs/.doctrees/flownodes.doctree b/docs/.doctrees/flownodes.doctree index 19eef6516bf2121f6ddf70ca5af5082014c23e04..e98360485cd05a4043134fac956e528b367f9826 100644 GIT binary patch literal 61490 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 literal 54378 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 KAIHuqWB(txPQVfX diff --git a/docs/.doctrees/physarray.doctree b/docs/.doctrees/physarray.doctree index d76fa785a93efa35a6dd84ae022ee03fb7d12569..3b96da202cbd41e03a9953086b15c9a01add0bf7 100644 GIT binary patch literal 64643 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 Hzw3VhK%((} diff --git a/docs/_modules/pyconform/dataflow.html b/docs/_modules/pyconform/dataflow.html index 40aff383..75ab2915 100644 --- a/docs/_modules/pyconform/dataflow.html +++ b/docs/_modules/pyconform/dataflow.html @@ -183,7 +183,7 @@

Source code for pyconform.dataflow

 from pyconform.parsing import ParsedVariable, ParsedFunction, ParsedUniOp, ParsedBinOp
 from pyconform.functions import find_operator, find_function
 from pyconform.physarray import PhysArray
-from pyconform.flownodes import FlowNode, DataNode, ReadNode, EvalNode
+from pyconform.flownodes import DataNode, ReadNode, EvalNode, iter_dfs
 from pyconform.flownodes import MapNode, ValidateNode, WriteNode
 from asaptools.simplecomm import create_comm, SimpleComm
 from asaptools.partition import WeightBalanced
@@ -227,159 +227,216 @@ 

Source code for pyconform.dataflow

             raise TypeError('Output dataset must be of OutputDatasetDesc type')
         self._ods = outds
 
-        # Separate output variables into variables with data or string 'definitions'
-        datvars = {}
-        defvars = {}
-        for vname, vdesc in self._ods.variables.iteritems():
+        # Create a dictionary of DataNodes from variables with non-string definitions
+        datnodes = self._create_data_nodes_()
+
+        # Create a dictionary to store FlowNodes for variables with string definitions
+        defnodes = self._create_definition_nodes_(datnodes)
+
+        # Compute the definition node info objects (zero-sized physarrays)
+        definfos = self._compute_node_infos_(defnodes)
+        
+        # Construct the dimension map
+        self._i2omap, self._o2imap = self._compute_dimension_maps_(definfos)
+        
+        # Create the map nodes
+        defnodes = self._create_map_nodes_(defnodes, definfos)
+
+        # Create the validate nodes for each valid output variable
+        valnodes = self._create_validate_nodes_(datnodes, defnodes)
+        
+        # Get the set of all sum-like dimensions (dimensions that cannot be broken into chunks)
+        self._sumlike_dimensions = self._find_sumlike_dimensions_(valnodes)
+
+        # Create the WriteNodes for each time-series output file
+        self._writenodes = self._create_write_nodes_(valnodes)
+
+        # Compute the bytesizes of each output variable
+        varsizes = self._compute_variable_sizes_(valnodes)
+
+        # Compute the file sizes for each output file
+        self._filesizes = self._compute_file_sizes(varsizes)
+
+    def _create_data_nodes_(self):
+        datnodes = {}
+        for vname in self._ods.variables:
+            vdesc = self._ods.variables[vname]
+            if not isinstance(vdesc.definition, basestring):
+                if vdesc.datatype == 'char':
+                    vdata = numpy.asarray(vdesc.definition, dtype='S')
+                else:
+                    vdata = numpy.asarray(vdesc.definition, dtype=vdesc.dtype)
+                vunits = vdesc.cfunits()
+                vdims = vdesc.dimensions.keys()
+                varray = PhysArray(vdata, name=vname, units=vunits, dimensions=vdims)
+                datnodes[vname] = DataNode(varray)
+        return datnodes
+
+    def _create_definition_nodes_(self, datnodes):        
+        defnodes = {}
+        for vname in self._ods.variables:
+            vdesc = self._ods.variables[vname]
             if isinstance(vdesc.definition, basestring):
-                defvars[vname] = vdesc
-            else:
-                datvars[vname] = vdesc
-
-        # Create a dictionary to store DataNodes from variables with data 'definitions'
-        self._datnodes = {}
-        for vname, vdesc in datvars.iteritems():
-            vdata = numpy.array(vdesc.definition, dtype=vdesc.datatype)
-            vunits = vdesc.cfunits()
-            vdims = vdesc.dimensions.keys()
-            varray = PhysArray(vdata, name=vname, units=vunits, dimensions=vdims)
-            self._datnodes[vname] = DataNode(varray)
-
-        # Create a dictionary to store FlowNodes for variables with string 'definitions'
-        self._defnodes = {}
-        for vname, vdesc in defvars.iteritems():
-            try:
-                vnode = self._construct_flow_(parse_definition(vdesc.definition))
-            except VariableNotFoundError, err:
-                warn('{}. Skipping output variable {}.'.format(str(err), vname), DefinitionWarning)
+                try:
+                    vnode = self._construct_flow_(parse_definition(vdesc.definition), datnodes=datnodes)
+                except VariableNotFoundError, err:
+                    warn('{}. Skipping output variable {}.'.format(str(err), vname), DefinitionWarning)
+                else:
+                    defnodes[vname] = vnode
+        return defnodes      
+
+    def _construct_flow_(self, obj, datnodes={}):
+        if isinstance(obj, ParsedVariable):
+            vname = obj.key
+            if vname in self._ids.variables:
+                return ReadNode(self._ids.variables[vname], index=obj.args)
+
+            elif vname in datnodes:
+                return datnodes[vname]
+
             else:
-                self._defnodes[vname] = vnode                
+                raise VariableNotFoundError('Input variable {!r} not found or cannot be used as input'.format(vname))
 
-        # Gather information about each FlowNode's metadata (via empty PhysArrays)
-        definfos = dict((vname, vnode[None]) for vname, vnode in self._defnodes.iteritems())
+        elif isinstance(obj, (ParsedUniOp, ParsedBinOp)):
+            name = obj.key
+            nargs = len(obj.args)
+            op = find_operator(name, numargs=nargs)
+            args = [self._construct_flow_(arg, datnodes=datnodes) for arg in obj.args]
+            return EvalNode(name, op, *args)
+
+        elif isinstance(obj, ParsedFunction):
+            name = obj.key
+            func = find_function(name)
+            args = [self._construct_flow_(arg, datnodes=datnodes) for arg in obj.args]
+            kwds = {k:self._construct_flow_(obj.kwds[k], datnodes=datnodes) for k in obj.kwds}
+            return EvalNode(name, func, *args, **kwds)
 
+        else:
+            return obj
+
+    def _compute_node_infos_(self, nodes):
+        # Gather information about each FlowNode's metadata (via empty PhysArrays)
+        infos = {}
+        for name in nodes:
+            node = nodes[name] 
+            try:
+                info = node[None]
+            except Exception, err:
+                ndef = self._ods.variables[name].definition
+                err_msg = 'Failure in variable {!r} with definition {!r}: {}'.format(name, ndef, str(err))
+                raise RuntimeError(err_msg)
+            else:
+                infos[name] = info
+        return infos
+        
+    def _compute_dimension_maps_(self, definfos):
         # Each output variable FlowNode must be mapped to its output dimensions.
         # To aid with this, we sort by number of dimensions:
-        nodeorder = zip(*sorted((len(self._ods.variables[vname].dimensions), vname)
-                                for vname in self._defnodes))[1]
+        nodeorder = zip(*sorted((len(self._ods.variables[vname].dimensions), vname) for vname in definfos))[1]
 
         # Now, we construct the dimension maps
-        self._i2omap = {}
-        self._o2imap = {}
+        i2omap = {}
+        o2imap = {}
         for vname in nodeorder:
             out_dims = self._ods.variables[vname].dimensions.keys()
             inp_dims = definfos[vname].dimensions
 
-            unmapped_out = tuple(d for d in out_dims if d not in self._o2imap)
-            mapped_inp = tuple(self._o2imap[d] for d in out_dims if d in self._o2imap)
+            unmapped_out = tuple(d for d in out_dims if d not in o2imap)
+            mapped_inp = tuple(o2imap[d] for d in out_dims if d in o2imap)
             unmapped_inp = tuple(d for d in inp_dims if d not in mapped_inp)
 
             if len(unmapped_out) != len(unmapped_inp):
-                map_str = ', '.join('{}-->{}'.format(k,self._i2omap[k]) for k in self._i2omap)
+                map_str = ', '.join('{}-->{}'.format(k, i2omap[k]) for k in i2omap)
                 err_msg = ('Cannot map dimensions {} to dimensions {} in output variable {} '
                            '(MAP: {})').format(inp_dims, out_dims, vname, map_str)
                 raise ValueError(err_msg)
             if len(unmapped_out) == 0:
                 continue
             for out_dim, inp_dim in zip(unmapped_out, unmapped_inp):
-                self._o2imap[out_dim] = inp_dim
-                self._i2omap[inp_dim] = out_dim
+                o2imap[out_dim] = inp_dim
+                i2omap[inp_dim] = out_dim
 
         # Now that we know how dimensions are mapped, compute the output dimension sizes
         for dname, ddesc in self._ods.dimensions.iteritems():
-            if not ddesc.is_set():
-                ddesc.set(self._ids.dimensions[self._o2imap[dname]])
+            if dname in o2imap:
+                idd = self._ids.dimensions[o2imap[dname]]
+                if (ddesc.is_set() and ddesc.stringlen and ddesc.size < idd.size) or not ddesc.is_set():
+                    ddesc.set(idd)
+        
+        return i2omap, o2imap
+
+    @property
+    def dimension_map(self):
+        """The internally generated input-to-output dimension name map"""
+        return self._i2omap
 
-        # Append a MapNode to all string-defined nodes (map dimension names)
-        for vname in self._defnodes:
-            dnode = self._defnodes[vname]
+    def _create_map_nodes_(self, defnodes, definfos):
+        mapnodes = {}
+        for vname in defnodes:
+            dnode = defnodes[vname]
             dinfo = definfos[vname]
             map_dims = tuple(self._i2omap[d] for d in dinfo.dimensions)
             name = 'map({!s}, to={})'.format(vname, map_dims)
-            self._defnodes[vname] = MapNode(name, dnode, self._i2omap)
-
-        # Now loop through ALL of the variables and create ValidateNodes for validation
-        self._varnodes = {}
-        for vname, vdesc in self._ods.variables.iteritems():
-            if vname in self._datnodes:
-                vnode = self._datnodes[vname]
-            elif vname in self._defnodes:
-                vnode = self._defnodes[vname]
-
-            self._varnodes[vname] = ValidateNode(vname, vnode, units=vdesc.cfunits(),
-                                                 dimensions=vdesc.dimensions.keys(),
-                                                 attributes=vdesc.attributes,
-                                                 dtype=vdesc.datatype)
-        
-        # Now, for each ValidateNode, get the set of all sum-like dimensions
-        # (these are dimensions that cannot be broken into chunks)
+            mapnodes[vname] = MapNode(name, dnode, self._i2omap)
+        return mapnodes
+
+    def _create_validate_nodes_(self, datnodes, defnodes):
+        valid_vars = datnodes.keys() + defnodes.keys()          
+        valnodes = {}
+        for vname in valid_vars:
+            vdesc = self._ods.variables[vname]
+            vnode = datnodes[vname] if vname in datnodes else defnodes[vname]
+
+            try:
+                validnode = ValidateNode(vname, vnode, dimensions=vdesc.dimensions.keys(),
+                                         attributes=vdesc.attributes, dtype=vdesc.dtype)
+            except Exception, err:
+                vdef = vdesc.definition
+                err_msg = 'Failure in variable {!r} with definition {!r}: {}'.format(vname, vdef, str(err))
+                raise RuntimeError(err_msg)
+
+            valnodes[vname] = validnode
+        return valnodes
+    
+    def _find_sumlike_dimensions_(self, valnodes):
         unmapped_sumlike_dimensions = set()
-        for vname, vnode in self._varnodes.iteritems():
-            visited = set()
-            tosearch = [vnode]
-            while tosearch:
-                nd = tosearch.pop()
+        for vname in valnodes:
+            vnode = valnodes[vname]
+            for nd in iter_dfs(vnode):
                 if isinstance(nd, EvalNode):
                     unmapped_sumlike_dimensions.update(nd.sumlike_dimensions)
-                visited.add(nd)
-                if isinstance(nd, FlowNode):
-                    tosearch.extend(i for i in nd.inputs if i not in visited)
         
         # Map the sum-like dimensions to output dimensions
-        self._sumlike_dimensions = set(self._i2omap[d] for d in unmapped_sumlike_dimensions if d in self._i2omap)
+        return set(self._i2omap[d] for d in unmapped_sumlike_dimensions if d in self._i2omap)
 
-        # Create the WriteNodes for each time-series output file
+    def _create_write_nodes_(self, valnodes):
         writenodes = {}
-        for fname, fdesc in self._ods.files.iteritems():
-            vnodes = tuple(self._varnodes[n] for n in fdesc.variables.keys())
-            writenodes[fname] = WriteNode(fdesc, inputs=vnodes)
-        self._writenodes = writenodes
+        for fname in self._ods.files:
+            fdesc = self._ods.files[fname]
+            vmissing = tuple(vname for vname in fdesc.variables if vname not in valnodes)
+            if vmissing:
+                warn('Skipping output file {} due to missing required variables: '
+                     '{}'.format(fname, ', '.join(sorted(vmissing))), DefinitionWarning)
+            else:
+                vnodes = tuple(valnodes[vname] for vname in fdesc.variables)
+                wnode = WriteNode(fdesc, inputs=vnodes)
+                writenodes[wnode.label] = wnode
+        return writenodes
 
-        # Compute the bytesizes of each output variable
+    def _compute_variable_sizes_(self, valnodes):
         bytesizes = {}
-        for vname, vdesc in self._ods.variables.iteritems():
+        for vname in valnodes:
+            vdesc = self._ods.variables[vname]
             vsize = sum(ddesc.size for ddesc in vdesc.dimensions.itervalues())
             vsize = 1 if vsize == 0 else vsize
-            bytesizes[vname] = vsize * numpy.dtype(vdesc.datatype).itemsize
-
-        # Compute the file sizes for each output file
-        self._filesizes = {}
+            bytesizes[vname] = vsize * vdesc.dtype.itemsize
+        return bytesizes
+    
+    def _compute_file_sizes(self, varsizes):
+        filesizes = {}
         for fname, wnode in self._writenodes.iteritems():
-            self._filesizes[fname] = sum(bytesizes[vnode.label] for vnode in wnode.inputs)
-        
-    def _construct_flow_(self, obj):
-        if isinstance(obj, ParsedVariable):
-            vname = obj.key
-            if vname in self._ids.variables:
-                return ReadNode(self._ids.variables[vname], index=obj.args)
-
-            elif vname in self._datnodes:
-                return self._datnodes[vname]
-
-            else:
-                raise VariableNotFoundError('Input variable {!r} not found or cannot be used as input'.format(vname))
-
-        elif isinstance(obj, (ParsedUniOp, ParsedBinOp)):
-            name = obj.key
-            nargs = len(obj.args)
-            op = find_operator(name, numargs=nargs)
-            args = [self._construct_flow_(arg) for arg in obj.args]
-            return EvalNode(name, op, *args)
-
-        elif isinstance(obj, ParsedFunction):
-            name = obj.key
-            func = find_function(name)
-            args = [self._construct_flow_(arg) for arg in obj.args]
-            kwds = {k:self._construct_flow_(obj.kwds[k]) for k in obj.kwds}
-            return EvalNode(name, func, *args, **kwds)
-
-        else:
-            return obj
-
-    @property
-    def dimension_map(self):
-        """The internally generated input-to-output dimension name map"""
-        return self._i2omap
+            filesizes[fname] = sum(varsizes[vnode.label] for vnode in wnode.inputs)
+        return filesizes
 
 
[docs] def execute(self, chunks={}, serial=False, history=False, scomm=None, deflate=None): """ diff --git a/docs/_modules/pyconform/datasets.html b/docs/_modules/pyconform/datasets.html index afc03aa4..7fa4a3f8 100644 --- a/docs/_modules/pyconform/datasets.html +++ b/docs/_modules/pyconform/datasets.html @@ -173,10 +173,11 @@

Source code for pyconform.datasets

 from os import linesep
 from os.path import exists
 from collections import OrderedDict
-from numpy import dtype, array
+from numpy import dtype
 from netCDF4 import Dataset as NC4Dataset
 from cf_units import Unit
 from warnings import warn
+from pyconform.physarray import PhysArray
 
 
 #===================================================================================================
@@ -235,7 +236,7 @@ 

Source code for pyconform.datasets

     unlimited.
     """
 
-    def __init__(self, name, size=None, unlimited=False):
+    def __init__(self, name, size=None, unlimited=False, stringlen=False):
         """
         Initializer
         
@@ -243,10 +244,12 @@ 

Source code for pyconform.datasets

             name (str): Dimension name
             size (int): Dimension size
             unlimited (bool): Whether the dimension is unlimited or not
+            stringlen (bool): Whether the dimension represents a string length or not
         """
         self._name = name
         self._size = int(size) if size is not None else None
         self._unlimited = bool(unlimited)
+        self._stringlen = bool(stringlen)
 
     @property
     def name(self):
@@ -263,6 +266,11 @@ 

Source code for pyconform.datasets

         """Boolean indicating whether the dimension is unlimited or not"""
         return self._unlimited
 
+    @property
+    def stringlen(self):
+        """Boolean indicating whether the dimension represents a string length or not"""
+        return self._stringlen
+
 
[docs] def is_set(self): """ Return True if the dimension size and unlimited status is set, False otherwise @@ -347,19 +355,34 @@

Source code for pyconform.datasets

     the data is contained in the variable declaration).
     """
 
-    def __init__(self, name, datatype='float32', dimensions=(), definition=None, attributes={}):
+    # Elemental NetCDF datatypes
+    _NTYPES_ = ('byte', 'ubyte', 'char', 'short', 'ushort', 'int', 'uint',
+                'int64', 'uint64', 'float', 'real', 'double')
+    _DTYPES_ = (dtype('b'), dtype('u1'), dtype('S1'), dtype('i2'), dtype('u2'), dtype('i4'), dtype('u4'),
+                dtype('i8'), dtype('u8'), dtype('f4'), dtype('f4'), dtype('f8'))
+
+    def __init__(self, name, datatype='float', dimensions=(), definition=None, attributes={}):
         """
         Initializer
 
         Parameters:
             name (str): Name of the variable
-            datatype (str): Numpy datatype of the variable data
+            datatype (str): NetCDF datatype or NumPy dtype of the variable data
             dimensions (tuple): Tuple of DimensionDesc objects for the variable
             definition: String or data definition of variable
             attributes (dict): Dictionary of variable attributes
         """
         self._name = name
-        self._datatype = str(dtype(datatype))
+        
+        if isinstance(datatype, basestring) and datatype in VariableDesc._NTYPES_:
+            self._ntype = datatype
+            self._dtype = VariableDesc._DTYPES_[VariableDesc._NTYPES_.index(datatype)]
+        elif isinstance(datatype, dtype) and datatype in VariableDesc._DTYPES_:
+            self._ntype = VariableDesc._NTYPES_[VariableDesc._DTYPES_.index(datatype)]
+            self._dtype = datatype
+        else:
+            raise TypeError('Invalid variable datatype {} for variable {}'.format(datatype, name))
+
         self.definition = definition
 
         if not _is_list_of_type_(dimensions, DimensionDesc):
@@ -382,8 +405,13 @@ 

Source code for pyconform.datasets

     @property
     def datatype(self):
         """String datatype of the variable"""
-        return self._datatype
-
+        return self._ntype
+    
+    @property
+    def dtype(self):
+        """NumPy dtype of the variable data"""
+        return self._dtype
+    
     @property
     def attributes(self):
         """Variable attributes dictionary"""
@@ -431,7 +459,7 @@ 

Source code for pyconform.datasets

 
 
[docs] def units(self): """Retrieve the units attribute, if it exists, otherwise 1""" - return self.attributes.get('units', 1)
+ return self.attributes.get('units', 'no unit')
[docs] def calendar(self): """Retrieve the calendar attribute, if it exists, otherwise None""" @@ -669,7 +697,7 @@

Source code for pyconform.datasets

 
         for fname, fdesc in self._files.iteritems():
             for vdesc in fdesc.variables.itervalues():
-                vdesc.files[fname] = fdesc
+                vdesc.files[fname] = fdesc     
 
     @property
     def name(self):
@@ -729,23 +757,26 @@ 

Source code for pyconform.datasets

                 for aname in ncfile.ncattrs():
                     fattrs[aname] = ncfile.getncattr(aname)
 
-                # Get the file dimensions
-                fdims = OrderedDict()
-                for dname, dobj in ncfile.dimensions.iteritems():
-                    fdims[dname] = DimensionDesc(dname, size=len(dobj), unlimited=dobj.isunlimited())
-
-                # Parse variables
+                # Parse variables and their dimensions
                 fvars = []
+                fdims = OrderedDict()
                 for vname, vobj in ncfile.variables.iteritems():
 
                     vattrs = OrderedDict()
                     for vattr in vobj.ncattrs():
                         vattrs[vattr] = vobj.getncattr(vattr)
 
+                    for dname in vobj.dimensions:
+                        if dname not in fdims:
+                            dobj = ncfile.dimensions[dname]
+                            size = len(dobj)
+                            unlimited = dobj.isunlimited()
+                            slen = True if dname == vobj.dimensions[-1] and vobj.dtype == dtype('S1') else False
+                            fdims[dname] = DimensionDesc(dname, size=size, unlimited=unlimited, stringlen=slen)
+
                     vdims = [fdims[dname] for dname in vobj.dimensions]
 
-                    fvars.append(VariableDesc(vname, datatype='{!s}'.format(vobj.dtype),
-                                              dimensions=vdims, attributes=vattrs))
+                    fvars.append(VariableDesc(vname, datatype=vobj.dtype, dimensions=vdims, attributes=vattrs))
 
                 files.append(FileDesc(fname, format=ffmt, attributes=fattrs, variables=fvars))
 
@@ -783,8 +814,8 @@ 

Source code for pyconform.datasets

             the names of other variables that should be added to the file, in addition to obvious
             metadata variables and the variable containing the 'file' section.
     """
-    _NC_TYPES_ = {3: [dtype(t) for t in ('c', 'i1', 'i2', 'i4', 'f4', 'f8')],
-                  4: [dtype(t) for t in ('c', 'i1', 'u1', 'i2', 'u2', 'i4', 'u4', 'i8', 'u8', 'f4', 'f8')]}
+    _NC_TYPES_ = {3: ['byte', 'char', 'short', 'int', 'float', 'double'],
+                  4: ['byte', 'char', 'short', 'ushort', 'int', 'uint', 'int64', 'uint64', 'float', 'real', 'double']}
     _NC_FORMATS_ = {'NETCDF4': 4, 'NETCDF4_CLASSIC': 3, 'NETCDF3_CLASSIC': 3,
                     'NETCDF3_64BIT_OFFSET': 3, 'NETCDF3_64BIT_DATA': 3, 'NETCDF3_64BIT': 3}
 
@@ -810,24 +841,22 @@ 

Source code for pyconform.datasets

                 vkwds['attributes'] = vdict['attributes']
 
             # Get the datatype of the variable, otherwise defaults to VariableDesc default
-            vkwds['datatype'] = 'float32'
+            vkwds['datatype'] = 'float'
             if 'datatype' in vdict:
                 vkwds['datatype'] = vdict['datatype']
 
-            # Get either the 'definition' or the 'data' of the variables
+            # Get either the 'definition' (string definition or data) of the variables
             def_wrn = ''
             if 'definition' in vdict:
                 vdef = vdict['definition']
                 if isinstance(vdef, basestring):
                     if len(vdef.strip()) > 0:
-                        vkwds['definition'] = vdef
                         vshape = None
                     else:
                         def_wrn = 'Empty definition for output variable {!r} in dataset {!r}.'.format(vname, name)
                 else:
-                    vdat = array(vdef, dtype=vkwds['datatype'])
-                    vshape = vdat.shape
-                    vkwds['definition'] = vdat
+                    vshape = PhysArray(vdef).shape
+                vkwds['definition'] = vdef
             else:
                 def_wrn = 'No definition given for output variable {!r} in dataset {!r}.'.format(vname, name)
             
@@ -837,11 +866,12 @@ 

Source code for pyconform.datasets

 
             # Get the dimensions of the variable (REQUIRED)
             if 'dimensions' in vdict:
+                vdims = vdict['dimensions']
+                sldim = vdims[-1] if vkwds['datatype'] == 'char' else None
                 if vshape is None:
-                    vkwds['dimensions'] = tuple(DimensionDesc(d) for d in vdict['dimensions'])
+                    vkwds['dimensions'] = tuple(DimensionDesc(d, stringlen=(sldim==d)) for d in vdims)
                 else:
-                    vkwds['dimensions'] = tuple(DimensionDesc(d, s) for d, s in
-                                                zip(vdict['dimensions'], vshape))
+                    vkwds['dimensions'] = tuple(DimensionDesc(d, size=s, stringlen=(sldim==d)) for d, s in zip(vdims, vshape))
             else:
                 err_msg = 'Dimensions are required for variable {!r} in dataset {!r}'.format(vname, name)
                 raise ValueError(err_msg)
@@ -884,6 +914,7 @@ 

Source code for pyconform.datasets

             else:
                 metavars.append(vname)
 
+        # Loop through all character type variables and get the 
         # Loop through all found files and create the file descriptors
         filedescs = []
         for fname, fdict in files.iteritems():
@@ -958,14 +989,14 @@ 

Source code for pyconform.datasets

         Check if a given type is valid for the given file format
         
         Parameters:
-            t (str, dtype): The string-type or dtype to check
+            t (str): The string-type to check
             f (str): The file format of the file in whi
         """
         if f in OutputDatasetDesc._NC_FORMATS_:
             NC_VER = OutputDatasetDesc._NC_FORMATS_[f]
         else:
             raise ValueError('Unrecognized NetCDF file format {!r}'.format(f))
-        if dtype(t) not in OutputDatasetDesc._NC_TYPES_[NC_VER]:
+        if t not in OutputDatasetDesc._NC_TYPES_[NC_VER]:
             raise ValueError('Data type {!r} unrecognized in NetCDF file format {!r}'.format(t, f))
diff --git a/docs/_modules/pyconform/flownodes.html b/docs/_modules/pyconform/flownodes.html index 1eab937a..e67288b7 100644 --- a/docs/_modules/pyconform/flownodes.html +++ b/docs/_modules/pyconform/flownodes.html @@ -170,10 +170,11 @@

Source code for pyconform.flownodes

 """
 
 from pyconform.indexing import index_str, join, align_index, index_tuple
-from pyconform.physarray import PhysArray
+from pyconform.physarray import PhysArray, CharArray
 from pyconform.datasets import VariableDesc, FileDesc
 from pyconform.functions import Function
-from cf_units import Unit
+from cf_units import Unit, num2date
+from datetime import datetime
 from os.path import exists, dirname
 from os import makedirs
 from netCDF4 import Dataset
@@ -189,12 +190,60 @@ 

Source code for pyconform.flownodes

 
[docs]class ValidationWarning(Warning): """Warning for validation errors"""
+ #=================================================================================================== # UnitsWarning #===================================================================================================
[docs]class UnitsWarning(Warning): """Warning for units errors"""
+ +#======================================================================================================================= +# iter_dfs - Depth-First Search Iterator +#======================================================================================================================= +
[docs]def iter_dfs(node): + """ + Iterate through graph of FlowNodes from a starting node using a Depth-First Search + + Parameters: + node (FlowNode): the starting node from where to begin iterating + """ + if not isinstance(node, FlowNode): + raise TypeError('Can only iterate over FlowNodes') + + visited = set() + tosearch = [node] + while tosearch: + nd = tosearch.pop() + visited.add(nd) + if isinstance(nd, FlowNode): + tosearch.extend(i for i in nd.inputs if i not in visited) + yield nd
+ + +#======================================================================================================================= +# iter_bfs - Breadth-First Search Iterator +#======================================================================================================================= +
[docs]def iter_bfs(node): + """ + Iterate through graph of FlowNodes from a starting node using a Breadth-First Search + + Parameters: + node (FlowNode): the starting node from where to begin iterating + """ + if not isinstance(node, FlowNode): + raise TypeError('Can only iterate over FlowNodes') + + visited = set() + tosearch = [node] + while tosearch: + nd = tosearch.pop(0) + visited.add(nd) + if isinstance(nd, FlowNode): + tosearch.extend(i for i in nd.inputs if i not in visited) + yield nd
+ + #=================================================================================================== # FlowNode #=================================================================================================== @@ -305,8 +354,7 @@

Source code for pyconform.flownodes

         # Check that the variable exists in the file
         with Dataset(self._filepath, 'r') as ncfile:
             if variable.name not in ncfile.variables:
-                raise OSError('Variable {!r} not found in NetCDF file: '
-                              '{!r}'.format(variable.name, self._filepath))
+                raise OSError('Variable {!r} not found in NetCDF file: {!r}'.format(variable.name, self._filepath))
         self._variable = variable.name
 
         # Check if the index means "all"
@@ -374,7 +422,7 @@ 

Source code for pyconform.flownodes

             index12 = join(shape0, index1, index2)
 
             # Retrieve the data from file, unpacking if necessary
-            if 'scale_factor' in attrs or 'add_offset' in attrs:
+            if 'scale_factor' in attrs or 'add_offset' in attrs and not ncvar.scale:
                 scale_factor = attrs.get('scale_factor', 1)
                 add_offset = attrs.get('add_offset', 0)
                 data = scale_factor * ncvar[index12] + add_offset
@@ -547,14 +595,13 @@ 

Source code for pyconform.flownodes

     This is a "non-source"/"non-sink" FlowNode.
     """
 
-    def __init__(self, label, dnode, units=None, dimensions=None, dtype=None, attributes={}):
+    def __init__(self, label, dnode, dimensions=None, dtype=None, attributes={}):
         """
         Initializer
         
         Parameters:
             label: The label associated with this FlowNode
             dnode (FlowNode): FlowNode that provides input into this FlowNode
-            units (Unit): CF units to validate against
             dimensions (tuple): The output dimensions to validate against
             dtype (dtype): The NumPy dtype of the data to return
             attributes (dict): Attributes to associate with the new variable
@@ -577,11 +624,6 @@ 

Source code for pyconform.flownodes

             else:
                 raise TypeError('Dimensions must be a list or tuple')
 
-        # Check for units
-        if units is not None and not isinstance(units, Unit):
-            raise TypeError('Units must be a Unit object')
-        self._units = units
-
         # Store the attributes given to the FlowNode
         self._attributes = OrderedDict((k, v) for k, v in attributes.iteritems())
         
@@ -624,11 +666,20 @@ 

Source code for pyconform.flownodes

                             '{!r}').format(indata.dtype, odtype, self.label)
 
         # Check that units match as expected
-        if self._units is not None and self._units != indata.units:
-            if index is None:
-                indata.units = self._units
-            else:
-                indata = indata.convert(self._units)
+        if 'units' in self.attributes:
+            if indata.units.is_time_reference():
+                if 'calendar' not in self.attributes:
+                    self.attributes['calendar'] = indata.units.calendar
+            ounits = Unit(self.attributes['units'], calendar=self.attributes.get('calendar', None))
+            if ounits != indata.units:
+                if index is None:
+                    indata.units = ounits
+                else:
+                    try:
+                        indata = indata.convert(ounits)
+                    except Exception as err:
+                        err_msg = 'When validating output variable {}: {}'.format(self.label, err)
+                        raise err.__class__(err_msg)
 
         # Check that the dimensions match as expected
         if self.dimensions is not None and self.dimensions != indata.dimensions:
@@ -735,6 +786,11 @@ 

Source code for pyconform.flownodes

                 raise ValueError(('WriteNode {!r} takes input from variable {!r} that is not '
                                   'contained in the descibed file').format(filedesc.name, inp.label))
 
+        # Construct the proper filename
+        fname = self._autoparse_filename_(self.label)
+        self._label = fname
+        self._filedesc._name = fname
+        
         # Set the filehandle
         self._file = None
 
@@ -744,6 +800,51 @@ 

Source code for pyconform.flownodes

         # Initialize set of unwritten attributes
         self._unwritten_attributes = {'_FillValue', 'direction', 'history'}
     
+    def _autoparse_filename_(self, fname):
+        """
+        Determine if autoparsing the filename needs to be done
+        
+        Parameters:
+            fname (str): The original name of the file
+            
+        Returns:
+            str: The new name for the file
+        """
+        
+        if '{' in fname:
+            
+            possible_tvars = []
+            for var in self._filedesc.variables:
+                vobj = self._filedesc.variables[var]
+                if vobj.cfunits().is_time_reference() and len(vobj.dimensions) == 1:
+                    possible_tvars.append(var)
+            if len(possible_tvars) == 0:
+                raise ValueError('Could not find time variable in file {!r}'.format(fname))
+            tvar = 'time' if 'time' in possible_tvars else possible_tvars[0]
+
+            tnodes = [vnode for vnode in self.inputs if vnode.label == tvar]
+            if len(tnodes) == 0:
+                raise ValueError('Time variable input missing in file {!r}'.format(fname))
+            tnode = tnodes[0]
+            t1 = tnode[0:1]
+            t2 = tnode[-1:]
+
+            while '{' in fname:
+                beg = fname.find('{')
+                end = fname.find('}', beg)
+                if end == -1:
+                    raise ValueError('Filename {!r} has unbalanced special characters'.format(fname))
+                prefix = fname[:beg]
+                fmtstr1, fmtstr2 = fname[beg+1:end].split('-')
+                suffix = fname[end+1:]
+
+                datestr1 = num2date(t1.data[0], str(t1.units), t1.units.calendar).strftime(fmtstr1).replace(' ', '0')
+                datestr2 = num2date(t2.data[0], str(t2.units), t2.units.calendar).strftime(fmtstr2).replace(' ', '0')
+                
+                fname = '{}{}-{}{}'.format(prefix, datestr1, datestr2, suffix)
+            
+        return fname  
+              
 
[docs] def enable_history(self): """ Enable writing of the history attribute to the file @@ -771,7 +872,7 @@

Source code for pyconform.flownodes

                     makedirs(fdir)
                 except:
                     raise IOError('Failed to create directory for output file {!r}'.format(fname))
-
+                
             # Try to open the output file for writing
             try:
                 self._file = Dataset(fname, 'w', format=self._filedesc.format)
@@ -779,6 +880,7 @@ 

Source code for pyconform.flownodes

                 raise IOError('Failed to open output file {!r}'.format(fname))
 
             # Write the global attributes
+            self._filedesc.attributes['creation_date'] = datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
             self._file.setncatts(self._filedesc.attributes)
 
             # Scan over variables for coordinates and dimension information
@@ -825,7 +927,7 @@ 

Source code for pyconform.flownodes

                 vdesc = self._filedesc.variables[vname]
                 vattrs = OrderedDict((k, v) for k, v in vnode.attributes.iteritems())
 
-                vdtype = numpy.dtype(vdesc.datatype)
+                vdtype = vdesc.dtype
                 fillval = vattrs.get('_FillValue', None)
                 vdims = vdesc.dimensions.keys()
                 if deflate is None:
@@ -932,8 +1034,13 @@ 

Source code for pyconform.flownodes

         # Create data structure to keep track of which variable chunks we have written
         vchunks = {vnode.label:set() for vnode in self.inputs}
         
-        # Compute the Global Dimension Sizes dictionary
-        gdims = OrderedDict((d, self._filedesc.dimensions[d].size) for d in self._filedesc.dimensions)
+        # Compute the Global Dimension Sizes dictionary from the input variable nodes
+        inputdims = []
+        for vnode in self.inputs:
+            for d in self._filedesc.variables[vnode.label].dimensions:
+                if d not in inputdims:
+                    inputdims.append(d)
+        gdims = OrderedDict((d, self._filedesc.dimensions[d].size) for d in inputdims)
         
         # Iterate over the global dimension space
         for chunk in WriteNode._chunk_iter_(gdims, chunks=chunks):
@@ -952,7 +1059,10 @@ 

Source code for pyconform.flownodes

                 
                 # Write the data to the variable, if it hasn't already been written
                 if repr(wchunk) not in vchunks[vname]:
-                    ncvar[wchunk] = vnode[rchunk]
+                    vdata = vnode[rchunk]
+                    if isinstance(vdata, CharArray):
+                        vdata = vdata.stretch(ncvar.shape[-1])
+                    ncvar[wchunk] = vdata
                     vchunks[vname].add(repr(wchunk))
 
         # Close the file after completion
diff --git a/docs/_modules/pyconform/functions.html b/docs/_modules/pyconform/functions.html
index 7d4857f0..5352a75e 100644
--- a/docs/_modules/pyconform/functions.html
+++ b/docs/_modules/pyconform/functions.html
@@ -169,7 +169,7 @@ 

Source code for pyconform.functions

 
 from abc import ABCMeta, abstractmethod
 from pyconform.physarray import PhysArray, UnitsError
-from numpy import sqrt, mean, where
+from numpy.ma import sqrt, where
 from cf_units import Unit
 
 #=======================================================================================================================
@@ -443,7 +443,7 @@ 

Source code for pyconform.functions

         data_r = self.arguments[0]
         data = data_r if is_constant(data_r) else data_r[index]
         if isinstance(data, PhysArray):
-            return PhysArray(sqrt(data.data), units=self._units, name='sqrt({})'.format(data.name),
+            return PhysArray(sqrt(data), units=self._units, name='sqrt({})'.format(data.name),
                              dimensions=data.dimensions, positive=data.positive)
         else:
             return sqrt(data)
@@ -468,12 +468,7 @@

Source code for pyconform.functions

         data = self.arguments[0][index]
         dimensions = self.arguments[1:]
         indims = [d for d in dimensions if d in data.dimensions]
-        axes = tuple(data.dimensions.index(d) for d in indims)
-        new_dims = tuple(d for d in data.dimensions if d not in indims)
-        dim_str = ','.join(str(d) for d in indims)
-        return PhysArray(mean(data.data, axis=axes),
-                         units=data.units, dimensions=new_dims, positive=data.positive,
-                         name='mean({}, dims=[{}])'.format(data.name, dim_str))
+ return data.mean(dimensions=indims)
#=================================================================================================== @@ -512,17 +507,52 @@

Source code for pyconform.functions

 
[docs]class ChangeUnitsFunction(Function): key = 'chunits' - def __init__(self, data, units=1): - super(ChangeUnitsFunction, self).__init__(data, units=units) + def __init__(self, data, units=None, refdate=None, calendar=None): + super(ChangeUnitsFunction, self).__init__(data, units=units, refdate=refdate, calendar=calendar) + dunits = Unit(1) if is_constant(data) else data[None].units + dcal = dunits.calendar + if dunits.is_time_reference(): + dunit, dref = [s.strip() for s in dunits.origin.split('since')] + else: + dunit = dunits.origin + dref = None + + uobj = Unit(units) if is_constant(units) else units[None].units + ucal = uobj.calendar + if uobj.is_time_reference(): + uunit, uref = [s.strip() for s in uobj.origin.split('since')] + else: + uunit = uobj.origin + uref = None + + unit = dunit if units is None else uunit + + if isinstance(refdate, basestring): + ref = refdate + elif refdate is None: + ref = dref if uref is None else uref + else: + raise ValueError('chunits: Reference date must be a string, if given') + + if isinstance(calendar, basestring): + cal = calendar + elif calendar is None: + cal = dcal if ucal is None else ucal + else: + raise ValueError('chunits: Calendar must be a string, if given') + + if ref is None: + self._newunits = Unit(unit, calendar=cal) + else: + self._newunits = Unit('{} since {}'.format(unit, ref), calendar=cal) + def __getitem__(self, index): data = self.arguments[0] if is_constant(self.arguments[0]) else self.arguments[0][index] - units = self.keywords['units'] if is_constant(self.keywords['units']) else self.keywords['units'][index] - uobj = units.units if isinstance(units, PhysArray) else Unit(units) - cal_str = '' if uobj.calendar is None else '|{}'.format(uobj.calendar) - unit_str = '{}{}'.format(uobj, cal_str) + cal_str = '' if self._newunits.calendar is None else '|{}'.format(self._newunits.calendar) + unit_str = '{}{}'.format(self._newunits, cal_str) new_name = 'chunits({}, units={})'.format(data.name, unit_str) - return PhysArray(data, name=new_name, units=uobj)
+ return PhysArray(data, name=new_name, units=self._newunits)
#=================================================================================================== diff --git a/docs/_modules/pyconform/physarray.html b/docs/_modules/pyconform/physarray.html index 0d0356c1..13dba733 100644 --- a/docs/_modules/pyconform/physarray.html +++ b/docs/_modules/pyconform/physarray.html @@ -215,6 +215,41 @@

Source code for pyconform.physarray

     return numpy.ma.getmask(obj)
+#======================================================================================================================= +# getdtype +#======================================================================================================================= +
[docs]def getdtype(obj): + """ + Get the dtype associated with an object + """ + return numpy.asarray(obj).dtype
+ + +#======================================================================================================================= +# ischartype +#======================================================================================================================= +
[docs]def ischartype(obj): + """ + Return whether the object is a string/character type + """ + return getdtype(obj).char in ('S', 'U')
+ + +#======================================================================================================================= +# getshape +#======================================================================================================================= +
[docs]def getshape(obj): + """ + Get the shape associated with an object + """ + if isinstance(obj, PhysArray): + return obj.shape + elif ischartype(obj): + return CharArray._chararray_(obj).shape + else: + return numpy.shape(obj)
+ + #======================================================================================================================= # getname #======================================================================================================================= @@ -237,6 +272,8 @@

Source code for pyconform.physarray

     """
     if isinstance(obj, PhysArray):
         return obj.units
+    elif ischartype(obj):
+        return Unit('no unit')
     else:
         return Unit(1)
@@ -251,7 +288,7 @@

Source code for pyconform.physarray

     if isinstance(obj, PhysArray):
         return obj.dimensions
     else:
-        return tuple(reversed(range(len(numpy.shape(obj)))))
+ return tuple(reversed(range(len(getshape(obj)))))
#======================================================================================================================= @@ -278,12 +315,15 @@

Source code for pyconform.physarray

     along the edges of a Data Flow graph.
     """
 
-    def __new__(cls, indata, mask=None, name=None, units=None, dimensions=None, positive=''):
-        obj = numpy.ma.asarray(indata).view(cls)
+    def __new__(cls, indata, name=None, units=None, dimensions=None, positive='', **kwds):
+        makwds = {k:kwds[k] for k in ['dtype'] if k in kwds}
+        obj = numpy.ma.asarray(indata, **makwds).view(cls)
+        if obj.dtype.char in ('S', 'U'):
+            return CharArray(indata, name=name, dimensions=dimensions)
         
         # Add the mask if specified
-        if mask is not None:
-            obj.mask = mask
+        if 'mask' in kwds:
+            obj.mask = kwds['mask']
 
         # Store a name associated with the object
         if name is None:
@@ -295,7 +335,7 @@ 

Source code for pyconform.physarray

         if units is None:
             obj.units = getunits(indata)
         else:
-            obj.units = Unit(units)
+            obj.units = units
 
         # Store dimension names associated with each axis
         if dimensions is None:
@@ -337,17 +377,17 @@ 

Source code for pyconform.physarray

         return self._optinfo['units']
 
     @units.setter
-    def units(self, units):
+    def units(self, u):
         """Units of the data"""
-        self._optinfo['units'] = Unit(units)
+        self._optinfo['units'] = u if isinstance(u, Unit) else Unit(u)
     
     @staticmethod
     def _safe_convert_(obj, units1, units2):
         # Because netcdftime datetime conversion always returns an NDArray, even if the
         # original object is a subclass of NDArray, we have to wrap the convert function
         # to safely preserve the object type...  sigh.
-        u1 = Unit(units1)
-        u2 = Unit(units2)
+        u1 = units1 if isinstance(units1, Unit) else Unit(units1)
+        u2 = units2 if isinstance(units2, Unit) else Unit(units2)
         if isinstance(obj, PhysArray):
             new_array = numpy.ma.MaskedArray(units1.convert(obj.data, units2), mask=obj.mask, dtype=obj.dtype)
             u1_str = '{}'.format(u1) + ('|{}'.format(u1.calendar) if u1.calendar else '')
@@ -366,7 +406,7 @@ 

Source code for pyconform.physarray

         Parameters:
             units (Unit): The new units to which to convert the PhysArray
         """
-        uunit = Unit(units)
+        uunit = units if isinstance(units, Unit) else Unit(units)
         if self.units == uunit:
             return self
         elif self.units.is_convertible(uunit):
@@ -377,15 +417,15 @@ 

Source code for pyconform.physarray

     @property
     def dimensions(self):
         """Named dimensions of the data"""
-        return self._optinfo['dimensions']
+        return self._optinfo['dimensions']            
 
     @dimensions.setter
     def dimensions(self, dims):
         """Named dimensions of the data"""
         if not isinstance(dims, (list, tuple)):
-            raise TypeError('Dimensions must be a tuple')
+            raise TypeError('Dimensions must be a tuple, not {}'.format(type(dims)))
         if len(dims) != len(self.shape):
-            raise ValueError('Dimensions must have same length as shape')
+            raise ValueError('Dimensions {} must have same length as shape {}'.format(dims, self.shape))
         self._optinfo['dimensions'] = tuple(dims)
     
 
[docs] def transpose(self, *dims): @@ -606,7 +646,7 @@

Source code for pyconform.physarray

 
 
[docs] def invert(self): """Return a new PhysArray with the value of the array inverted (1/value)""" - return PhysArray(1.0 / self.data, dimensions=self.dimensions, units=self.units.invert(), + return PhysArray(1.0 / self, dimensions=self.dimensions, units=self.units.invert(), name='(1/{!s})'.format(self), positive=self.positive)
def __div__(self, other): @@ -685,7 +725,167 @@

Source code for pyconform.physarray

         self.name='({!s}**{!s})'.format(self, other)
         self.units **= other
         self.positive = None if other.data % 2 == 0 else self.positive
-        return self
+ return self + +
[docs] def mean(self, dimensions=None, **kwds): + if dimensions is None: + axis = kwds['axis'] if 'axis' in kwds else None + elif isinstance(dimensions, (list, tuple)): + axis = tuple(i for i in sorted(self.dimensions.index(d) for d in dimensions)) + else: + raise TypeError('Dimensions must be given as a list or tuple') + if axis is None: + dims = self.dimensions + meanval = self.view(numpy.ma.MaskedArray).mean() + elif isinstance(axis, int): + dims = (self.dimensions[axis],) + meanval = self.view(numpy.ma.MaskedArray).mean(axis=axis) + elif isinstance(axis, (list, tuple)): + dims = tuple(self.dimensions[i] for i in axis) + meanval = self.view(numpy.ma.MaskedArray) + for a in axis: + meanval = meanval.mean(axis=a) + else: + raise TypeError('Axis must be given as an integer, list or tuple') + new_dims = tuple(d for d in self.dimensions if d not in dims) + dim_str = ','.join(str(d) for d in dims) + return PhysArray(meanval, name='mean({}, dims=[{}])'.format(self.name, dim_str), dimensions=new_dims, + positive=self.positive, units=self.units)
+ +
[docs] def sum(self, dimensions=None, **kwds): + if dimensions is None: + axis = kwds['axis'] if 'axis' in kwds else None + elif isinstance(dimensions, (list, tuple)): + axis = tuple(i for i in sorted(self.dimensions.index(d) for d in dimensions)) + else: + raise TypeError('Dimensions must be given as a list or tuple') + if axis is None: + dims = self.dimensions + sumval = self.view(numpy.ma.MaskedArray).sum() + elif isinstance(axis, int): + dims = (self.dimensions[axis],) + sumval = self.view(numpy.ma.MaskedArray).sum(axis=axis) + elif isinstance(axis, (list, tuple)): + dims = tuple(self.dimensions[i] for i in axis) + sumval = self.view(numpy.ma.MaskedArray) + for a in axis: + sumval = sumval.mean(axis=a) + else: + raise TypeError('Axis must be given as an integer, list or tuple') + new_dims = tuple(d for d in self.dimensions if d not in dims) + dim_str = ','.join(str(d) for d in dims) + return PhysArray(sumval, name='sum({}, dims=[{}])'.format(self.name, dim_str), dimensions=new_dims, + positive=self.positive, units=self.units)
+ + +#======================================================================================================================= +# CharArray +#======================================================================================================================= +
[docs]class CharArray(PhysArray): + """ + Special kind of PhysArray to deal with string arrays + """ + + def __new__(cls, indata, name=None, dimensions=None): + obj = numpy.ma.asarray(indata, dtype='S') + if len(obj.shape) == 0: + obj = obj.reshape(1).view('S1') + else: + strlen = obj.dtype.itemsize + shape = obj.shape + ((strlen,) if strlen > 1 else tuple()) + obj = obj.view('S1').reshape(shape) + obj = numpy.ma.masked_where(obj == '', obj).view(cls) + obj.fill_value = '' + + # Store a name associated with the object + if name is None: + obj.name = getname(indata) + else: + obj.name = name + + # Store units of the data + obj.units = Unit('no unit') + + # Store dimension names associated with each axis + if dimensions is None: + obj.dimensions = getdimensions(indata) + else: + obj.dimensions = dimensions + + # Set the positive direction for the data + obj.positive = None + + return obj + + @staticmethod + def _chararray_(indata): + obj = CharArray._strarray_(indata) + if len(obj.shape) == 0: + obj = obj.reshape(1).view('S1') + else: + strlen = obj.dtype.itemsize + shape = obj.shape + ((strlen,) if strlen > 1 else tuple()) + obj = obj.view('S1').reshape(shape) + return obj + + @staticmethod + def _strarray_(indata): + return numpy.asarray(indata, dtype='S') + + def __repr__(self): + if self.shape[-1] > 0: + prndat = self.data.view('S{}'.format(self.shape[-1])).reshape(self.shape[:-1]) + else: + prndat = self.data + datstr = str(prndat).replace(linesep, ' ') + return ('{!s}(data={!s}, name={!r}, dimensions=' + '{!s})').format(self.__class__.__name__, datstr, self.name, self.dimensions) + @property + def units(self): + """Units of the data""" + return self._optinfo['units'] + + @units.setter + def units(self, units): + new_units = units if isinstance(units, Unit) else Unit(units) + if not new_units.is_no_unit(): + raise UnitsError('CharArrays cannot have units.') + self._optinfo['units'] = new_units + + @property + def positive(self): + """Positive direction (up or down) for the data""" + return self._optinfo['positive'] + + @positive.setter + def positive(self, pos): + if pos is not None: + raise ValueError('CharArrays cannot be assigned a positive attribute') + self._optinfo['positive'] = pos + +
[docs] def convert(self, units): + try: + new_self = PhysArray.convert(self, units) + except UnitsError: + raise UnitsError('CharArrays do not have units and cannot be converted to units {}'.format(units)) + return new_self
+ +
[docs] def transpose(self, *dims): + if set(dims) == set(self.dimensions) and dims[-1] != self.dimensions[-1]: + raise DimensionsError('The last dimension of a CharArray must always be the string length. ' + 'Cannot transpose.') + return PhysArray.transpose(self, *dims)
+ +
[docs] def invert(self): + raise NotImplementedError('CharArrays cannot be inverted')
+ +
[docs] def stretch(self, newlen): + if newlen > self.shape[-1]: + pad = numpy.zeros((self.shape[:-1] + (newlen-self.shape[-1],)), dtype='S') + pad = numpy.ma.masked_where(pad == '', pad) + return CharArray(numpy.ma.concatenate((self, pad), axis=-1), name=self.name, dimensions=self.dimensions) + else: + return self
diff --git a/docs/datasets.html b/docs/datasets.html index 34ba8b45..2b50e78f 100644 --- a/docs/datasets.html +++ b/docs/datasets.html @@ -236,7 +236,7 @@
-class pyconform.datasets.DimensionDesc(name, size=None, unlimited=False)[source]¶
+class pyconform.datasets.DimensionDesc(name, size=None, unlimited=False, stringlen=False)[source]¶

Bases: object

Descriptor for a dimension in a DatasetDesc

Contains the name of the dimensions, its size, and whether the dimension is limited or @@ -273,6 +273,12 @@

Numeric size of the dimension (if set)

+
+
+stringlen¶
+

Boolean indicating whether the dimension represents a string length or not

+
+
static unique(descs)[source]¶
@@ -415,16 +421,11 @@
-
-
-t = 'f8'¶
-
-
-class pyconform.datasets.VariableDesc(name, datatype='float32', dimensions=(), definition=None, attributes={})[source]¶
+class pyconform.datasets.VariableDesc(name, datatype='float', dimensions=(), definition=None, attributes={})[source]¶

Bases: object

Descriptor for a variable in a dataset

Contains the variable name, string datatype, dimensions tuple, attributes dictionary, @@ -460,6 +461,12 @@

Dictionary of dimension descriptors for dimensions on which the variable depends

+
+
+dtype¶
+

NumPy dtype of the variable data

+
+
files¶
diff --git a/docs/flownodes.html b/docs/flownodes.html index ab034ecf..e5172e78 100644 --- a/docs/flownodes.html +++ b/docs/flownodes.html @@ -262,7 +262,7 @@
-class pyconform.flownodes.ValidateNode(label, dnode, units=None, dimensions=None, dtype=None, attributes={})[source]¶
+class pyconform.flownodes.ValidateNode(label, dnode, dimensions=None, dtype=None, attributes={})[source]¶

Bases: pyconform.flownodes.FlowNode

FlowNode class to validate input data from a neighboring FlowNode

The ValidateNode takes additional attributes in its initializer that can effect the @@ -348,6 +348,34 @@

+
+
+pyconform.flownodes.iter_bfs(node)[source]¶
+

Iterate through graph of FlowNodes from a starting node using a Breadth-First Search

+ +++ + + + +
Parameters:node (FlowNode) – the starting node from where to begin iterating
+
+ +
+
+pyconform.flownodes.iter_dfs(node)[source]¶
+

Iterate through graph of FlowNodes from a starting node using a Depth-First Search

+ +++ + + + +
Parameters:node (FlowNode) – the starting node from where to begin iterating
+
+ diff --git a/docs/functions.html b/docs/functions.html index 2512ae63..3f8ecf21 100644 --- a/docs/functions.html +++ b/docs/functions.html @@ -198,7 +198,7 @@
-class pyconform.functions.ChangeUnitsFunction(data, units=1)[source]¶
+class pyconform.functions.ChangeUnitsFunction(data, units=None, refdate=None, calendar=None)[source]¶

Bases: pyconform.functions.Function

diff --git a/docs/genindex.html b/docs/genindex.html index a51bc152..d8811d6b 100644 --- a/docs/genindex.html +++ b/docs/genindex.html @@ -211,13 +211,19 @@

C

  • calendar() (pyconform.datasets.VariableDesc method)
  • cfunits() (pyconform.datasets.VariableDesc method) +
  • +
  • ChangeUnitsFunction (class in pyconform.functions)
  • @@ -240,8 +246,6 @@

    D

  • DimensionDesc (class in pyconform.datasets)
  • - - + @@ -323,6 +331,8 @@

    G

  • getdata() (in module pyconform.physarray)
  • getdimensions() (in module pyconform.physarray) +
  • +
  • getdtype() (in module pyconform.physarray)
  • getmask() (in module pyconform.physarray)
  • @@ -331,6 +341,8 @@

    G

  • getname() (in module pyconform.physarray)
  • getpositive() (in module pyconform.physarray) +
  • +
  • getshape() (in module pyconform.physarray)
  • getunits() (in module pyconform.physarray)
  • @@ -346,15 +358,25 @@

    I

  • InputDatasetDesc (class in pyconform.datasets)
  • - - + @@ -425,6 +447,8 @@

    M

    -
  • units (pyconform.physarray.PhysArray attribute) -
  • -
  • units() (pyconform.datasets.VariableDesc method) +
  • units (pyconform.physarray.CharArray attribute) + +
    • +
    • units() (pyconform.datasets.VariableDesc method) +
    • UnitsError
    • UnitsWarning diff --git a/docs/objects.inv b/docs/objects.inv index 39b95ae80b1c0a5cdeb192000062bdf07b2e4d06..d1553eae623db339551d51fd064662485a930d95 100644 GIT binary patch delta 1354 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

      Copyright 2017, University Corporation for Atmospheric Research LICENSE: See the LICENSE.rst file for details

      +
      +
      +class pyconform.physarray.CharArray[source]¶
      +

      Bases: pyconform.physarray.PhysArray

      +

      Special kind of PhysArray to deal with string arrays

      +
      +
      +convert(units)[source]¶
      +
      + +
      +
      +invert()[source]¶
      +
      + +
      +
      +positive¶
      +

      Positive direction (up or down) for the data

      +
      + +
      +
      +stretch(newlen)[source]¶
      +
      + +
      +
      +transpose(*dims)[source]¶
      +
      + +
      +
      +units¶
      +

      Units of the data

      +
      + +
      +
      exception pyconform.physarray.DimensionsError[source]¶
      @@ -238,6 +277,11 @@

      Return a new PhysArray with the value of the array inverted (1/value)

      +
      +
      +mean(dimensions=None, **kwds)[source]¶
      +
      +
      name¶
      @@ -250,6 +294,11 @@

      Positive direction (up or down) for the data

      +
      +
      +sum(dimensions=None, **kwds)[source]¶
      +
      +
      transpose(*dims)[source]¶
      @@ -299,6 +348,12 @@

      Retrieve the dimensions-tuple associated with the object

      +
      +
      +pyconform.physarray.getdtype(obj)[source]¶
      +

      Get the dtype associated with an object

      +
      +
      pyconform.physarray.getmask(obj)[source]¶
      @@ -317,12 +372,24 @@

      Retrieve the positive attribute associated with the object

      +
      +
      +pyconform.physarray.getshape(obj)[source]¶
      +

      Get the shape associated with an object

      +
      +
      pyconform.physarray.getunits(obj)[source]¶

      Retrieve the Unit associated with the object

      +
      +
      +pyconform.physarray.ischartype(obj)[source]¶
      +

      Return whether the object is a string/character type

      +
      + diff --git a/docs/searchindex.js b/docs/searchindex.js index 3af7141a..ef04b721 100644 --- a/docs/searchindex.js +++ b/docs/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["changelog","dataflow","datasets","flownodes","functions","index","indexing","license","manual","parsing","physarray","pyconform","readme"],envversion:52,filenames:["changelog.rst","dataflow.rst","datasets.rst","flownodes.rst","functions.rst","index.rst","indexing.rst","license.rst","manual.rst","parsing.rst","physarray.rst","pyconform.rst","readme.rst"],objects:{"":{pyconform:[11,0,0,"-"]},"pyconform.dataflow":{DataFlow:[1,1,1,""],VariableNotFoundError:[1,4,1,""]},"pyconform.dataflow.DataFlow":{dimension_map:[1,2,1,""],execute:[1,3,1,""]},"pyconform.datasets":{DatasetDesc:[2,1,1,""],DefinitionWarning:[2,4,1,""],DimensionDesc:[2,1,1,""],FileDesc:[2,1,1,""],InputDatasetDesc:[2,1,1,""],OutputDatasetDesc:[2,1,1,""],VariableDesc:[2,1,1,""]},"pyconform.datasets.DatasetDesc":{dimensions:[2,2,1,""],files:[2,2,1,""],name:[2,2,1,""],variables:[2,2,1,""]},"pyconform.datasets.DimensionDesc":{is_set:[2,3,1,""],name:[2,2,1,""],set:[2,3,1,""],size:[2,2,1,""],unique:[2,5,1,""],unlimited:[2,2,1,""],unset:[2,3,1,""]},"pyconform.datasets.FileDesc":{attributes:[2,2,1,""],deflate:[2,2,1,""],dimensions:[2,2,1,""],exists:[2,3,1,""],format:[2,2,1,""],name:[2,2,1,""],unique:[2,5,1,""],variables:[2,2,1,""]},"pyconform.datasets.OutputDatasetDesc":{t:[2,2,1,""]},"pyconform.datasets.VariableDesc":{attributes:[2,2,1,""],calendar:[2,3,1,""],cfunits:[2,3,1,""],datatype:[2,2,1,""],dimensions:[2,2,1,""],files:[2,2,1,""],name:[2,2,1,""],unique:[2,5,1,""],units:[2,3,1,""]},"pyconform.flownodes":{DataNode:[3,1,1,""],EvalNode:[3,1,1,""],FlowNode:[3,1,1,""],MapNode:[3,1,1,""],ReadNode:[3,1,1,""],UnitsWarning:[3,4,1,""],ValidateNode:[3,1,1,""],ValidationWarning:[3,4,1,""],WriteNode:[3,1,1,""]},"pyconform.flownodes.EvalNode":{sumlike_dimensions:[3,2,1,""]},"pyconform.flownodes.FlowNode":{inputs:[3,2,1,""],label:[3,2,1,""]},"pyconform.flownodes.ValidateNode":{attributes:[3,2,1,""],dimensions:[3,2,1,""]},"pyconform.flownodes.WriteNode":{disable_history:[3,3,1,""],enable_history:[3,3,1,""],execute:[3,3,1,""]},"pyconform.functions":{AdditionOperator:[4,1,1,""],ChangeUnitsFunction:[4,1,1,""],DivisionOperator:[4,1,1,""],Function:[4,1,1,""],FunctionBase:[4,1,1,""],LimitFunction:[4,1,1,""],MeanFunction:[4,1,1,""],MultiplicationOperator:[4,1,1,""],NegationOperator:[4,1,1,""],Operator:[4,1,1,""],PositiveDownFunction:[4,1,1,""],PositiveUpFunction:[4,1,1,""],PowerOperator:[4,1,1,""],SquareRootFunction:[4,1,1,""],SubtractionOperator:[4,1,1,""],find:[4,6,1,""],find_function:[4,6,1,""],find_operator:[4,6,1,""],is_constant:[4,6,1,""],list_functions:[4,6,1,""],list_operators:[4,6,1,""]},"pyconform.functions.AdditionOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.ChangeUnitsFunction":{key:[4,2,1,""]},"pyconform.functions.DivisionOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.Function":{add_sumlike_dimensions:[4,3,1,""],key:[4,2,1,""],sumlike_dimensions:[4,2,1,""]},"pyconform.functions.FunctionBase":{key:[4,2,1,""]},"pyconform.functions.LimitFunction":{key:[4,2,1,""]},"pyconform.functions.MeanFunction":{key:[4,2,1,""]},"pyconform.functions.MultiplicationOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.NegationOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.Operator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.PositiveDownFunction":{key:[4,2,1,""]},"pyconform.functions.PositiveUpFunction":{key:[4,2,1,""]},"pyconform.functions.PowerOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.SquareRootFunction":{key:[4,2,1,""]},"pyconform.functions.SubtractionOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.indexing":{align_index:[6,6,1,""],index_str:[6,6,1,""],index_tuple:[6,6,1,""],join:[6,6,1,""]},"pyconform.parsing":{ParsedBinOp:[9,1,1,""],ParsedFunction:[9,1,1,""],ParsedUniOp:[9,1,1,""],ParsedVariable:[9,1,1,""],parse_definition:[9,6,1,""]},"pyconform.physarray":{DimensionsError:[10,4,1,""],PhysArray:[10,1,1,""],UnitsError:[10,4,1,""],getdata:[10,6,1,""],getdimensions:[10,6,1,""],getmask:[10,6,1,""],getname:[10,6,1,""],getpositive:[10,6,1,""],getunits:[10,6,1,""]},"pyconform.physarray.PhysArray":{convert:[10,3,1,""],dimensions:[10,2,1,""],down:[10,3,1,""],flip:[10,3,1,""],invert:[10,3,1,""],name:[10,2,1,""],positive:[10,2,1,""],transpose:[10,3,1,""],units:[10,2,1,""],up:[10,3,1,""]},pyconform:{dataflow:[1,0,0,"-"],datasets:[2,0,0,"-"],flownodes:[3,0,0,"-"],functions:[4,0,0,"-"],indexing:[6,0,0,"-"],parsing:[9,0,0,"-"],physarray:[10,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","attribute","Python attribute"],"3":["py","method","Python method"],"4":["py","exception","Python exception"],"5":["py","staticmethod","Python static method"],"6":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:attribute","3":"py:method","4":"py:exception","5":"py:staticmethod","6":"py:function"},terms:{"1deg":0,"boolean":[2,8],"byte":8,"case":8,"class":[1,2,3,4,9,10],"default":[8,12],"export":8,"float":8,"function":[0,1,2,3,6,9,11],"import":8,"int":[1,3],"long":[2,8],"new":[0,3,8,10],"public":[7,11,12],"return":[2,3,6,8,10],"short":8,"static":2,"switch":8,"true":[1,2,6,8],"var":8,"while":[6,8],ARE:7,Added:0,FOR:5,For:[3,8],HAS:7,ITS:7,NOT:[7,8],SUCH:7,THAT:7,THE:7,THERE:7,That:8,The:[1,2,3,5,6,7,10,12],Then:12,There:8,These:[3,8,12],USE:7,Use:[1,3,5],Uses:0,Using:5,WILL:7,WITH:7,With:8,__getitem__:[1,3],abil:0,about:[2,8],abov:[4,7,8,12],absolut:[3,8],accept:[3,8],access:6,accord:[2,3,6,8,12],accordingli:7,achiev:8,acknowledg:7,across:[2,8],act:8,action:[1,4,7],activ:7,actual:[2,12],acycl:[1,3],add:[0,8,12],add_sumlike_dimens:4,added:[2,3,8,12],adding:8,addit:[1,2,3,7,8],addition:[8,12],additionoper:4,adjac:3,advantag:8,advis:[3,7],affect:3,after:[8,12],agent:7,agre:7,air:7,aircraft:7,align:6,align_index:6,all:[1,2,3,7,8,12],alloc:8,allow:[0,7,8],almost:8,along:[1,8,10],alreadi:[8,10],also:[7,8],altern:[8,12],alwai:8,amon:0,amount:[6,8],ani:[3,7,8,12],anoth:[1,2,8],anticip:7,anyth:3,api:0,appear:[2,3,7,8],append:8,appli:[6,8],appreci:8,appropri:8,approv:7,arg:[3,4],argument:3,aris:7,arrai:[2,6,10],asappytool:8,asaptool:12,associ:[1,2,3,8,10],assu:2,assum:[1,2,3,8],assume_1d_time_variant_metadata:8,assumpt:8,atmospher:[0,1,2,3,4,5,6,9,10,11,12],attach:8,attribut:[0,1,2,3,10],author:[11,12],authorship:7,automat:[0,8,12],avail:[7,8,12],averag:8,avoid:8,axi:[6,10],b40:0,backend:8,bad:2,base:[1,2,3,4,7,9,10,12],bash:8,basic:[8,10],becaus:8,been:[6,7,8,12],befor:5,behalf:7,behavior:[3,8],being:8,below:[4,8],between:[7,8],bin:[8,12],binari:[9,12],bool:1,both:[8,10],branch:8,breach:7,browser:12,bug:7,build:[5,8],calendar:2,call:[3,8],can:[2,3,5,6,12],cannot:8,capabl:8,capac:7,carri:10,caus:7,cesm:0,cf_unit:[2,8],cfunit:2,chang:3,changelog:5,changeunitsfunct:4,charact:8,check:[0,3,8,12],checkout:8,choos:12,chunit:4,chunk:[0,1,3,8],claim:7,classic:8,cli:8,climio:0,clone:[8,12],cmip5:0,cmip6:0,cmip:8,code:[0,5,7,8],collabor:7,collect:7,colorado:7,com:[8,12],combin:8,come:3,comm_world:8,comment:[11,12],commerci:7,common:[8,12],commun:[7,8],compact:6,compani:7,compress:8,compression_level:8,comput:[6,7,8],conform:[8,11],consecut:6,consequenti:7,consist:2,construct:[1,2,3,9],consult:8,consum:8,contain:[1,2,3,7,8,10,12],content:[2,5],continu:8,contract:7,contribut:7,control:[7,8],convent:8,convers:[1,8],convert:[6,10],coordin:0,copi:7,copyright:[0,1,2,3,4,6,7,9,10,11,12],core:[8,10],corpor:[0,1,2,3,4,5,6,9,10,11,12],correct:8,correspond:[1,3,8],correspondingli:10,cost:6,costli:6,could:[1,7],cpu:8,creat:[0,1,3,7,8,12],create_specifi:8,critic:[7,8],current:[8,12],dag:1,damag:7,data:[0,1,2,3,4,6,7,8,10],dataarrai:3,dataflow:11,datanod:3,dataset:[0,7,8,11,12],datasetdesc:2,datatyp:2,date:[0,12],death:7,debug:8,declar:2,defin:[0,1,2,3,8,9,12],definit:[2,9],definitionwarn:2,deflat:[1,2,3],delet:8,demo:0,depend:[0,2,5,8],deri:10,desc:2,describ:[1,2,8],descriptor:[0,2],design:[6,7,8,12],desir:8,detail:[0,1,2,3,4,6,9,10,11,12],determin:8,devel:8,develop:[8,12],diagnost:8,dicitonari:2,dict:[1,2,3],dictionari:[1,2,3,6,8],differ:8,dim:[4,10],dimens:[1,2,3,4,6,8,10],dimension_map:1,dimensiondesc:2,dimensionserror:10,direct:[0,1,3,7,10],directli:[3,7,8,12],directori:[0,8,12],directpri:8,disabl:3,disable_histori:3,disclaim:7,displai:7,distribut:7,distutil:12,divisionoper:4,dmap:3,dnode:3,doc:[8,12],document:12,doe:[3,7,8,10,12],domin:8,don:8,done:8,doubl:8,down:[4,10],download:8,dreqpi:8,dsdict:2,dtype:3,dump:8,dure:[1,8,12],each:[1,2,3,6,8,10],earlier:[8,12],easi:8,easiest:8,easili:[8,12],edg:[1,3,10],edu:[8,11,12],effect:3,effici:[3,8],either:[2,8],element:9,elimin:3,employ:7,enabl:3,enable_histori:3,enhanc:7,enough:8,enter:12,entir:[8,12],entiti:7,entitl:7,environ:[7,8],environment:7,equal:[8,10],equit:7,equival:8,error:[3,8,10],etc:1,evalnod:3,evalu:3,even:7,event:7,everi:8,everyon:12,exampl:[0,6,8,12],except:[1,2,3,10],exclus:7,execut:[1,3,8],exist:[2,8,12],expand:8,experi:0,explicitli:8,express:[2,6,7],extens:8,extern:[1,8],extract:8,fact:8,factor:8,factori:8,fail:7,failur:[7,8],fals:[1,2,8],fastest:[1,3],fault:7,featur:[0,8],feel:8,few:8,fewer:8,field:8,file:[0,1,2,3,4,6,7,8,9,10,11,12],filedesc:[2,3],filenam:[2,8],fill:8,find:[4,8],find_funct:4,find_oper:4,first:[1,2,3,6,8],fit:[7,8],fix:[7,8],flag:8,flexibl:8,flip:10,float32:2,flow:[1,3,10],flownod:11,follow:[2,8],forc:8,format:[2,7,8,12],found:[1,2,8,12],free:7,freeli:7,frequenc:8,from:[1,2,3,5,6,7,10],full:8,func:[3,4],functionbas:4,functionevalu:4,gener:[0,1,6],get:8,getdata:10,getdimens:10,getmask:10,getnam:10,getposit:10,getunit:10,git:[8,12],github:[8,12],give:6,given:[1,3,6,8,10],glob:8,global:2,govern:7,grant:7,graph:[0,1,3,9,10],greater:8,greatli:8,hand:8,handi:12,handl:8,hard:8,has:[7,8,12],have:[2,3,6,8,12],hazard:7,head:8,header:2,help:8,henc:[2,8],herebi:7,hereund:7,high:7,highest:8,histori:[1,3,8],home:[8,12],how:[2,5,12],howev:[2,3,7,8,12],html:[8,12],http:[8,12],idl:8,idx:6,impact:8,impli:[7,8,12],implic:8,improv:[0,7,8],inadequ:7,incident:7,includ:[0,1,3,7,8,12],inclus:7,incorpor:7,increas:8,increasingli:8,incur:7,independ:[7,8],index1:6,index2:6,index:[1,3,5,8,11,12],index_exp:6,index_str:6,index_tupl:6,indic:[1,2,6,8,10],indirect:7,individu:7,ineffici:3,infil:8,infile1:8,infile2:8,inform:[2,7,8],infring:7,initi:[0,3],injuri:7,inpd:1,input:[1,2,3,8],input_file_list:8,inputdatasetdesc:2,insid:8,instal:5,instanc:8,instanti:8,instead:[2,8],institut:7,instruct:5,integ:8,intellectu:7,intend:7,intens:8,intention:7,interact:8,intercomparison:8,interest:7,interfac:[0,1,2,3,8],intern:[1,8],interpret:0,invari:8,invert:10,invest:6,involv:[10,12],irrepar:7,irrevoc:7,is_const:4,is_set:2,issu:12,item:3,its:[0,2,3,8,10],itself:[3,8],job:8,join:6,json:0,just:8,kei:[1,4,6],kevin:[11,12],kind:[2,7],know:8,known:12,kpaul:[11,12],kwd:[3,4],label:3,laboratori:7,larg:[6,8],largest:8,last:[1,3,8],lat:8,later:8,launch:8,launcher:8,law:7,lead:7,leav:8,left:[4,8],legal:7,length:8,less:8,level:[1,2,3,8],liabil:7,liabl:7,lib:[8,12],librari:8,licens:[0,1,2,3,4,5,6,9,10,11,12],license:7,light:8,like:[1,3,6,8,12],limit:[2,4,6,7,8],limitfunct:4,link:[8,12],linux:[8,12],list:[2,8],list_funct:4,list_oper:4,littl:8,load:[8,12],local:[8,12],locat:12,lon:8,look:12,lost:7,lsf:8,machin:12,made:[3,8,12],mai:[3,7,8,12],main:12,major:[0,12],make:[7,8,12],manag:1,mani:[0,8],manual:5,manufactur:7,map:[0,1,2,3],mapnod:3,mark:8,mask:10,maskedarrai:10,match:[3,8],mathemat:2,max_mean_ab:3,maximum:[3,8],mean:[3,4,7,8],meanfunct:4,meet:3,memori:[3,6],mention:8,merchant:7,meta1d:8,metadata:[2,8],metavar:2,method:[3,6],mickelso:[11,12],mickelson:[11,12],might:[2,8,12],min_mean_ab:3,minim:2,minimum:3,mip_table_pars:0,mode:[8,12],model:8,modif:7,modifi:7,modul:[1,3,5,6,8,9,10],more:[0,2,8,12],most:[6,8,12],mpi4pi:8,mpi:[8,12],mpirun:8,much:8,multi:2,multicor:8,multipl:[2,3,6,8],multipli:[8,10],multiplicationoper:4,must:[2,3,7,8,12],name:[1,2,3,6,8,10],navig:7,ncar:[7,8,12],ncformat:8,ndarrai:[1,10],ndim:6,necesari:10,necessari:[8,9,10],need:[1,2,3,6,8,12],negationoper:4,neighbor:3,nest:2,netcdf3:8,netcdf3_64bit_data:2,netcdf3_64bit_offset:2,netcdf3_class:2,netcdf4:[2,8,12],netcdf4_class:2,netcdf4c:8,netcdf:[2,3,6,7,8,11,12],netcdf_format:8,newli:[8,12],next:8,nio:8,node:[1,3],nomin:8,non:[3,7,8],noncommerci:7,none:[1,2,3,4,8,10],nonexclus:7,noninfring:7,nontransfer:7,normal:8,notat:8,note:[7,8],noth:[6,10],notic:7,nuclear:7,numarg:4,number:[3,6,8],numer:[2,8],numpi:[1,6,8,10,12],obj:10,object:[0,1,2,3,4,6,9,10],oblig:7,obtain:5,obviou:2,obvious:8,occur:12,occurr:8,old:8,onc:[3,8,12],one:[1,2,8],onli:[3,7,8,10,12],open:8,oper:[1,3,4,6,7,8,9],option:[2,8,12],order:[1,3,8,10],ordereddict:[1,2,3,8],origin:[6,7],other:[0,2,3,7,8],otherwis:2,our:[6,8],out:[8,12],outd:1,outfile_prefix:8,output:[1,2,3,8],output_file_prefix:8,output_file_suffix:8,output_limit:8,output_prefix:8,output_suffix:8,outputdatasetdesc:2,over:8,overlap:8,overload:8,overrid:[1,3],overridden:8,overrun:6,overview:5,overwrit:[3,8],own:[7,8],owner:7,ownership:7,packag:[5,8],page:[5,12],parallel:[0,1,8],paramet:[1,2,3,6,8,10],pars:11,parse_definit:9,parsedbinop:9,parsedfunct:9,parseduniop:9,parsedvari:9,part:8,parti:[7,8],particular:7,pass:[8,10],patch:7,path:[8,12],pattern:8,paul:[11,12],per:8,perform:[1,7],permiss:[8,12],perpetu:7,person:7,pertain:8,physarrai:[0,3,11],physic:[7,10],pickl:8,pip:[8,12],place:[0,8,12],plant:7,pleas:12,point:[3,8,12],posit:10,positivedownfunct:4,positiveupfunct:4,possibl:[3,6,7,8],power:[0,7],poweroper:4,pre:0,precis:8,prefix:[8,12],present:[6,8],preserv:[1,3],prevent:8,previou:8,primari:10,print:8,print_diagnost:8,privat:8,problem:[6,12],process:8,processor:8,produc:8,product:5,profit:7,programm:6,project:8,properti:[3,7],proprietari:7,provid:[7,8],pull:12,purpos:[7,8],pyconform:7,pynio:8,pypars:8,pypi:8,pyreshap:12,python2:[8,12],python:[6,12],pythonpath:[8,12],question:[11,12],quotat:8,rang:8,rank:8,rather:3,rcp4_5:0,read:[1,2,3,6,8,12],readi:8,readm:8,readnod:3,reason:3,recent:[8,12],recipi:7,recogn:9,reduc:[6,8],reduct:6,refactor:0,refer:[2,3,8],referenc:3,regard:[7,8],regist:3,relat:7,releas:0,relief:7,remedi:7,remov:7,renam:3,repositori:0,repres:[1,2,3,7,8],represent:[6,7],reproduc:7,reproduct:7,request:[1,8,12],requir:[7,12],research:[0,1,2,3,4,5,6,9,10,11,12],reshap:8,respect:[7,8],restrict:7,restructuredtext:8,result:[3,6,7,12],retain:7,retriev:[2,3,10],revenu:7,right:[4,7],rigidli:12,risk:7,root:8,roughli:8,royalti:7,rshpr:8,rst:[0,1,2,3,4,6,8,9,10,11,12],rule:8,run:[1,8,12],s2s:8,s_b:8,safe:7,safeti:8,sake:8,sale:7,same:[2,8],sampl:8,satur:8,save:8,scale:8,scomm:1,script:12,search:5,second:6,section:[2,8,12],see:[0,1,2,3,4,6,8,9,10,11,12],select:12,self:2,sell:7,send:[11,12],sent:3,separ:8,sequenc:8,seri:8,serial:[0,1,8],session:8,set:[2,3,7,8,10],setup:[8,12],setuptool:[8,12],sever:7,shall:7,shape0:6,shape:6,shell:8,sheri:[11,12],should:[2,3,8,12],show:8,shown:8,signatur:3,similar:8,similarli:8,simpl:[2,8,12],simplecomm:[0,1,8],simplest:2,simpli:8,simplif:0,simplifi:0,simul:8,simultan:8,sinc:[8,12],singl:[2,6,8],sink:3,site:[8,12],size:[1,2,3,8],skip:8,slice12:6,slice1:6,slice2:6,slice:[3,6,8],slowest:[1,3],softwar:8,some:1,sort:1,sourc:[1,2,3,4,5,6,8,9,10],space:8,span:[2,8],spec:8,special:[3,7],specif:[7,8],specifi:2,speed:8,sphinx:[8,12],sqrt:4,squarerootfunct:4,src:0,stabl:[8,12],standard:[2,7,8,12],state:7,statement:6,statu:2,stdout:8,step:8,stop:8,storag:6,store:[3,6],stream:8,strexpr:9,string:[2,6,8,9,10],structur:0,subclass:10,sublicens:7,submiss:8,submit:[7,12],submodul:[],subset:[2,8],subtract:1,subtractionoper:4,suffici:8,suffix:8,suitabl:12,sum:3,sumlike_dimens:[3,4],suppli:[3,7],sure:[8,12],svn:12,synopt:8,system:[7,8,12],tabl:0,tag:12,take:[3,8],technolog:7,templat:0,term:[2,8],test:[0,8,12],text:8,than:8,thei:[2,6,8],them:8,therefor:[8,12],thereof:7,thi:[1,2,3,6,7,8,9,10,12],thing:8,third:[7,8],thorough:8,though:[8,12],through:[3,7],throughout:8,thu:8,time:[3,6,8],time_bound:8,time_seri:8,time_series_filenam:8,time_variant_metadata:8,titl:7,token:9,told:6,toler:7,too:8,tool:[7,8],top:8,tort:7,total:8,traffic:7,transfer:7,transform:[7,8,12],transmit:1,transpos:[1,10],treat:8,tseri:8,tupl:[2,3,6,10],two:6,type:[2,3,8,9,12],typic:[8,12],ucar:[7,8,11,12],udunits2:8,unari:9,understand:8,unfortun:8,uniqu:2,unit:[0,1,2,3,4,7,10],unitserror:10,unitswarn:3,univers:[0,1,2,3,4,5,6,9,10,11,12],unix:12,unless:8,unlik:2,unlimit:[2,8],unset:2,until:1,untransform:8,updat:12,upgrad:7,upon:[2,7,8,12],usag:12,use:[1,3,5,7,12],used:[0,2,8,9,12],useful:8,user:[0,3,5,12],uses:8,using:[2,8,12],usr:12,usual:8,util:8,valid:[3,8],valid_max:3,valid_min:3,validatenod:3,validationwarn:3,valu:[1,3,8,10],valueerror:[1,10],vari:[1,3,8],variabl:[0,1,2,3,8,9],variable_nam:8,variabledesc:2,variablenotfounderror:1,variant:8,variou:8,vebos:8,verbos:8,veri:[8,12],version:[5,8,12],via:[1,12],view:[2,6],viewer:8,vname:8,wai:[6,8],want:[8,12],warn:[2,3],warranti:7,weapon:7,weight:8,welcom:12,well:[6,8],what:5,when:[3,8],where:[1,2,3,6,8,12],whether:[1,2,7,8],which:[2,6,7,8,10,12],wide:8,wildcard:8,wish:[3,8],within:0,without:[7,8,12],wmode:8,word:8,work:[0,6,7,8,12],workspac:8,worldwid:7,worth:6,would:8,write:[1,2,3,8,12],write_mod:8,writenod:3,written:[2,8],yellowston:8,you:[3,7,8,12],your:[7,8,12]},titles:["PyConform ChangeLog","pyconform.dataflow","pyconform.datasets","pyconform.flownodes","pyconform.functions","Welcome to the PyConform documentation!","pyconform.indexing","Product License","The PyConform User\u2019s Manual","pyconform.parsing","pyconform.physarray","The PyConform Package","PyConform"],titleterms:{"function":[4,8],FOR:7,The:[8,11],Use:12,Using:[8,12],agreement:7,api:8,argument:8,atmospher:7,attribut:8,befor:[8,12],best:8,build:12,can:8,changelog:0,code:12,command:8,concept:8,contributor:7,convert:8,corpor:7,create_reshap:8,dataflow:1,dataset:2,depend:12,document:[5,8],flownod:3,from:[8,12],gener:8,how:8,index:6,indic:5,instal:[8,12],instruct:12,licens:7,line:8,manual:8,memori:8,method:8,modul:11,node:8,object:8,obtain:[8,12],overview:12,packag:[11,12],pars:9,perform:8,physarrai:10,product:7,pyconform:[0,1,2,3,4,5,6,8,9,10,11,12],pyreshap:8,python:8,requir:8,research:7,s2smake:8,s2srun:8,script:8,share:8,some:8,sourc:12,specfil:8,specifi:8,submodul:[],tabl:5,univers:7,unix:8,use:8,user:8,version:0,welcom:5,what:8,within:8}}) \ No newline at end of file +Search.setIndex({docnames:["changelog","dataflow","datasets","flownodes","functions","index","indexing","license","manual","parsing","physarray","pyconform","readme"],envversion:52,filenames:["changelog.rst","dataflow.rst","datasets.rst","flownodes.rst","functions.rst","index.rst","indexing.rst","license.rst","manual.rst","parsing.rst","physarray.rst","pyconform.rst","readme.rst"],objects:{"":{pyconform:[11,0,0,"-"]},"pyconform.dataflow":{DataFlow:[1,1,1,""],VariableNotFoundError:[1,4,1,""]},"pyconform.dataflow.DataFlow":{dimension_map:[1,2,1,""],execute:[1,3,1,""]},"pyconform.datasets":{DatasetDesc:[2,1,1,""],DefinitionWarning:[2,4,1,""],DimensionDesc:[2,1,1,""],FileDesc:[2,1,1,""],InputDatasetDesc:[2,1,1,""],OutputDatasetDesc:[2,1,1,""],VariableDesc:[2,1,1,""]},"pyconform.datasets.DatasetDesc":{dimensions:[2,2,1,""],files:[2,2,1,""],name:[2,2,1,""],variables:[2,2,1,""]},"pyconform.datasets.DimensionDesc":{is_set:[2,3,1,""],name:[2,2,1,""],set:[2,3,1,""],size:[2,2,1,""],stringlen:[2,2,1,""],unique:[2,5,1,""],unlimited:[2,2,1,""],unset:[2,3,1,""]},"pyconform.datasets.FileDesc":{attributes:[2,2,1,""],deflate:[2,2,1,""],dimensions:[2,2,1,""],exists:[2,3,1,""],format:[2,2,1,""],name:[2,2,1,""],unique:[2,5,1,""],variables:[2,2,1,""]},"pyconform.datasets.VariableDesc":{attributes:[2,2,1,""],calendar:[2,3,1,""],cfunits:[2,3,1,""],datatype:[2,2,1,""],dimensions:[2,2,1,""],dtype:[2,2,1,""],files:[2,2,1,""],name:[2,2,1,""],unique:[2,5,1,""],units:[2,3,1,""]},"pyconform.flownodes":{DataNode:[3,1,1,""],EvalNode:[3,1,1,""],FlowNode:[3,1,1,""],MapNode:[3,1,1,""],ReadNode:[3,1,1,""],UnitsWarning:[3,4,1,""],ValidateNode:[3,1,1,""],ValidationWarning:[3,4,1,""],WriteNode:[3,1,1,""],iter_bfs:[3,6,1,""],iter_dfs:[3,6,1,""]},"pyconform.flownodes.EvalNode":{sumlike_dimensions:[3,2,1,""]},"pyconform.flownodes.FlowNode":{inputs:[3,2,1,""],label:[3,2,1,""]},"pyconform.flownodes.ValidateNode":{attributes:[3,2,1,""],dimensions:[3,2,1,""]},"pyconform.flownodes.WriteNode":{disable_history:[3,3,1,""],enable_history:[3,3,1,""],execute:[3,3,1,""]},"pyconform.functions":{AdditionOperator:[4,1,1,""],ChangeUnitsFunction:[4,1,1,""],DivisionOperator:[4,1,1,""],Function:[4,1,1,""],FunctionBase:[4,1,1,""],LimitFunction:[4,1,1,""],MeanFunction:[4,1,1,""],MultiplicationOperator:[4,1,1,""],NegationOperator:[4,1,1,""],Operator:[4,1,1,""],PositiveDownFunction:[4,1,1,""],PositiveUpFunction:[4,1,1,""],PowerOperator:[4,1,1,""],SquareRootFunction:[4,1,1,""],SubtractionOperator:[4,1,1,""],find:[4,6,1,""],find_function:[4,6,1,""],find_operator:[4,6,1,""],is_constant:[4,6,1,""],list_functions:[4,6,1,""],list_operators:[4,6,1,""]},"pyconform.functions.AdditionOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.ChangeUnitsFunction":{key:[4,2,1,""]},"pyconform.functions.DivisionOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.Function":{add_sumlike_dimensions:[4,3,1,""],key:[4,2,1,""],sumlike_dimensions:[4,2,1,""]},"pyconform.functions.FunctionBase":{key:[4,2,1,""]},"pyconform.functions.LimitFunction":{key:[4,2,1,""]},"pyconform.functions.MeanFunction":{key:[4,2,1,""]},"pyconform.functions.MultiplicationOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.NegationOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.Operator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.PositiveDownFunction":{key:[4,2,1,""]},"pyconform.functions.PositiveUpFunction":{key:[4,2,1,""]},"pyconform.functions.PowerOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.functions.SquareRootFunction":{key:[4,2,1,""]},"pyconform.functions.SubtractionOperator":{key:[4,2,1,""],numargs:[4,2,1,""]},"pyconform.indexing":{align_index:[6,6,1,""],index_str:[6,6,1,""],index_tuple:[6,6,1,""],join:[6,6,1,""]},"pyconform.parsing":{ParsedBinOp:[9,1,1,""],ParsedFunction:[9,1,1,""],ParsedUniOp:[9,1,1,""],ParsedVariable:[9,1,1,""],parse_definition:[9,6,1,""]},"pyconform.physarray":{CharArray:[10,1,1,""],DimensionsError:[10,4,1,""],PhysArray:[10,1,1,""],UnitsError:[10,4,1,""],getdata:[10,6,1,""],getdimensions:[10,6,1,""],getdtype:[10,6,1,""],getmask:[10,6,1,""],getname:[10,6,1,""],getpositive:[10,6,1,""],getshape:[10,6,1,""],getunits:[10,6,1,""],ischartype:[10,6,1,""]},"pyconform.physarray.CharArray":{convert:[10,3,1,""],invert:[10,3,1,""],positive:[10,2,1,""],stretch:[10,3,1,""],transpose:[10,3,1,""],units:[10,2,1,""]},"pyconform.physarray.PhysArray":{convert:[10,3,1,""],dimensions:[10,2,1,""],down:[10,3,1,""],flip:[10,3,1,""],invert:[10,3,1,""],mean:[10,3,1,""],name:[10,2,1,""],positive:[10,2,1,""],sum:[10,3,1,""],transpose:[10,3,1,""],units:[10,2,1,""],up:[10,3,1,""]},pyconform:{dataflow:[1,0,0,"-"],datasets:[2,0,0,"-"],flownodes:[3,0,0,"-"],functions:[4,0,0,"-"],indexing:[6,0,0,"-"],parsing:[9,0,0,"-"],physarray:[10,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","attribute","Python attribute"],"3":["py","method","Python method"],"4":["py","exception","Python exception"],"5":["py","staticmethod","Python static method"],"6":["py","function","Python function"]},objtypes:{"0":"py:module","1":"py:class","2":"py:attribute","3":"py:method","4":"py:exception","5":"py:staticmethod","6":"py:function"},terms:{"1deg":0,"boolean":[2,8],"byte":8,"case":8,"class":[1,2,3,4,9,10],"default":[8,12],"export":8,"float":[2,8],"function":[0,1,2,3,6,9,11],"import":8,"int":[1,3],"long":[2,8],"new":[0,3,8,10],"public":[7,11,12],"return":[2,3,6,8,10],"short":8,"static":2,"switch":8,"true":[1,2,6,8],"var":8,"while":[6,8],ARE:7,Added:0,FOR:5,For:[3,8],HAS:7,ITS:7,NOT:[7,8],SUCH:7,THAT:7,THE:7,THERE:7,That:8,The:[1,2,3,5,6,7,10,12],Then:12,There:8,These:[3,8,12],USE:7,Use:[1,3,5],Uses:0,Using:5,WILL:7,WITH:7,With:8,__getitem__:[1,3],abil:0,about:[2,8],abov:[4,7,8,12],absolut:[3,8],accept:[3,8],access:6,accord:[2,3,6,8,12],accordingli:7,achiev:8,acknowledg:7,across:[2,8],act:8,action:[1,4,7],activ:7,actual:[2,12],acycl:[1,3],add:[0,8,12],add_sumlike_dimens:4,added:[2,3,8,12],adding:8,addit:[1,2,3,7,8],addition:[8,12],additionoper:4,adjac:3,advantag:8,advis:[3,7],affect:3,after:[8,12],agent:7,agre:7,air:7,aircraft:7,align:6,align_index:6,all:[1,2,3,7,8,12],alloc:8,allow:[0,7,8],almost:8,along:[1,8,10],alreadi:[8,10],also:[7,8],altern:[8,12],alwai:8,amon:0,amount:[6,8],ani:[3,7,8,12],anoth:[1,2,8],anticip:7,anyth:3,api:0,appear:[2,3,7,8],append:8,appli:[6,8],appreci:8,appropri:8,approv:7,arg:[3,4],argument:3,aris:7,arrai:[2,6,10],asappytool:8,asaptool:12,associ:[1,2,3,8,10],assu:2,assum:[1,2,3,8],assume_1d_time_variant_metadata:8,assumpt:8,atmospher:[0,1,2,3,4,5,6,9,10,11,12],attach:8,attribut:[0,1,2,3,10],author:[11,12],authorship:7,automat:[0,8,12],avail:[7,8,12],averag:8,avoid:8,axi:[6,10],b40:0,backend:8,bad:2,base:[1,2,3,4,7,9,10,12],bash:8,basic:[8,10],becaus:8,been:[6,7,8,12],befor:5,begin:3,behalf:7,behavior:[3,8],being:8,below:[4,8],between:[7,8],bin:[8,12],binari:[9,12],bool:1,both:[8,10],branch:8,breach:7,breadth:3,browser:12,bug:7,build:[5,8],calendar:[2,4],call:[3,8],can:[2,3,5,6,12],cannot:8,capabl:8,capac:7,carri:10,caus:7,cesm:0,cf_unit:[2,8],cfunit:2,chang:3,changelog:5,changeunitsfunct:4,charact:[8,10],chararrai:10,check:[0,3,8,12],checkout:8,choos:12,chunit:4,chunk:[0,1,3,8],claim:7,classic:8,cli:8,climio:0,clone:[8,12],cmip5:0,cmip6:0,cmip:8,code:[0,5,7,8],collabor:7,collect:7,colorado:7,com:[8,12],combin:8,come:3,comm_world:8,comment:[11,12],commerci:7,common:[8,12],commun:[7,8],compact:6,compani:7,compress:8,compression_level:8,comput:[6,7,8],conform:[8,11],consecut:6,consequenti:7,consist:2,construct:[1,2,3,9],consult:8,consum:8,contain:[1,2,3,7,8,10,12],content:[2,5],continu:8,contract:7,contribut:7,control:[7,8],convent:8,convers:[1,8],convert:[6,10],coordin:0,copi:7,copyright:[0,1,2,3,4,6,7,9,10,11,12],core:[8,10],corpor:[0,1,2,3,4,5,6,9,10,11,12],correct:8,correspond:[1,3,8],correspondingli:10,cost:6,costli:6,could:[1,7],cpu:8,creat:[0,1,3,7,8,12],create_specifi:8,critic:[7,8],current:[8,12],dag:1,damag:7,data:[0,1,2,3,4,6,7,8,10],dataarrai:3,dataflow:11,datanod:3,dataset:[0,7,8,11,12],datasetdesc:2,datatyp:2,date:[0,12],deal:10,death:7,debug:8,declar:2,defin:[0,1,2,3,8,9,12],definit:[2,9],definitionwarn:2,deflat:[1,2,3],delet:8,demo:0,depend:[0,2,5,8],depth:3,deri:10,desc:2,describ:[1,2,8],descriptor:[0,2],design:[6,7,8,12],desir:8,detail:[0,1,2,3,4,6,9,10,11,12],determin:8,devel:8,develop:[8,12],diagnost:8,dicitonari:2,dict:[1,2,3],dictionari:[1,2,3,6,8],differ:8,dim:[4,10],dimens:[1,2,3,4,6,8,10],dimension_map:1,dimensiondesc:2,dimensionserror:10,direct:[0,1,3,7,10],directli:[3,7,8,12],directori:[0,8,12],directpri:8,disabl:3,disable_histori:3,disclaim:7,displai:7,distribut:7,distutil:12,divisionoper:4,dmap:3,dnode:3,doc:[8,12],document:12,doe:[3,7,8,10,12],domin:8,don:8,done:8,doubl:8,down:[4,10],download:8,dreqpi:8,dsdict:2,dtype:[2,3,10],dump:8,dure:[1,8,12],each:[1,2,3,6,8,10],earlier:[8,12],easi:8,easiest:8,easili:[8,12],edg:[1,3,10],edu:[8,11,12],effect:3,effici:[3,8],either:[2,8],element:9,elimin:3,employ:7,enabl:3,enable_histori:3,enhanc:7,enough:8,enter:12,entir:[8,12],entiti:7,entitl:7,environ:[7,8],environment:7,equal:[8,10],equit:7,equival:8,error:[3,8,10],etc:1,evalnod:3,evalu:3,even:7,event:7,everi:8,everyon:12,exampl:[0,6,8,12],except:[1,2,3,10],exclus:7,execut:[1,3,8],exist:[2,8,12],expand:8,experi:0,explicitli:8,express:[2,6,7],extens:8,extern:[1,8],extract:8,fact:8,factor:8,factori:8,fail:7,failur:[7,8],fals:[1,2,8],fastest:[1,3],fault:7,featur:[0,8],feel:8,few:8,fewer:8,field:8,file:[0,1,2,3,4,6,7,8,9,10,11,12],filedesc:[2,3],filenam:[2,8],fill:8,find:[4,8],find_funct:4,find_oper:4,first:[1,2,3,6,8],fit:[7,8],fix:[7,8],flag:8,flexibl:8,flip:10,float32:[],flow:[1,3,10],flownod:11,follow:[2,8],forc:8,format:[2,7,8,12],found:[1,2,8,12],free:7,freeli:7,frequenc:8,from:[1,2,3,5,6,7,10],full:8,func:[3,4],functionbas:4,functionevalu:4,gener:[0,1,6],get:[8,10],getdata:10,getdimens:10,getdtyp:10,getmask:10,getnam:10,getposit:10,getshap:10,getunit:10,git:[8,12],github:[8,12],give:6,given:[1,3,6,8,10],glob:8,global:2,govern:7,grant:7,graph:[0,1,3,9,10],greater:8,greatli:8,hand:8,handi:12,handl:8,hard:8,has:[7,8,12],have:[2,3,6,8,12],hazard:7,head:8,header:2,help:8,henc:[2,8],herebi:7,hereund:7,high:7,highest:8,histori:[1,3,8],home:[8,12],how:[2,5,12],howev:[2,3,7,8,12],html:[8,12],http:[8,12],idl:8,idx:6,impact:8,impli:[7,8,12],implic:8,improv:[0,7,8],inadequ:7,incident:7,includ:[0,1,3,7,8,12],inclus:7,incorpor:7,increas:8,increasingli:8,incur:7,independ:[7,8],index1:6,index2:6,index:[1,3,5,8,11,12],index_exp:6,index_str:6,index_tupl:6,indic:[1,2,6,8,10],indirect:7,individu:7,ineffici:3,infil:8,infile1:8,infile2:8,inform:[2,7,8],infring:7,initi:[0,3],injuri:7,inpd:1,input:[1,2,3,8],input_file_list:8,inputdatasetdesc:2,insid:8,instal:5,instanc:8,instanti:8,instead:[2,8],institut:7,instruct:5,integ:8,intellectu:7,intend:7,intens:8,intention:7,interact:8,intercomparison:8,interest:7,interfac:[0,1,2,3,8],intern:[1,8],interpret:0,invari:8,invert:10,invest:6,involv:[10,12],irrepar:7,irrevoc:7,is_const:4,is_set:2,ischartyp:10,issu:12,item:3,iter:3,iter_bf:3,iter_df:3,its:[0,2,3,8,10],itself:[3,8],job:8,join:6,json:0,just:8,kei:[1,4,6],kevin:[11,12],kind:[2,7,10],know:8,known:12,kpaul:[11,12],kwd:[3,4,10],label:3,laboratori:7,larg:[6,8],largest:8,last:[1,3,8],lat:8,later:8,launch:8,launcher:8,law:7,lead:7,leav:8,left:[4,8],legal:7,length:[2,8],less:8,level:[1,2,3,8],liabil:7,liabl:7,lib:[8,12],librari:8,licens:[0,1,2,3,4,5,6,9,10,11,12],license:7,light:8,like:[1,3,6,8,12],limit:[2,4,6,7,8],limitfunct:4,link:[8,12],linux:[8,12],list:[2,8],list_funct:4,list_oper:4,littl:8,load:[8,12],local:[8,12],locat:12,lon:8,look:12,lost:7,lsf:8,machin:12,made:[3,8,12],mai:[3,7,8,12],main:12,major:[0,12],make:[7,8,12],manag:1,mani:[0,8],manual:5,manufactur:7,map:[0,1,2,3],mapnod:3,mark:8,mask:10,maskedarrai:10,match:[3,8],mathemat:2,max_mean_ab:3,maximum:[3,8],mean:[3,4,7,8,10],meanfunct:4,meet:3,memori:[3,6],mention:8,merchant:7,meta1d:8,metadata:[2,8],metavar:2,method:[3,6],mickelso:[11,12],mickelson:[11,12],might:[2,8,12],min_mean_ab:3,minim:2,minimum:3,mip_table_pars:0,mode:[8,12],model:8,modif:7,modifi:7,modul:[1,3,5,6,8,9,10],more:[0,2,8,12],most:[6,8,12],mpi4pi:8,mpi:[8,12],mpirun:8,much:8,multi:2,multicor:8,multipl:[2,3,6,8],multipli:[8,10],multiplicationoper:4,must:[2,3,7,8,12],name:[1,2,3,6,8,10],navig:7,ncar:[7,8,12],ncformat:8,ndarrai:[1,10],ndim:6,necesari:10,necessari:[8,9,10],need:[1,2,3,6,8,12],negationoper:4,neighbor:3,nest:2,netcdf3:8,netcdf3_64bit_data:2,netcdf3_64bit_offset:2,netcdf3_class:2,netcdf4:[2,8,12],netcdf4_class:2,netcdf4c:8,netcdf:[2,3,6,7,8,11,12],netcdf_format:8,newlen:10,newli:[8,12],next:8,nio:8,node:[1,3],nomin:8,non:[3,7,8],noncommerci:7,none:[1,2,3,4,8,10],nonexclus:7,noninfring:7,nontransfer:7,normal:8,notat:8,note:[7,8],noth:[6,10],notic:7,nuclear:7,numarg:4,number:[3,6,8],numer:[2,8],numpi:[1,2,6,8,10,12],obj:10,object:[0,1,2,3,4,6,9,10],oblig:7,obtain:5,obviou:2,obvious:8,occur:12,occurr:8,old:8,onc:[3,8,12],one:[1,2,8],onli:[3,7,8,10,12],open:8,oper:[1,3,4,6,7,8,9],option:[2,8,12],order:[1,3,8,10],ordereddict:[1,2,3,8],origin:[6,7],other:[0,2,3,7,8],otherwis:2,our:[6,8],out:[8,12],outd:1,outfile_prefix:8,output:[1,2,3,8],output_file_prefix:8,output_file_suffix:8,output_limit:8,output_prefix:8,output_suffix:8,outputdatasetdesc:2,over:8,overlap:8,overload:8,overrid:[1,3],overridden:8,overrun:6,overview:5,overwrit:[3,8],own:[7,8],owner:7,ownership:7,packag:[5,8],page:[5,12],parallel:[0,1,8],paramet:[1,2,3,6,8,10],pars:11,parse_definit:9,parsedbinop:9,parsedfunct:9,parseduniop:9,parsedvari:9,part:8,parti:[7,8],particular:7,pass:[8,10],patch:7,path:[8,12],pattern:8,paul:[11,12],per:8,perform:[1,7],permiss:[8,12],perpetu:7,person:7,pertain:8,physarrai:[0,3,11],physic:[7,10],pickl:8,pip:[8,12],place:[0,8,12],plant:7,pleas:12,point:[3,8,12],posit:10,positivedownfunct:4,positiveupfunct:4,possibl:[3,6,7,8],power:[0,7],poweroper:4,pre:0,precis:8,prefix:[8,12],present:[6,8],preserv:[1,3],prevent:8,previou:8,primari:10,print:8,print_diagnost:8,privat:8,problem:[6,12],process:8,processor:8,produc:8,product:5,profit:7,programm:6,project:8,properti:[3,7],proprietari:7,provid:[7,8],pull:12,purpos:[7,8],pyconform:7,pynio:8,pypars:8,pypi:8,pyreshap:12,python2:[8,12],python:[6,12],pythonpath:[8,12],question:[11,12],quotat:8,rang:8,rank:8,rather:3,rcp4_5:0,read:[1,2,3,6,8,12],readi:8,readm:8,readnod:3,reason:3,recent:[8,12],recipi:7,recogn:9,reduc:[6,8],reduct:6,refactor:0,refdat:4,refer:[2,3,8],referenc:3,regard:[7,8],regist:3,relat:7,releas:0,relief:7,remedi:7,remov:7,renam:3,repositori:0,repres:[1,2,3,7,8],represent:[6,7],reproduc:7,reproduct:7,request:[1,8,12],requir:[7,12],research:[0,1,2,3,4,5,6,9,10,11,12],reshap:8,respect:[7,8],restrict:7,restructuredtext:8,result:[3,6,7,12],retain:7,retriev:[2,3,10],revenu:7,right:[4,7],rigidli:12,risk:7,root:8,roughli:8,royalti:7,rshpr:8,rst:[0,1,2,3,4,6,8,9,10,11,12],rule:8,run:[1,8,12],s2s:8,s_b:8,safe:7,safeti:8,sake:8,sale:7,same:[2,8],sampl:8,satur:8,save:8,scale:8,scomm:1,script:12,search:[3,5],second:6,section:[2,8,12],see:[0,1,2,3,4,6,8,9,10,11,12],select:12,self:2,sell:7,send:[11,12],sent:3,separ:8,sequenc:8,seri:8,serial:[0,1,8],session:8,set:[2,3,7,8,10],setup:[8,12],setuptool:[8,12],sever:7,shall:7,shape0:6,shape:[6,10],shell:8,sheri:[11,12],should:[2,3,8,12],show:8,shown:8,signatur:3,similar:8,similarli:8,simpl:[2,8,12],simplecomm:[0,1,8],simplest:2,simpli:8,simplif:0,simplifi:0,simul:8,simultan:8,sinc:[8,12],singl:[2,6,8],sink:3,site:[8,12],size:[1,2,3,8],skip:8,slice12:6,slice1:6,slice2:6,slice:[3,6,8],slowest:[1,3],softwar:8,some:1,sort:1,sourc:[1,2,3,4,5,6,8,9,10],space:8,span:[2,8],spec:8,special:[3,7,10],specif:[7,8],specifi:2,speed:8,sphinx:[8,12],sqrt:4,squarerootfunct:4,src:0,stabl:[8,12],standard:[2,7,8,12],start:3,state:7,statement:6,statu:2,stdout:8,step:8,stop:8,storag:6,store:[3,6],stream:8,stretch:10,strexpr:9,string:[2,6,8,9,10],stringlen:2,structur:0,subclass:10,sublicens:7,submiss:8,submit:[7,12],submodul:[],subset:[2,8],subtract:1,subtractionoper:4,suffici:8,suffix:8,suitabl:12,sum:[3,10],sumlike_dimens:[3,4],suppli:[3,7],sure:[8,12],svn:12,synopt:8,system:[7,8,12],tabl:0,tag:12,take:[3,8],technolog:7,templat:0,term:[2,8],test:[0,8,12],text:8,than:8,thei:[2,6,8],them:8,therefor:[8,12],thereof:7,thi:[1,2,3,6,7,8,9,10,12],thing:8,third:[7,8],thorough:8,though:[8,12],through:[3,7],throughout:8,thu:8,time:[3,6,8],time_bound:8,time_seri:8,time_series_filenam:8,time_variant_metadata:8,titl:7,token:9,told:6,toler:7,too:8,tool:[7,8],top:8,tort:7,total:8,traffic:7,transfer:7,transform:[7,8,12],transmit:1,transpos:[1,10],treat:8,tseri:8,tupl:[2,3,6,10],two:6,type:[2,3,8,9,10,12],typic:[8,12],ucar:[7,8,11,12],udunits2:8,unari:9,understand:8,unfortun:8,uniqu:2,unit:[0,1,2,3,4,7,10],unitserror:10,unitswarn:3,univers:[0,1,2,3,4,5,6,9,10,11,12],unix:12,unless:8,unlik:2,unlimit:[2,8],unset:2,until:1,untransform:8,updat:12,upgrad:7,upon:[2,7,8,12],usag:12,use:[1,3,5,7,12],used:[0,2,8,9,12],useful:8,user:[0,3,5,12],uses:8,using:[2,3,8,12],usr:12,usual:8,util:8,valid:[3,8],valid_max:3,valid_min:3,validatenod:3,validationwarn:3,valu:[1,3,8,10],valueerror:[1,10],vari:[1,3,8],variabl:[0,1,2,3,8,9],variable_nam:8,variabledesc:2,variablenotfounderror:1,variant:8,variou:8,vebos:8,verbos:8,veri:[8,12],version:[5,8,12],via:[1,12],view:[2,6],viewer:8,vname:8,wai:[6,8],want:[8,12],warn:[2,3],warranti:7,weapon:7,weight:8,welcom:12,well:[6,8],what:5,when:[3,8],where:[1,2,3,6,8,12],whether:[1,2,7,8,10],which:[2,6,7,8,10,12],wide:8,wildcard:8,wish:[3,8],within:0,without:[7,8,12],wmode:8,word:8,work:[0,6,7,8,12],workspac:8,worldwid:7,worth:6,would:8,write:[1,2,3,8,12],write_mod:8,writenod:3,written:[2,8],yellowston:8,you:[3,7,8,12],your:[7,8,12]},titles:["PyConform ChangeLog","pyconform.dataflow","pyconform.datasets","pyconform.flownodes","pyconform.functions","Welcome to the PyConform documentation!","pyconform.indexing","Product License","The PyConform User\u2019s Manual","pyconform.parsing","pyconform.physarray","The PyConform Package","PyConform"],titleterms:{"function":[4,8],FOR:7,The:[8,11],Use:12,Using:[8,12],agreement:7,api:8,argument:8,atmospher:7,attribut:8,befor:[8,12],best:8,build:12,can:8,changelog:0,code:12,command:8,concept:8,contributor:7,convert:8,corpor:7,create_reshap:8,dataflow:1,dataset:2,depend:12,document:[5,8],flownod:3,from:[8,12],gener:8,how:8,index:6,indic:5,instal:[8,12],instruct:12,licens:7,line:8,manual:8,memori:8,method:8,modul:11,node:8,object:8,obtain:[8,12],overview:12,packag:[11,12],pars:9,perform:8,physarrai:10,product:7,pyconform:[0,1,2,3,4,5,6,8,9,10,11,12],pyreshap:8,python:8,requir:8,research:7,s2smake:8,s2srun:8,script:8,share:8,some:8,sourc:12,specfil:8,specifi:8,submodul:[],tabl:5,univers:7,unix:8,use:8,user:8,version:0,welcom:5,what:8,within:8}}) \ No newline at end of file diff --git a/docs/sphinx/manual.rst b/docs/sphinx/manual.rst index 94e012af..b92cc400 100644 --- a/docs/sphinx/manual.rst +++ b/docs/sphinx/manual.rst @@ -23,673 +23,7 @@ PyConform explicitly depends upon the following Python packages: These packages imply a dependency on the NumPy (v1.4+) and mpi4py (v1.3+) packages, and the libraries NetCDF, MPI/MPI-2, and UDUNITS2.. -If using Python version 2.6, you will need to install the ``ordereddict`` -package, too. - No thorough testing has been done to show whether earlier versions of these dependencies will work with the PyReshaper. The versions listed have been shown to work, and it is assumed that later versions will continue to work. - -How can I install it? -===================== - -The easiest way of obtaining the PyReshaper is from the Python Package -Index (PyPI), using ``pip``: - -:: - - $ pip install [--user] PyReshaper - -Alternatively, you can download the source from GitHub and install with -``setuptools``: - -:: - - $ git clone https://github.com/NCAR/PyReshaper - $ cd PyReshaper - $ python setup.py install [--user] - -This will download and install the most recent stable version of the source -code. If the most recent version of the non-stable source is desired, you -may switch to the development branch before installing. - -:: - - $ git checkout devel - -When installing, the ``--user`` option to either ``pip`` or ``setup.py`` -will install the PyReshaper in the user's private workspace, as defined -by the system on which the user is installing. This is useful if you don't -have permissions to install system-wide software. - -Generating the API Documentation --------------------------------- - -If you are a developer, you may find the Sphinx API documentation helpful -in understanding the design and functionality of the PyReshaper code. To -generate this documentation, you must have Sphinx available and installed. -If you do, the API documentation can be easily generated with the following -command from the ``docs`` directory. - -:: - - $ make html - -The API documentation will be placed in the ``docs/build/html/`` directory. - -Generating the User Documentation ---------------------------------- - -The ``README.rst`` file and this User Manual should be consulted for help -on installing and using the software. Both documents are included with -the source. The ``README.rst`` file is included with the top-level -PyReshaper directory, and the User Manual is contained in the -``docs/source/manual.rst`` file. Both files are reStructuredText formatted -files, meaning they are simple text files that can be read with any text -viewer. - -An HTML version of the User Manual will automatically be created by -Sphinx, as described in the previous section. A link will be created -to the manual in the HTML documentation. - -Before Using the PyReshaper ---------------------------- - -If you installed the PyReshaper using ``pip``, then you should be ready to -go. However, if you using the ``--user`` option, the local install directories -using by ``pip`` may not be in your paths. - -First, you must add the installation site-packages directory to your -``PYTHONPATH``. If you installed with the ``--user`` option, this means -adding the ``$HOME/.local/lib/python2.X/site-packages`` (on Linux) directory -to your ``PYTHONPATH``. If you specified a different ``--prefix`` option, -then you must point to that prefix directory. For bash users, this is -done with the following command. - -:: - - $ export PYTHONPATH=$PYTHONPATH:$PREFIX/lib/python2.X/site-packages - -where the ``$PREFIX`` is the root installation directory used when -installing the PyReshaper package (``$HOME/.local/`` if using the -``--user`` option on Linux), and the value of ``X`` will correspond to the -version of Python used to install the PyReshaper package. - -If you want to use the command-line interface to the PyReshaper, you -must also add the PyReshaper executables directory to your ``PATH``. -Like for the ``PYTHONPATH``, this can be done with the following -command. - -:: - - $ export PATH=$PATH:$PREFIX/bin - -How do I use it? -================ - -Some General Concepts ---------------------- - -Before we describe the various ways you can use the PyReshaper, we must -describe more about what, precisely, the PyReshaper is designed to do. - -As we've already mentioned, the PyReshaper is designed to convert a set -of NetCDF files from time-slice (i.e., synoptic or history-file) format -to time-series (or single-field) format, either in serial or parallel. -Time-slice files contain all of the model variables in one file, but typically -only span 1 or a few time-steps per file. Time-series files nominally contain -only 1 single time-dependent variable spanning many time-steps, but they -can additionally contain metadata used to describe the single-field variable -contained by the file. - -In serial, the PyReshaper will write each time-series variable to its own -file in sequence. In parallel, time-series variables will be -written simultaneously across the MPI processes allocated for the job. - -There are a number of assumptions that the PyReshaper makes regarding the -time-slice (input) data, which we list below. - -1. Each time-slice NetCDF file has multiple time-dependent variables - inside it, but can have many time-independent variables inside it, as - well. -2. Each time-slice NetCDF file contains data for times that do not - overlap with each other. (That is, each time-slice NetCDF file can - contain data spanning a number of simulation time steps. However, the - span of time contained in one time slice cannot overlap the span of - time in another time-slice.) If the time-slices overlap, an error - will be given and execution will stop. -3. Every time-slice NetCDF file contains the same time-dependent - variables, just at differing times. - -Similarly, there are a number of assumptions made about the time-series -(output) data produced by the PyReshaper conversion process. The variables -written to the output data can be time-series variables or metadata -variables. Time-series variables are written to one output file only. -Metadata variables are written to all output files. - -1. By default, every time-dependent variable will be assumed to be a - time-series variable (i.e., written to its own time-series NetCDF file). -2. Every time-independent variable that appears in the time-slice files - will be assumed to be a metadata variable (i.e., written to every - time-series file). -3. Users can explicitly specify any number of time-dependent variables - as metadata variables (e.g., such as ``time`` itself). -4. Every time-series file written by the PyReshaper will span the total - range of time spanned by all time-slice files specified. -5. Every time-series file will be named with the same prefix and suffix, - according to the rule: - - time\_series\_filename = prefix + variable\_name + suffix - -where the variable\_name is the name of the time-series variable -associated with that time-series file. - -It is important to understand the implications of the last assumption on -the list above. Namely, it is important to note what this assumption -means in terms of NetCDF file-naming conventions. It is common for the -file-name to contain information that pertains to the time-sampling -frequency of the data in the file, or the range of time spanned by the -time-series file, or any number of other things. To conform to such -naming conventions, it may be required that the total set of time-slice -files that the user wishes to convert to time-series be given to the -PyReshaper in multiple subsets, running the PyReshaper independently on -each subset of time-slice files. Throughout this manual, we -will refer to such "subsets" as streams. As such, every single PyReshaper -operation is designed to act on a single stream. - -Using the PyReshaper from the Unix Command-Line ------------------------------------------------ - -While the most flexible way of using the PyReshaper is from within -Python, as described above, the easiest way to use the PyReshaper is usually -to run the PyReshaper command-line utilities. In this section, we describe -how to use the command-line utilities ``s2smake`` and ``s2srun``, which -provide command-line interfaces (CLI) to the PyReshaper. (These scripts -will be installed in the ``$PREFIX/bin`` directory, where ``PREFIX`` is the -installation root directory. If you installed PyReshaper with the ``--user`` -flag, you may need to add this directpry to your path.) - -The ``s2smake`` utility is designed to generate a Specifier object file -(*specfile*) that contains a specification of the PyReshaper job. -The ``s2srun`` utility is then used to run the PyReshaper with the newly -generated *specfile*. - -Below is an example of how to use the PyReshaper's ``s2smake`` utility, -with all options and parameters specified on the command line. - -:: - - $ s2smake \ - --netcdf_format="netcdf4" \ - --compression_level=1 \ - --output_prefix="/path/to/outfile_prefix." \ - --output_suffix=".000101-001012.nc" \ - -m "time" -m "time_bounds" \ - --specfile=example.s2s \ - /path/to/infiles/*.nc - -In this example, you will note that we have specified each -time-dependent metadata variable name with its own ``-m`` option. (In -this case, there are only 2, ``time`` and ``time_bounds``.) We have also -specified the list of input (time-slice) files using a wildcard, which -the Unix shell fills in with a list of all filenames that match this *glob* -*pattern*. In this case, we are specifying all files with the ``.nc`` file -extension in the directory ``/path/to/infiles``. These command-line options -and arguments specify all of the same input needed to run the PyReshaper. -Running this command will save this PyReshaper *specfile* in a file called -``example.s2s``. - -When using *glob patterns*, it is important to understand that the *shell* -expands these glob patterns out into the full list of matching filenames -*before* running the ``s2smake`` command. On many systems, the length of -a shell command is limited to a fixed number of characters, and it is possible -for the *glob pattern* to expand to a length that makes the command too long -for the shell to execute! If this is the case, you may contain your glob -pattern in quotation marks (i.e., ``"/path/to/infiles/*.nc"`` instead of -``/path/to/infiles/*.nc``). The ``s2smake`` command will then expand the -glob pattern internally, allowing you to avoid the command-line character -limit of the system. - -With the *specfile* created and saved using the ``s2smake`` utility, -we can run the PyReshaper with this *specfile* using the ``s2srun`` utility, -with all options and parameters specified on the command line. - -:: - - $ s2srun --serial --verbosity=2 example.s2s - -The example above shows the execution, in serial, of the PyReshaper job -specified by the ``example.s2s`` *specfile* with a verbosity -level of 2. - -For parallel operation, one must launch the ``s2srun`` script from -the appropriate MPI launcher. On the NCAR Yellowstone system -(``yellowstone.ucar.edu``), for example, this is done with the following -command. - -:: - - $ mpirun.lsf s2srun --verbosity=3 example.s2s - -In the above example, this will launch the ``s2srun`` script into -the MPI environment already created by either a request for an -interactive session or from an LSF submission script. - -Arguments to the ``s2smake`` Script -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The arguments to the ``s2smake`` utility are as follows. - -- ``--backend BACKEND`` (``-b BACKEND``): I/O backend to be used when - reading or writing from NetCDF files. The parameter ``BACKEND`` can be one - of ``'Nio'`` or ``'netCDF4'``, indicating PyNIO or netCDF4-python, respectively. - The default value is ``'netCDF4'``. - -- ``--compression_level C`` (``-c C``): NetCDF compression level, when using the - netcdf4 file format, where ``C`` is an integer between 0 and 9, with 0 indicating - no compression at all and 9 indicating the highest level of compression. The - default compression level is 1. - -- ``--netcdf_format NCFORMAT`` (``-f NCFORMAT``): NetCDF file format to be used - for all output files, where ``NCFORMAT`` can be ``'netcdf'``, ``'netcdf4'``, or - ``'netcdf4c'``, indicating NetCDF3 Classic format, NetCDF4 Classic format, or - NetCDF4 Classic format with forced compression level 1. The default file format - is ``'netcdf4'``. - -- ``--metadata VNAME`` (``-m VNAME``): Indicate that the variable ``VNAME`` should - be treated as metadata, and written to all output files. There may be more than - one ``--metadata`` (or ``-m``) options given, each one being added to a list. - -- ``--meta1d`` (``-1``): This flag forces all 1D time-variant variables to be treated - as metadata. These variables need not be added explicitly to the list of metadata - variables (i.e., with the ``--metadata`` or ``-m`` argument). These variables will - be added to the list when the PyReshaper runs. - -- ``--specfile SPECFILE`` (``-o SPECFILE``): The name of the *specfile* to write, - containing the specification of the PyReshaper job. The default *specfile* name - is ``'input.s2s'``. - -- ``--output_prefix PREFIX`` (``-p PREFIX``): A string specifying the prefix to be - given to all output filenames. The output file will be named according to the - rule: - - ``output_prefix + variable_name + output_suffix`` - - The default output filename prefix is ``'tseries.'``. - -- ``--output_suffix SUFFIX`` (``-s SUFFIX``): A string specifying the suffix to be - given to all output filenames. The output file will be named according to the - rule: - - ``output_prefix + variable_name + output_suffix`` - - The default output filename suffix is ``'.nc'``. - -- ``--time_series VNAME``: Indicate that only the named ``VNAME`` variables should - be treated as time-series variables and extracted into their own time-series files. - This option works like the ``--metadata`` option, in that multiple occurrences of - this option can be used to extract out only the time-series variables given. If - any variable names are given to both the ``--metadata`` and ``--time_series`` - options, then the variable will be treated as metadata. If the ``--time_series`` - option is *not* used, then all time-dependent variables that are not specified to - be metadata (i.e., with the ``--metadata`` option) will be treated as time-series - variables and given their own output file. **NOTE: If you use this option, data - can be left untransformed from time-slice to time-series output! DO NOT DELETE - YOUR OLD TIME-SLICE FILES!** - -Each input file should be listed in sequence, space separated, on the command line to -the utility, nominally after all other options have been specified. - - -Arguments to the ``s2srun`` Script -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -While the basic options shown in the previous examples above are -sufficient for most purposes, additional options are available. - -- ``--chunk NAME,SIZE`` (``-c NAME,SIZE``): This command-line option can be used - to specify a maximum read/write chunk-size ``SIZE`` along a given named dimension - ``NAME``. Multiple ``--chunk`` options can be given to specify chunk-sizes along - multiple dimensions. This option determines the size of the data "chunk" read - from a single input file (and then written to an output file). If the chunk-size - is greater than the given dimension size, then the entire dimension will be read - at once. If the chunk-size is less than the given dimension size, then all variables - that depend on that dimension will be read in multiple parts, each "chunk" being written - before the next is read. This can be important to control memory use. By default, - chunking is done over the unlimited dimension with a chunk-size of 1. - -- ``--limit L`` (``-l L``): This command-line option can be used to set the - ``output_limit`` argument of the PyReshaper ``convert()`` function, - described below. This can be used when testing to only output the first ``L`` - files. The default value is 0, which indicates no limit (normal operation). - -- ``--write_mode M`` (``-m M``): This command-line option can be used to set - the ``wmode`` output file write-mode parameter of the ``create_reshaper()`` - function, described below. The default write mode is ``'w'``, which indicates - normal writing, which will error if the output files already exists (i.e., - no overwriting). Other options are ``'o'`` to overwrite existing output files, - ``'s'`` to skip existing output files, ``'a'`` to append to existing output - files. - -- ``--serial`` (``-s``): If this flag is used, it will run the PyReshaper in - serial mode. By default, it will run PyReshaper in parallel mode. - -- ``--verbosity V`` (``-v V``): Sets the verbosity level for standard output - from the PyReshaper. A level of 0 means no output, and a value of 1 or more - means increasingly more output. The default verbosity level is 1. - -Nominally, the last argument given to the ``s2srun`` utility should be the name -of the *specfile* to run. - - -Using the PyReshaper from within Python ---------------------------------------- - -Obviously, one of the advantages of writing the PyReshaper in Python is -that it is easy to import features (modules) of the PyReshaper into your -own Python code, as you might link your own software tools to an -external third-party library. The library API for the PyReshaper is -designed to be simple and light-weight, making it easy to use in your -own Python tools or scripts. - -Below, we show an example of how to use the PyReshaper from within -Python to convert a stream from time-slice format to time-series -format. - -.. code:: py - - from pyreshaper import specification, reshaper - - # Create a Specifier object - specifier = specification.create_specifier() - - # Specify the input needed to perform the PyReshaper conversion - specifier.input_file_list = [ "/path/to/infile1.nc", "/path/to/infile2.nc", ...] - specifier.netcdf_format = "netcdf4" - specifier.compression_level = 1 - specifier.output_file_prefix = "/path/to/outfile_prefix." - specifier.output_file_suffix = ".000101-001012.nc" - specifier.time_variant_metadata = ["time", "time_bounds"] - - # Create the PyReshaper object - rshpr = reshaper.create_reshaper(specifier, - serial=False, - verbosity=1, - wmode='s') - - # Run the conversion (slice-to-series) process - rshpr.convert() - - # Print timing diagnostics - rshpr.print_diagnostics() - -In the above example, it is important to understand the input given to -the PyReshaper. Namely, all of the input for this single stream is -contained by a single instantiation of a Specifier object (the code for -which is defined in the specification module). We will describe each -attribute of the Specifier object below. - -Specifier Object Attributes -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- ``input_file_list``: This specifies a list of input (time-slice) file - paths that all conform to the input file assumptions (described - above). The list of input files need not be time-ordered, as the - PyReshaper will order them appropriately. (This means that this list - can easily be generated by using filename globs.) - -In the example above, each file path is full and absolute, for safety's -sake. - -- ``netcdf_format``: This is a string specifying what NetCDF format - will be used to write the output (time-series) files. Acceptable options - for ``netcdf_format`` are: ``"netcdf"`` for NetCDF3 format, ``"netcdf4"`` - for NetCDF4 Classic format, and ``"netcdf4c"`` for NetCDF4 Classic with - level-1 compression. - -- ``compression_level``: This is an integer specifying the level of - compression to use when writing the output files. This can be a number - from 0 to 9, where 0 means no compression (default) and 9 mean the - highest level of compression. This is overridden when the ``"netcdf4c"`` - format is used, where it is forced to be 1. - -In the above example, NetCDF4 Classic format is used for the output files, -with level-1 compression. The ``"netcdf4c"`` option can be used as a -short-hand notation for this combination of ``netcdf_format`` and -``compression_level`` options. - -- ``output_file_prefix``: This is a string specifying the common output - (time-series) filename prefix. It is assumed that each time-series - file will be named according to the rule: - - filename = output\_file\_prefix + variable\_name + output\_file\_suffix - -- ``output_file_suffix``: This is a string specifying the common output - (time-series) filename suffix. It is assumed that each time-series - file will be named according to the above rule. - -It is important to understand, as in the example above, that the prefix -can include the full, absolute path information for the output -(time-series) files. - -- ``time_variant_metadata``: This specifies a list of variable names - corresponding to variables that should be written to every output - (time-series) NetCDF file. Nominally, this should specify only the - time-variant (time-dependent) variables that should *not* be treated - as time-series variables (i.e., treated as metadata), since all - time-invariant (time-independent) variables will be treat as metadata - automatically. - -- ``assume_1d_time_variant_metadata``: If set to ``True``, this indicates - that all 1D time-variant variables (i.e., variables that *only* depend - upon ``time``) should be added to the list of ``time_variant_metadata`` - when the Reshaper runs. The default for this option is ``False``. - -- ``time_series``: If set to a list of string variable names, only these - variable names will be transformed into time-series format. This is - equivalent to the ``--time_series`` option to the ``s2smake`` utility. - **NOTE: Setting this attribute can leave data untransformed from time-slice - to time-series format! DO NOT DELETE YOUR OLD TIME-SLICE FILES!** - -- ``backend``: This specifies which I/O backend to use for reading - and writing NetCDF files. The default backend is ``'netCDF4'``, but - the user can alternatively specify ``'Nio'`` to use PyNIO. - -Specifier Object Methods -~~~~~~~~~~~~~~~~~~~~~~~~ - -In addition to the attributes above, the Specifier objects have some useful -methods that can be called. - -- ``validate()``: Calling this function validates the attributes of the - Specifier, making sure their types and values appear correct. - -- ``write(filename)``: Calling this function with the argument ``filename`` - will write the *specfile* matching the Specifier. - - -Specfiles -~~~~~~~~~ - -*Specfiles* are simply *pickled* Specifier objects written to a file. To -create a *specfile*, one can simply call the Specifier's ``write()`` method, -described above, or one can explicitly *pickle* the Specifier directly, as -shown below. - -.. code:: py - - import pickle - - # Assume "spec" is an existing Specifier instance - pickle.dump(spec, open("specfile.s2s", "wb")) - -This is equivalent to the call ``spec.write('specfile.s2s')``. - -A *specfile* can be read with the following Python code. - -.. code:: py - - import pickle - - spec = pickle.load( open("specfile.s2s", "rb") ) - - -Arguments to the ``create_reshaper()`` Function -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In the example above, the PyReshaper object (rshpr) is created by -passing the single Specifier instance to the *factory* function -``create_reshaper()``. This function returns a PyReshaper object that has -the functions ``convert()`` and ``print_diagnostics()`` that perform the -time-slice to time-series conversion step and print useful timing -diagnostics, respectively. - -In addition to the Specifier instance, the ``create_reshaper()`` function -takes the following parameters. - -- ``serial``: This is a boolean flag, which can be ``True`` or ``False``, - indicating whether the PyReshaper ``convert()`` step should be done in serial - (``True``) or parallel (``False``). By default, parallel operation is - assumed if this parameter is not specified. - -- ``verbosity``: This is an integer parameter that specifies what level of - output to produce (to ``stdout``) during the ``convert()`` step. A - verbosity level of ``0`` means that no output will be produced, while an - increasing vebosity level producing more and more output. Currently, a - level of ``2`` produces the most output possible. - - 1. ``verbosity = 0``: This means that no output will be produced unless - specifically requested (i.e., by calling the ``print_diagnostics()`` - function). - 2. ``verbosity = 1``: This means that only output that would be produced - by the head rank of a parallel process will be generated. - 3. ``verbosity = 2``: This means that all output from all processors - will be generated, but any output that is the same on all processors - will only be generated once. - -- ``wmode``: This is a single-character string that can be used to set the - *write mode* of the PyReshaper. By default, the PyReshaper will not overwrite - existing output files, if they exist. In normal operation, this means the - PyReshaper will error (and stop execution) if output files are already - present. This behavior can be controlled with the ``wmode`` parameter. - The ``wmode`` parameter can be set to any of the following. - - 1. ``wmode = 'w'``: This indicates that normal write operation is to be - performed. That is, the PyReshaper will error and stop execution if it - finds output files that already exist. This is the default setting. - 2. ``wmode = 's'``: This indicates that the PyReshaper should skip generating - time-series files for output files that already exist. No check is - done to see if the output files are correct. - 3. ``wmode = 'o'``: This indicates that the PyReshaper should overwrite - existing output files, if present. In this mode, the existing output - files will be deleted before running the PyReshaper operation. - 4. ``wmode = 'a'``: This indicates that the PyReshaper should append to - existing output files, if present. In this mode, it is assumed that the - existing output files have the correct format before appending new data - to them. - -- ``simplecomm``: This option allows the user to pass an ``ASAPPyTools`` - ``SimpleComm`` instance to the PyReshaper, instead of having the PyReshaper - create its own internally. The ``SimpleComm`` object is the simple MPI - communication object used by the PyReshaper to handle its MPI communication. - By default, the PyReshaper will create its own SimpleComm that uses the - MPI ``COMM_WORLD`` communicator for communication. However, the user - may create their own ``SimpleComm`` object and force the PyReshaper to use - it by setting this option equal to the user-created ``SimpleComm`` instance. - - -Arguments to the ``convert()`` Function -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -While not shown in the above examples, there are named arguments that can -be passed to the ``convert()`` function of the Reshaper object. - -- ``output_limit``: This argument sets an integer limit on the number of - time-series files generated during the ``convert()`` operation (per MPI process). - This can be useful for debugging purposes, as it can greatly reduce the length - of time consumed in the ``convert()`` function. A value of ``0`` indicates - no limit, or all output files will be generated. - -- ``chunks``: This argument sets a dictionary of dimension names to chunk-sizes. - This is equivalent to the ``--chunk`` command-line option to ``s2srun``. This option - determines the size of the data "chunk" read from a single input file (and then written - to an output file) along each given dimension. If a chunk-size is greater than the given - dimension size, then the entire dimension will be read at once. If a chunk-size is less - than the given dimension size, then all variables that depend on that dimension will be - read in multiple parts, each "chunk" being written before the next is read. This can be - important to control memory use. By default, the ``chunks`` parameter is equal to - ``None``, which means chunking is done over the unlimited dimension with a chunk-size of 1. - - -Obtaining Best Performance with the PyReshaper ----------------------------------------------- - -While the PyReshaper can be run in either serial or parallel, best performance -is almost always achieved by running in parallel. Understanding how the -PyReshaper operates, however, is important to knowing how to get the best -performance. - -Of critical importance to understanding this, one must appreciate the fact that -the PyReshaper only parallelizes over *time-series* (output) variables. Or, -in other words, it parallelizes over output files, since each time-series -variable is written to its own file. Thus, the maximum amount of parallelism -in the PyReshaper equal to the number of time-series variables in the input -dataset. If 10 time-series variables exist in the input dataset, then the -maximum performance will be achieved by running the job with 10 MPI processes. - -Unfortunately, that is not all that needs to be appreciated, because there are -many factors that can impact performance. - -Shared Memory -~~~~~~~~~~~~~ - -On many parallel systems, with well-scaling parallel software, *compute* -performance scales with the number of MPI processes, where each process is -executed on its own CPU core. Multicore CPUs, therefore, can run (efficiently) -as many MPI processes simultaneously as there are cores on the CPU. These -MPI processes will share the memory attached to the CPU, however, so -memory-intensive MPI processes may require leaving some cores idle on the -CPU in order to leave enough memory for the MPI processes to execute without -an out-of-memory failure. - -To best determine how much memory you need on a single MPI process, find the -largest time-series variable in the input dataset. This can usually be found -by multiplying the size of each dimension upon which the time-series variable -depends, and then multiplying by the byte-size of the variable's data type. -For example, a ``double`` time-series variable with the dimensions -``('time', 'lat', 'lon')``, would have a byte-size of the following. - -:: - - S_B('var') = S('time') * S('lat') * S('lon') * S_B('double') - -where ``S(d)`` represents the numeric size of dimension ``d``, and ``S_B(v)`` -represents the number of bytes of the variable ``v``. (The ``S_B('double')`` -is equal to 8 bytes, while ``S_B('float')`` is equal to 4 bytes.) If we -assume ``S('time') = 14600``, ``S('lat') = 180``, and ``S('lon') = 360``, then -``S_B('var') = 7`` GB. - -If you then run ``N`` MPI processes on each node, each MPI process has roughly -``1/N``th of the memory available to it, and this memory must be large enough -to contain the time-series variable. So, on a system with 16 cores per node, -and 64 GB per node, has only (on average) 4 GB per core. The above time-series -variable would not fit in only 4 GB, but it would fit in 8 GB, so we might use -only 8 of the 16 available cores per node in our PyReshaper run. - -I/O Nodes -~~~~~~~~~ - -Similar limitations usually apply to *I/O* (reading/writing data) operations, -of which the PyReshaper is one. The PyReshaper does very little computation -on the CPU, and almost all of its operation time is dominated by I/O. -Unfortunately, most systems have serial I/O from all MPI processes on the same -CPU (or *node*). Hence, while a multicore CPU can efficiently execute as many -MPI processes as cores on the CPU for *computation*, this may not be true for -I/O. To prevent overloading the node's I/O capabilities, it may be necessary -to run fewer PyReshaper processes *per node* than there are available cores. - -This is a parameter that is hard to get a feel for, so it is best to see how -performance varies on the system you are using. In general, though, using the -maximum number of processes per node will saturate the I/O capabilities of the -node, so using fewer processes per node may improve conversion speeds.