Example #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)
Example #2
0
def handler_app(environ, start_response):

    fields = parse_formvars(environ)
    if environ['REQUEST_METHOD'] == 'GET':

        try:
            if fields['SERVICE'] != 'WMS':
                raise

            try:
                FILE = fields['FILE']
            except:
                FILE = None
            try:
                COMMAND = fields['COMMAND']
            except:
                COMMAND = None
            try:
                VARIABLE = fields['VARIABLE'].replace('%2B', '+')
            except:
                VARIABLE = None
            try:
                PATTERN = fields['PATTERN']
            except:
                PATTERN = None

            #---------------------------------------------------------
            if fields['REQUEST'] == 'GetVariables':
                pyferret.run('use ' + FILE)
                varnamesdict = pyferret.getstrdata('..varnames')
                variables = varnamesdict['data'].flatten().tolist()

                #print(json.dumps(variables))
                start_response('200 OK',
                               [('content-type', 'application/javascript')])
                return iter('newVariables(' + json.dumps(variables) +
                            ')')  # return jsonp

            #---------------------------------------------------------
            elif fields['REQUEST'] == 'GetDatasets':
                tmpname = tempfile.NamedTemporaryFile(suffix='.txt').name
                tmpname = os.path.basename(tmpname)

                pyferret.run('set redirect /clobber /file="%s" stdout' %
                             (tmpdir + '/' + tmpname))
                pyferret.run('show data')
                pyferret.run('cancel redirect')

                if os.path.isfile(tmpdir + '/' + tmpname):
                    ftmp = open(tmpdir + '/' + tmpname, 'rb')
                    txt = ftmp.read()
                    ftmp.close()
                    os.remove(tmpdir + '/' + tmpname)

                print('GetDatasets: ', os.getpid())

                start_response('200 OK', [('content-type', 'text/plain')])
                return iter('displayDatasets(' +
                            json.dumps(str(os.getpid()) + '\n\n' + txt) + ')')

            #---------------------------------------------------------
            elif fields['REQUEST'] == 'GetColorBar':
                pyferret.run('use ' + FILE)
                tmpname = tempfile.NamedTemporaryFile(suffix='.png').name
                tmpname = os.path.basename(tmpname)

                pyferret.run('set window/aspect=1/outline=0')
                pyferret.run('go margins 2 4 3 3')
                pyferret.run(COMMAND + '/set_up ' + VARIABLE)
                pyferret.run(
                    'ppl shakey 1, 0, 0.15, , 3, 9, 1, `($vp_width)-1`, 1, 1.25 ; ppl shade'
                )
                pyferret.run(
                    'frame/format=PNG/transparent/xpixels=400/file="' +
                    tmpdir + '/key' + tmpname + '"')

                im = Image.open(tmpdir + '/key' + tmpname)
                box = (0, 325, 400, 375)
                area = im.crop(box)
                area.save(tmpdir + '/' + tmpname, "PNG")

            #---------------------------------------------------------
            elif fields['REQUEST'] == 'GetMap':
                pyferret.run('use ' + FILE)
                tmpname = tempfile.NamedTemporaryFile(suffix='.png').name
                tmpname = os.path.basename(tmpname)

                WIDTH = int(fields['WIDTH'])
                HEIGHT = int(fields['HEIGHT'])

                # BBOX=xmin,ymin,xmax,ymax
                BBOX = fields['BBOX'].split(',')

                HLIM = '/hlim=' + BBOX[0] + ':' + BBOX[2]
                VLIM = '/vlim=' + BBOX[1] + ':' + BBOX[3]

                print('GetMap: ', os.getpid())

                pyferret.run(
                    'set window/aspect=1/outline=5'
                )  # outline=5 is a strange setting but works otherwise get outline around polygons
                pyferret.run('go margins 0 0 0 0')
                pyferret.run(COMMAND + '/noaxis/nolab/nokey' + HLIM + VLIM +
                             ' ' + VARIABLE)
                pyferret.run('frame/format=PNG/transparent/xpixels=' +
                             str(WIDTH) + '/file="' + tmpdir + '/' + tmpname +
                             '"')

                if os.path.isfile(tmpdir + '/' + tmpname):
                    if PATTERN:
                        img = Image.open(tmpdir + '/' + tmpname)
                        pattern = Image.open(PATTERN)
                        img = Image.composite(img, pattern, pattern)
                        img.save(tmpdir + '/' + tmpname)

            #---------------------------------------------------------
            else:
                raise

            if os.path.isfile(tmpdir + '/' + tmpname):
                ftmp = open(tmpdir + '/' + tmpname, 'rb')
                img = ftmp.read()
                ftmp.close()
                os.remove(tmpdir + '/' + tmpname)

            start_response(
                '200 OK',
                [('content-type', 'image/png')])  # for GetColorBar and GetMap
            return iter(img)

        except:
            return iter('Exception caught')
Example #3
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)
Example #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 = { }

        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)