Пример #1
0
    def __init__(self, filename, title='', qual=''):
        '''
        "Opens" the given NetCDF dataset file in Ferret using the Ferret "USE" command.
        Creates a FerVar for each data variable in this data file and 
        assigns it as an attribute of this class using the variable name.
            filename (string): name of the dataset filename or http address
            title (string): title for the dataset for plots and listing;
                if not given, the Ferret name for the dataset will be used
            qual (string): Ferret qualifiers to be used with the "USE" command
        '''
        self._filename = ''
        self._dsetname = ''
        self._fervars = {}
        self._fervarnames = set()
        if not filename:
            if qual == _anonymous_dataset_qualifier:
                # initialize an new anonymous dataset that will either be
                # pyferret.anondset or will be modified by a subclass (FerAggDSet)
                return
            else:
                raise ValueError(
                    'pyferret.anondset should be used for the anonymous dataset'
                )

        # tell Ferret to open/use this dataset
        cmdstr = 'USE'
        if title:
            cmdstr += '/TITLE="' + str(title) + '"'
        if qual:
            cmdstr += str(qual)
        cmdstr += ' "' + str(filename) + '"'
        (errval, errmsg) = pyferret.run(cmdstr)
        if errval != pyferret.FERR_OK:
            raise ValueError(errmsg)

        # record the filename and Ferret dataset name
        self._filename = filename
        # need to use the filename as given as the dataset name to avoid possible abiguity
        self._dsetname = filename
        # create a FerVar for each variable in this dataset
        namesdict = pyferret.getstrdata('..varnames')
        for varname in namesdict['data'].flatten():
            if sys.version_info[0] > 2:
                # For Python3.x, namesdict['data'] is a NumPy array of bytes; convert to unicode
                varname = str(varname, 'UTF-8')
            # create a FerVar representing this existing Ferret file variable
            filevar = pyferret.FerVar()
            filevar._markasknownvar(varname, self._dsetname, True)
            # assign this FerVar - uppercase the variable name keys to make case-insensitive
            self._fervars[varname.upper()] = filevar
            # keep a original-case version of the name
            self._fervarnames.add(varname)
Пример #2
0
 def diagform(self):
     '''
     Returns an anonymous FerVar that is the transformation of this FerFMRCVar 
     to a "diagonal" form, where the T (time) axis is the date forecasted and 
     the F (forecast) axis is the date the forecast was made.
     '''
     if (not self._varname) or (not self._dsetname):
         raise ValueError('Invalid FerFMRCVar object')
     # TF_TIMES is an automatically generated variable for FMRC datasets in Ferret
     # TF_CAL_T is an automatically generated axis for FMRC datasets in Ferret
     diagdefn = '%s[gt(TF_TIMES)=TF_CAL_T]' % self._varname
     title = self._title + ' (diag form)'
     diagvar = pyferret.FerVar(defn=diagdefn, title=title)
     diagvar._requires.add(self._varname.upper())
     diagvar._requires.add("TF_TIMES")
     return diagvar
Пример #3
0
 def leadform(self):
     '''
     Returns an anonymous FerVar that is the transformation of this FerFMRCVar 
     to the "lead" form, where the T (time) axis is the date forecasted and 
     the F (forecast) axis is the lead time for the date forecasted (forecasted
     time minus time that the forecast was made).
     '''
     if (not self._varname) or (not self._dsetname):
         raise ValueError('Invalid FerFMRCVar object')
     # TF_TIMES is an automatically generated variable for FMRC datasets in Ferret
     # TF_CAL_T is an automatically generated axis for FMRC datasets in Ferret
     # TF_LAG_F is an automatically generated axis for FMRC datasets in Ferret
     leaddefn = '%s[gt(TF_TIMES)=TF_CAL_T,gf(TF_TIMES)=TF_LAG_F]' % self._varname
     title = self._title + ' (lead form)'
     leadvar = pyferret.FerVar(defn=leaddefn, title=title)
     leadvar._requires.add(self._varname.upper())
     leadvar._requires.add("TF_TIMES")
     return leadvar
Пример #4
0
    def __init__(self,
                 name,
                 dsets,
                 along='T',
                 title='',
                 warn=True,
                 hide=False):
        '''
        Aggregates the given list of datasets along the given axis using the 
        Ferret "DEFINE DATA /AGGREGATE" command.  Creates a FerVar for each data 
        variable in common among these datasets, and assigns it as an attribute 
        of this class instance using the variable name.  
            name (string): Ferret name for this aggregated dataset
            dsets (sequence of strings and/or FerDSets): datasets to aggregate.
                A string will be interpreted as a filename for creating a FerDSet.
            along ('T', 'E', 'F'): axis along which to aggregate the datasets
            title (string): title for the dataset for plots and listing;
                if not given, the Ferret name for the dataset will be used
            warn (bool): issue warning messages about variables not in common among
                all member datasets (either not present or not using the same grid)
            hide (bool): hide the member datasets in standard Ferret listings 
                such as with pyferret.showdata()
        '''
        # Create an empty dataset with the given Ferret name
        super(FerAggDSet, self).__init__('', qual=_anonymous_dataset_qualifier)
        if not isinstance(name, str):
            raise ValueError(
                'Ferret name for the aggregate dataset must be astring')
        aggname = name.strip()
        if not aggname:
            raise ValueError('Ferret name for the aggregate dataset is blank')
        self._filename = aggname
        self._dsetname = aggname
        # Need to keep the given order of component datasets
        self._compdsetnames = []
        # But still use a dictionary with uppercase names for keys
        self._compdsets = {}
        # Create the DEFINE DATA /AGGREGATE Ferret command, creating
        # and saving component FerDSets as needed
        if along not in ('T', 'E', 'F'):
            raise ValueError("along must be one of 'T', 'E', or 'F'")
        self._along = along
        self._comphidden = bool(hide)
        cmdstr = 'DEFINE DATA/AGGREGATE/' + self._along
        if title:
            cmdstr += '/TITLE="' + str(title) + '"'
        if not warn:
            cmdstr += '/QUIET'
        if self._comphidden:
            cmdstr += '/HIDE'
        cmdstr += ' ' + aggname + ' = '
        firstone = True
        if not (isinstance(dsets, tuple) or isinstance(dsets, list)):
            raise ValueError(
                'dsets must be a tuple or list of strings and/or FerDSets')
        for myitem in dsets:
            if isinstance(myitem, str):
                mydset = pyferret.FerDSet(myitem)
            elif isinstance(myitem, pyferret.FerDSet):
                mydset = myitem
            else:
                raise ValueError(
                    'dsets must be a tuple or list of strings and/or FerDSets')
            if mydset._dsetname.upper() in self._compdsets:
                raise ValueError('duplicate dataset name ' + mydset._dsetname)
            if not firstone:
                cmdstr += ', '
            else:
                firstone = False
            cmdstr += mydset._dsetname
            self._compdsetnames.append(mydset._dsetname)
            self._compdsets[mydset._dsetname.upper()] = mydset
        (errval, errmsg) = pyferret.run(cmdstr)
        if errval != pyferret.FERR_OK:
            raise ValueError(errmsg)

        # create a FerVar for each variable in this dataset
        namesdict = pyferret.getstrdata('..varnames')
        for varname in namesdict['data'].flatten():
            # create a FerVar representing this existing Ferret aggregated file variable
            filevar = pyferret.FerVar()
            filevar._markasknownvar(varname, self._dsetname, True)
            # assign this FerVar - uppercase the variable name keys to make case-insensitive
            self._fervars[varname.upper()] = filevar
            # keep a original-case version of the name
            self._fervarnames.add(varname)
Пример #5
0
    def __init__(self, name, dsets, along='T', title='', warn=True, hide=False):
        '''
        Aggregates the given list of datasets along the given axis using the 
        Ferret "DEFINE DATA /AGGREGATE" command.  Creates a FerVar for each data 
        variable in common among these datasets, and assigns it as an attribute 
        of this class instance using the variable name.  
            name (string): Ferret name for this aggregated dataset
            dsets (sequence of strings and/or FerDSets): datasets to aggregate.
                A string will be interpreted as a filename for creating a FerDSet.
            along ('T', 'E', 'F'): axis along which to aggregate the datasets
            title (string): title for the dataset for plots and listing;
                if not given, the Ferret name for the dataset will be used
            warn (bool): issue warning messages about variables not in common among
                all member datasets (either not present or not using the same grid)
            hide (bool): hide the member datasets in standard Ferret listings 
                such as with pyferret.showdata()
        '''
        # Create an empty dataset with the given Ferret name
        super(FerAggDSet, self).__init__('', qual=_anonymous_dataset_qualifier)
        if not isinstance(name, str):
            raise ValueError('Ferret name for the aggregate dataset must be astring')
        aggname = name.strip()
        if not aggname:
            raise ValueError('Ferret name for the aggregate dataset is blank')
        self._filename = aggname
        self._dsetname = aggname
        # Need to keep the given order of component datasets
        self._compdsetnames = [ ]
        # But still use a dictionary with uppercase names for keys
        self._compdsets = { }

        if along not in ('T', 'E', 'F'):
            raise ValueError("along must be one of 'T', 'E', or 'F'")
        self._along = along
        self._comphidden = bool(hide)

        # Create a Ferret string variable containing all the dataset names to be aggregated
        if not ( isinstance(dsets, tuple) or isinstance(dsets, list) ):
            raise ValueError('dsets must be a tuple or list of strings and/or FerDSets')
        filesfile = tempfile.NamedTemporaryFile(mode='w', delete=False, 
                                  prefix=aggname + '_', suffix='_agg.txt')
        filesfilename = filesfile.name
        deletefilesfile = True
        try:
            for myitem in dsets:
                if isinstance(myitem, str):
                    mydset = pyferret.FerDSet(myitem)
                elif isinstance(myitem, pyferret.FerDSet):
                    mydset = myitem
                else:
                    raise ValueError('dsets must be a tuple or list of strings and/or FerDSets')
                if mydset._dsetname.upper() in self._compdsets:
                    raise ValueError('duplicate dataset name ' + mydset._dsetname)
                print(mydset._dsetname, file=filesfile)
                self._compdsetnames.append(mydset._dsetname)
                self._compdsets[mydset._dsetname.upper()] = mydset
            deletefilesfile = False
        finally:
            filesfile.close()
            if deletefilesfile:
                os.unlink(filesfilename)
        filesvarname = aggname + "_datafile_names"
        cmdstr = 'LET ' + filesvarname + ' = SPAWN("cat \'' + filesfilename + '\'")'
        (errval, errmsg) = pyferret.run(cmdstr)
        if errval != pyferret.FERR_OK:
            os.unlink(filesfilename)
            raise ValueError(errmsg)
        # filesfile not read (SPAWN command executed) until filesvarname is needed

        # Create the DEFINE DATA /AGGREGATE Ferret command, creating
        # and saving component FerDSets as needed
        cmdstr = 'DEFINE DATA/AGGREGATE/' + self._along
        if title:
            cmdstr += '/TITLE="' + str(title) + '"'
        if not warn:
            cmdstr += '/QUIET'
        if self._comphidden:
            cmdstr += '/HIDE'
        cmdstr += ' ' + aggname + ' = ' + filesvarname
        (errval, errmsg) = pyferret.run(cmdstr)
        # filesfile now read so can delete it
        os.unlink(filesfilename)
        if errval != pyferret.FERR_OK:
            raise ValueError(errmsg)

        # create a FerVar for each variable in this dataset
        namesdict = pyferret.getstrdata('..varnames')
        for varname in namesdict['data'].flatten():
            if sys.version_info[0] > 2:
                # For Python3.x, namesdict['data'] is a NumPy array of bytes; convert to unicode
                varname = str(varname, 'UTF-8')
            # create a FerVar representing this existing Ferret aggregated file variable
            filevar = pyferret.FerVar()
            filevar._markasknownvar(varname, self._dsetname, True)
            # assign this FerVar - uppercase the variable name keys to make case-insensitive
            self._fervars[varname.upper()] = filevar
            # keep a original-case version of the name
            self._fervarnames.add(varname)