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)
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')
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)
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)