source: CCCC/trunk/file_utils.py @ 148

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CCCC/trunk/file_utils.py@148
Revision 148, 9.2 KB checked in by mjuckes, 6 years ago (diff)

Added support for ScientificPython?

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