source: CCCC/tags/1.2.5/ceda_cc/file_utils.py @ 212

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CCCC/tags/1.2.5/ceda_cc/file_utils.py@1241
Revision 212, 11.5 KB checked in by mjuckes, 6 years ago (diff)

undated comp_mpi

Line 
1
2# Standard library imports
3import string, pkgutil
4
5from xceptions import *
6
7# Third party imports
8
9#### netcdf --- currently support cdms2, python-netCDF4 and Scientific
10
11l = pkgutil.iter_modules()
12ll = map( lambda x: x[1], l )
13
14supportedNetcdf = ['cdms2','netCDF4','Scientific','ncq3']
15
16installedSupportedNetcdf = []
17##ll = []
18
19for x in supportedNetcdf:
20  if x in ll:
21    installedSupportedNetcdf.append( x )
22
23if len(installedSupportedNetcdf) > 0:
24  try: 
25    cmd = 'import %s' % installedSupportedNetcdf[0]
26    print '>>>>>>>>>', cmd
27    exec cmd
28    ncLib = installedSupportedNetcdf[0]
29  except:
30    print 'Failed to install %s' % installedSupportedNetcdf[0]
31    ncLib = None
32else:
33  print """No supported netcdf module found.
34         Supported modules are %s.
35         Attempting to run with experimental ncq3
36         Execution may fail, depending on options chosen.
37         """ % str(supportedNetcdf)
38  ncLib = 'ncq3'
39
40if ncLib == 'Scientific':
41  from Scientific.IO import NetCDF as ncdf
42
43## end of netcdf import.
44
45## utility function to convert "type" to string and standardise terminology
46def tstr( x ):
47  x1 = str(x)
48  return {'real':'float32', 'integer':'int32', 'float':'float32', 'double':'float64' }.get( x1, x1 )
49
50class fileMetadata(object):
51
52  def __init__(self,dummy=False,attributeMappingsLog=None,forceLib=None):
53     
54     self.dummy = dummy
55     self.atMapLog = attributeMappingsLog
56     self.forceLib = forceLib
57     if self.atMapLog == None:
58       self.atMapLog = open( 'cccc_atMapLog.txt', 'a' )
59
60  def close(self):
61    self.atMapLog.close()
62
63  def loadNc(self,fpath):
64    self.fpath = fpath
65    self.fn = string.split( fpath, '/' )[-1]
66    self.fparts = string.split( self.fn[:-3], '_' )
67    self.ga = {}
68    self.va = {}
69    self.da = {}
70    if self.dummy:
71      self.makeDummyFileImage()
72      return
73    if self.forceLib == 'ncq3':
74      import ncq3
75      self.ncq3 = ncq3
76      self.loadNc__ncq(fpath)
77    elif self.forceLib == 'cdms2':
78      import cdms2
79      self.cdms2 = cdms2
80      self.loadNc__Cdms(fpath)
81    elif self.forceLib == 'netCDF4':
82      import netCDF4
83      self.netCDF4 = netCDF4
84      self.loadNc__Netcdf4(fpath)
85    elif self.forceLib == 'Scientific':
86      import Scientific
87      from Scientific.IO import NetCDF as ncdf
88      self.ncdf = ncdf
89      self.loadNc__Scientific(fpath)
90    elif ncLib == 'cdms2':
91      import cdms2
92      self.cdms2 = cdms2
93      self.loadNc__Cdms(fpath)
94    elif ncLib == 'netCDF4':
95      import netCDF4
96      self.netCDF4 = netCDF4
97      self.loadNc__Netcdf4(fpath)
98    elif ncLib == 'Scientific':
99      from Scientific.IO import NetCDF as ncdf
100      self.ncdf = ncdf
101      self.loadNc__Scientific(fpath)
102    else:
103      import ncq3
104      self.ncq3 = ncq3
105      self.loadNc__ncq(fpath)
106      ##raise baseException( 'No supported netcdf module assigned' )
107
108  def loadNc__ncq(self,fpath):
109    self.nc0 = self.ncq3.open( fpath )
110    self.nc0.getDigest()
111    self.ncq3.close( self.nc0 )
112    self.nc = self.ncq3.Browse( self.nc0.digest )
113    for a in self.nc._gal:
114       self.ga[a.name] = a.value
115    for v in self.nc._vdict.keys():
116      thisv = self.nc._vdict[v][0]
117      if v not in self.nc._ddict.keys():
118        self.va[v] = {}
119        for a in self.nc._ll[thisv.id]:
120          self.va[v][a.name] = a.value
121        self.va[v]['_type'] = tstr( thisv.type )
122        if v in ['plev','plev_bnds','height']:
123          x = thisv.data
124          if type(x) != type([]):
125            x = [x]
126          self.va[v]['_data'] = x
127      else:
128        self.da[v] = {}
129        thisa = self.nc._ddict[v]
130        for a in self.nc._ll[thisv.id]:
131          self.da[v][a.name] = a.value
132        self.da[v]['_type'] = tstr( thisv.type )
133        self.da[v]['_data'] = thisv.data
134   
135  def loadNc__Cdms(self,fpath):
136    self.nc = self.cdms2.open( fpath )
137    for k in self.nc.attributes.keys():
138      self.ga[k] = self.nc.attributes[k]
139      if len( self.ga[k] ) == 1:
140        self.ga[k] = self.ga[k][0]
141    for v in self.nc.variables.keys():
142      self.va[v] = {}
143      for k in self.nc.variables[v].attributes.keys():
144        x = self.nc.variables[v].attributes[k]
145     ## returns a list for some scalar attributes.
146        if type(x) == type([]) and len(x) == 1:
147          x = x[0]
148        self.va[v][k] = x
149      self.va[v]['_type'] = tstr( self.nc.variables[v].dtype )
150      if v in ['plev','plev_bnds','height']:
151        x = self.nc.variables[v].getValue().tolist()
152        if type(x) != type([]):
153          x = [x]
154        self.va[v]['_data'] = x
155        ### Note: returns a scalar if data has a scalar value.
156
157    for v in self.nc.axes.keys():
158      self.da[v] = {}
159      for k in self.nc.axes[v].attributes.keys():
160        self.da[v][k] = self.nc.axes[v].attributes[k]
161      self.da[v]['_type'] = tstr( self.nc.axes[v].getValue().dtype )
162      self.da[v]['_data'] = self.nc.axes[v].getValue().tolist()
163     
164    self.nc.close()
165
166###
167### attributes in .__dict__ dictionary
168### variables in .variables dicttionary
169### dimension lengths in .dimensions
170### <variable>.getValue() returns an numpy.ndarray
171### data type in <variable>.getValue().dtype
172### for scalar variables, <variable>.getValue().tolist() returns a scalar.
173###
174  def loadNc__Scientific(self,fpath):
175    self.nc = self.ncdf.NetCDFFile( fpath, 'r' )
176    for k in self.nc.__dict__.keys():
177      self.ga[k] = self.nc.__dict__[k]
178      if type(self.ga[k]) not in [type('x'),type(1),type(1.)] and len(self.ga[k]) == 1:
179        self.ga[k] = self.ga[k][0]
180    for v in self.nc.variables.keys():
181      if v not in self.nc.dimensions.keys():
182        self.va[v] = {}
183        for k in self.nc.variables[v].__dict__.keys():
184          self.va[v][k] = self.nc.variables[v].__dict__[k]
185        self.va[v]['_type'] = tstr( self.nc.variables[v].getValue().dtype )
186        if v in ['plev','plev_bnds','height']:
187        ### Note: returns a scalar if data has a scalar value.
188          x = self.nc.variables[v].getValue().tolist()
189          if type(x) != type([]):
190            x = [x]
191          self.va[v]['_data'] = x
192
193    for v in self.nc.dimensions.keys():
194      self.da[v] = {}
195      if v in self.nc.variables.keys():
196        for k in self.nc.variables[v].__dict__.keys():
197          self.da[v][k] = self.nc.variables[v].__dict__[k]
198        self.da[v]['_type'] = tstr( self.nc.variables[v].getValue().dtype )
199        self.da[v]['_data'] = self.nc.variables[v].getValue().tolist()
200      else:
201        self.da[v]['_type'] = 'index (no data variable)'
202     
203    self.nc.close()
204
205  def loadNc__Netcdf4(self,fpath):
206    self.nc = self.netCDF4.Dataset(fpath, 'r')
207    for k in self.nc.ncattrs():
208      self.ga[k] = self.nc.getncattr(k)
209      if type( self.ga[k] ) in [ type([]),type(()) ]:
210        if len( self.ga[k] ) == 1:
211          self.ga[k] = self.ga[k][0]
212    for v in self.nc.variables.keys():
213      if v not in self.nc.dimensions.keys():
214        self.va[v] = {}
215        for k in self.nc.variables[v].ncattrs():
216          self.va[v][k] = self.nc.variables[v].getncattr(k)
217        try:
218          self.va[v]['_type'] = tstr( self.nc.variables[v].dtype )
219        except:
220          self.va[v]['_type'] = tstr( self.nc.variables[v].datatype )
221        if v in ['plev','plev_bnds','height']:
222          self.va[v]['_data'] = self.nc.variables[v][:].tolist()
223
224    for v in self.nc.dimensions.keys():
225      self.da[v] = {}
226      if v in self.nc.variables.keys():
227        for k in self.nc.variables[v].ncattrs():
228          self.da[v][k] = self.nc.variables[v].getncattr(k)
229        try:
230          self.da[v]['_type'] = tstr( self.nc.variables[v].dtype )
231        except:
232          self.da[v]['_type'] = tstr( self.nc.variables[v].datatype )
233
234        self.da[v]['_data'] = self.nc.variables[v][:].tolist()
235      else:
236        self.da[v]['_type'] = 'index (no data variable)'
237     
238    self.nc.close()
239
240  def makeDummyFileImage(self):
241    for k in range(10):
242      self.ga['ga%s' % k] =  str(k)
243    for v in [self.fparts[0],]:
244      self.va[v] = {}
245      self.va[v]['standard_name'] = 's%s' % v
246      self.va[v]['long_name'] = v
247      self.va[v]['cell_methods'] = 'time: point'
248      self.va[v]['units'] = '1'
249      self.va[v]['_type'] = 'float32'
250
251    for v in ['lat','lon','time']:
252      self.da[v] = {}
253      self.da[v]['_type'] = 'float64'
254      self.da[v]['_data'] = range(5)
255    dlist = ['lat','lon','time']
256    svals = lambda p,q: map( lambda y,z: self.da[y].__setitem__(p, z), dlist, q )
257    svals( 'standard_name', ['latitude', 'longitude','time'] )
258    svals( 'long_name', ['latitude', 'longitude','time'] )
259    svals( 'units', ['degrees_north', 'degrees_east','days since 19590101'] )
260
261  def applyMap( self, mapList, globalAttributesInFn, log=None ):
262    for m in mapList:
263      if m[0] == 'am001':
264        if m[1][0][0] == "@var":
265          if m[1][0][1] in self.va.keys():
266            this = self.va[m[1][0][1]]
267            apThis = True
268            for c in m[1][1:]:
269              if c[0] not in this.keys():
270                apThis = False
271              elif c[1] != this[c[0]]:
272                apThis = False
273            if m[2][0] != '':
274              targ = m[2][0]
275            else:
276              targ = m[1][-1][0]
277            if apThis:
278              if log != None:
279                log.info( 'Setting %s to %s' % (targ,m[2][1]) )
280              ##print 'Setting %s:%s to %s' % (m[1][0][1],targ,m[2][1])
281              thisval = self.va[m[1][0][1]].get( targ, None )
282              self.va[m[1][0][1]][targ] = m[2][1]
283              self.atMapLog.write( '@var:"%s","%s","%s","%s","%s"\n' % (self.fpath, m[1][0][1], targ, thisval, m[2][1] ) )
284
285        elif m[1][0][0] == "@ax":
286          ##print 'checking dimension ',m[1][0][1], self.da.keys()
287          if m[1][0][1] in self.da.keys():
288            ##print 'checking dimension [2]',m[1][0][1]
289            this = self.da[m[1][0][1]]
290            apThis = True
291            for c in m[1][1:]:
292              if c[0] not in this.keys():
293                apThis = False
294              elif c[1] != this[c[0]]:
295                apThis = False
296            if m[2][0] != '':
297              targ = m[2][0]
298            else:
299              targ = m[1][-1][0]
300            if apThis:
301              if log != None:
302                log.info( 'Setting %s to %s' % (targ,m[2][1]) )
303              ##print 'Setting %s:%s to %s' % (m[1][0][1],targ,m[2][1])
304              thisval = self.da[m[1][0][1]].get( targ, None )
305              self.da[m[1][0][1]][targ] = m[2][1]
306              self.atMapLog.write( '@ax:"%s","%s","%s","%s","%s"\n' % (self.fpath, m[1][0][1], targ, thisval, m[2][1]) )
307        elif m[1][0][0] == "@":
308            this = self.ga
309            apThis = True
310## apply change where attribute absent only
311            for c in m[1][1:]:
312              if c[0] not in this.keys():
313                if c[1] != '__absent__':
314                  apThis = False
315              elif c[1] == '__absent__' or c[1] != this[c[0]]:
316                apThis = False
317            if m[2][0] != '':
318              targ = m[2][0]
319            else:
320              targ = m[1][-1][0]
321            if apThis:
322              if log != None:
323                log.info( 'Setting %s to %s' % (targ,m[2][1]) )
324              ##print 'Setting %s to %s' % (targ,m[2][1])
325              thisval = self.ga.get( targ, None )
326              self.ga[targ] = m[2][1]
327              self.atMapLog.write( '@:"%s","%s","%s","%s","%s"\n' % (self.fpath, 'ga', targ, thisval, m[2][1]) )
328##
329              if targ in globalAttributesInFn:
330                i = globalAttributesInFn.index(targ)
331                thisval = self.fparts[ i ]
332                self.fparts[ i ] = m[2][1]
333                self.fn = string.join( self.fparts, '_' ) + '.nc'
334                self.atMapLog.write( '@fn:"%s","%s","%s"\n' % (self.fpath, thisval, m[2][1]) )
335        else:
336          print 'Token %s not recognised' % m[1][0][0]
Note: See TracBrowser for help on using the repository browser.