/usr/lib/python2.7/dist-packages/pyferret/ferdset.py is in python-ferret 7.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | '''
Represents a data set (file) and the data variables it contains.
'''
import sys
import pyferret
_anonymous_dataset_qualifier = '__new_anonymous_dataset__'
class FerDSet(object):
'''
A data set and the data variables it contains
'''
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 __repr__(self):
'''
Representation to recreate this FerDataSet.
Also includes the variable names as variables can be added after creation.
'''
infostr = "FerDSet('%s') with variables %s" % \
(self._filename, str(self.fernames(sort=True)))
return infostr
def __eq__(self, other):
'''
Two FerDSets are equal if their filenames, datasetnames, and
dictionary of FerVar variables are all equal. All string values
are compared case-insensitive.
'''
if not isinstance(other, FerDSet):
return NotImplemented
if self._filename.upper() != other._filename.upper():
return False
if self._dsetname.upper() != other._dsetname.upper():
return False
if self._fervars != other._fervars:
return False
return True
def __ne__(self, other):
'''
Two FerDSets are not equal if their filenames, datasetnames, or
dictionary of FerVar variables are not equal. All string values
are compared case-insensitive.
'''
if not isinstance(other, FerDSet):
return NotImplemented
return not self.__eq__(other)
def __len__(self):
'''
Returns the number of Ferret variables associated with this dataset
'''
return len(self._fervars)
def __getitem__(self, name):
'''
Return the Ferret variable (FerVar) with the given name.
'''
if not isinstance(name, str):
raise TypeError('name key is not a string')
return self._fervars[name.upper()]
def __setitem__(self, name, value):
'''
Creates a copy of value (FerVar), assigns it to Ferret identified by
name (string), and adds this copy to this dataset, identified by name.
'''
if not isinstance(name, str):
raise TypeError('name key is not a string')
if not isinstance(value, pyferret.FerVar):
raise TypeError('value to be assigned is not a FerVar')
if self._filename and not self._dsetname:
raise TypeError('this dataset has been closed')
# if this name is already assigned to a FerVar, first remove the
# Ferret definition that is going to be overwritten; otherwise,
# Python's delete of the item in garbage collection will wipe out
# the (possibly new) definition as some unknown time.
try:
self.__delitem__(name)
except Exception:
pass
# make an anonymous copy of the FerVar (or subclass - the copy
# method preserves the class type) and assign it in Ferret.
newvar = value.copy()
try:
newvar._assigninferret(name, self._dsetname)
except ValueError as ex:
raise TypeError(str(ex))
# add this FerVar to this dataset using the uppercase name
# to make names case-insenstive
self._fervars[name.upper()] = newvar
# keep a original-case version of the name
self._fervarnames.add(name)
def __delitem__(self, name):
'''
Removes (cancels) the Ferret variable identified by name (string)
and removes the FerVar from this dataset.
'''
if not isinstance(name, str):
raise TypeError('name key is not a string')
uppername = name.upper()
# let the following throw a KeyError if not found
value = self._fervars[uppername]
try:
value._removefromferret()
except ValueError as ex:
raise TypeError(str(ex))
del self._fervars[uppername]
origname = None
for myname in self._fervarnames:
if myname.upper() == uppername:
origname = myname
break
# should always be found at this point
if origname is None:
raise KeyError('unexpected unknown variable name ' + name)
self._fervarnames.remove(origname)
def __contains__(self, name):
'''
Returns whether the Ferret variable name (case insensitive) is in this dataset
'''
if not isinstance(name, str):
return False
return ( name.upper() in self._fervars )
def __iter__(self):
'''
Returns an iterator over the Ferret variable names (in their original case).
'''
return iter(self._fervarnames)
def __getattr__(self, name):
'''
Returns the Ferret variable (FerVar) with the given name (case insensitive).
Note that this method is only called when the parent object
does not have an attribute with this name.
'''
try:
return self.__getitem__(name)
except KeyError:
raise AttributeError('no attribute or FerVar with name %s' % name)
def __setattr__(self, name, value):
'''
If value is a FerVar, then creates a copy of this Ferret variable, assigns it
to Ferret identified by name (string), and adds it to this dataset identified
by name. If value is not a FerVar, passes this call onto the parent object.
'''
if isinstance(value, pyferret.FerVar):
try:
self.__setitem__(name, value)
except TypeError as ex:
raise AttributeError(str(ex))
else:
super(FerDSet, self).__setattr__(name, value)
def __delattr__(self, name):
'''
If name is associated with a FerVar, removes (cancels) the Ferret variable
identified by name (string) and removes the FerVar from this dataset.
If name is not associated with FerVar, passes this call onto the parent object.
'''
try:
self.__delitem__(name)
except TypeError as ex:
raise AttributeError(str(ex))
except KeyError:
try :
super(FerDSet, self).__delattr__(name)
except AttributeError:
raise AttributeError('no attribute or FerVar with name %s' % name)
def __dir__(self):
'''
Returns a list of attributes, include FerVar names, of this object.
Adds original-case, uppercase, and lowercase FerVar names.
'''
mydir = set( dir(super(FerDSet, self)) )
for name in self.fernames(sort=False):
mydir.add( name.upper() )
mydir.add( name.lower() )
return list(mydir)
def fernames(self, sort=False):
'''
Returns a list of the names (in their original case) of the current
Ferret variables associated with this dataset.
sort (boolean): sort the list of names?
'''
namelist = list(self._fervarnames)
if sort:
namelist.sort()
return namelist
def fervars(self, sort=False):
'''
Returns a list of the current Ferret variables associated with this dataset.
sort (boolean): sort the list of FerVars?
'''
varlist = list( self._fervars.values() )
if sort:
varlist.sort()
return varlist
def close(self):
'''
Removes (cancels) all the (non-file) variables in Ferret associated with this dataset,
then closes (cancels) this dataset in Ferret (which removes the file variables as well).
Raises a ValueError if there is a problem.
'''
# if the dataset is already closed, ignore this command
if self._filename and not self._dsetname:
return
# remove all the Ferret variables associated with this dataset,
# ignoring errors from trying to remove file variables.
for name in self._fervars:
try:
# remove this variable from Ferret
self._fervars[name]._removefromferret()
except NotImplementedError:
pass
# remove all the FerVar's from _fervars
self._fervars.clear()
self._fervarnames = [ ]
# nothing else to do if an anonymous dataset
if not self._dsetname:
return
# now remove the dataset
cmdstr = 'CANCEL DATA "%s"' % self._dsetname
(errval, errmsg) = pyferret.run(cmdstr)
if errval != pyferret.FERR_OK:
raise ValueError('unable to remove dataset "%s" in Ferret: %s' % self._dsetname)
# mark this dataset as closed
self._dsetname = ''
def show(self, brief=True, qual=''):
'''
Show the Ferret information about this dataset. This uses the Ferret
SHOW DATA command to create and display the information.
brief (boolean): if True (default), a brief report is shown;
otherwise a full report is shown.
qual (string): Ferret qualifiers to add to the SHOW DATA command
If this is the anonymous dataset (no dataset name), the Ferret
SHOW VAR/USER command is used instead to show all variables
created by this anonymous dataset.
'''
# if the dataset is closed, ignore this command
if self._filename and not self._dsetname:
return
if not isinstance(qual, str):
raise ValueError('qual (Ferret qualifiers) must be a string')
if not self._dsetname:
cmdstr = 'SHOW VAR/USER'
if qual:
cmdstr += qual
else:
cmdstr = 'SHOW DATA'
if not brief:
cmdstr += '/FULL'
if qual:
cmdstr += qual
cmdstr += ' "'
cmdstr += self._dsetname
cmdstr += '"'
(errval, errmsg) = pyferret.run(cmdstr)
if errval != pyferret.FERR_OK:
raise ValueError('Ferret command "%s" failed: %s' % (cmdstr, errmsg))
|