source: CCCC/tags/0.1/file_utils.py @ 155

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CCCC/tags/0.1/file_utils.py
Revision 155, 9.4 KB checked in by mjuckes, 6 years ago (diff)

various fixes for aMap feature -- see updates.txt

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        try:
152          self.va[v]['_type'] = str( self.nc.variables[v].dtype )
153        except:
154          self.va[v]['_type'] = str( self.nc.variables[v].datatype )
155        if v in ['plev','plev_bnds','height']:
156          self.va[v]['_data'] = self.nc.variables[v][:].tolist()
157
158    for v in self.nc.dimensions.keys():
159      self.da[v] = {}
160      if v in self.nc.variables.keys():
161        for k in self.nc.variables[v].ncattrs():
162          self.da[v][k] = self.nc.variables[v].getncattr(k)
163        try:
164          self.da[v]['_type'] = str( self.nc.variables[v].dtype )
165        except:
166          self.da[v]['_type'] = str( self.nc.variables[v].datatype )
167
168        self.da[v]['_data'] = self.nc.variables[v][:].tolist()
169      else:
170        self.da[v]['_type'] = 'index (no data variable)'
171     
172    self.nc.close()
173
174  def makeDummyFileImage(self):
175    for k in range(10):
176      self.ga['ga%s' % k] =  str(k)
177    for v in [self.fparts[0],]:
178      self.va[v] = {}
179      self.va[v]['standard_name'] = 's%s' % v
180      self.va[v]['long_name'] = v
181      self.va[v]['cell_methods'] = 'time: point'
182      self.va[v]['units'] = '1'
183      self.va[v]['_type'] = 'float32'
184
185    for v in ['lat','lon','time']:
186      self.da[v] = {}
187      self.da[v]['_type'] = 'float64'
188      self.da[v]['_data'] = range(5)
189    dlist = ['lat','lon','time']
190    svals = lambda p,q: map( lambda y,z: self.da[y].__setitem__(p, z), dlist, q )
191    svals( 'standard_name', ['latitude', 'longitude','time'] )
192    svals( 'long_name', ['latitude', 'longitude','time'] )
193    svals( 'units', ['degrees_north', 'degrees_east','days since 19590101'] )
194
195  def applyMap( self, mapList, globalAttributesInFn, log=None ):
196    for m in mapList:
197      if m[0] == 'am001':
198        if m[1][0][0] == "@var":
199          if m[1][0][1] in self.va.keys():
200            this = self.va[m[1][0][1]]
201            apThis = True
202            for c in m[1][1:]:
203              if c[0] not in this.keys():
204                apThis = False
205              elif c[1] != this[c[0]]:
206                apThis = False
207            if m[2][0] != '':
208              targ = m[2][0]
209            else:
210              targ = m[1][-1][0]
211            if apThis:
212              if log != None:
213                log.info( 'Setting %s to %s' % (targ,m[2][1]) )
214              ##print 'Setting %s:%s to %s' % (m[1][0][1],targ,m[2][1])
215              thisval = self.va[m[1][0][1]].get( targ, None )
216              self.va[m[1][0][1]][targ] = m[2][1]
217              self.atMapLog.write( '@var:"%s","%s","%s","%s","%s"\n' % (self.fpath, m[1][0][1], targ, thisval, m[2][1] ) )
218
219        elif m[1][0][0] == "@ax":
220          ##print 'checking dimension ',m[1][0][1], self.da.keys()
221          if m[1][0][1] in self.da.keys():
222            ##print 'checking dimension [2]',m[1][0][1]
223            this = self.da[m[1][0][1]]
224            apThis = True
225            for c in m[1][1:]:
226              if c[0] not in this.keys():
227                apThis = False
228              elif c[1] != this[c[0]]:
229                apThis = False
230            if m[2][0] != '':
231              targ = m[2][0]
232            else:
233              targ = m[1][-1][0]
234            if apThis:
235              if log != None:
236                log.info( 'Setting %s to %s' % (targ,m[2][1]) )
237              ##print 'Setting %s:%s to %s' % (m[1][0][1],targ,m[2][1])
238              thisval = self.da[m[1][0][1]].get( targ, None )
239              self.da[m[1][0][1]][targ] = m[2][1]
240              self.atMapLog.write( '@ax:"%s","%s","%s","%s","%s"\n' % (self.fpath, m[1][0][1], targ, thisval, m[2][1]) )
241        elif m[1][0][0] == "@":
242            this = self.ga
243            apThis = True
244## apply change where attribute absent only
245            for c in m[1][1:]:
246              if c[0] not in this.keys():
247                if c[1] != '__absent__':
248                  apThis = False
249              elif c[1] == '__absent__' or c[1] != this[c[0]]:
250                apThis = False
251            if m[2][0] != '':
252              targ = m[2][0]
253            else:
254              targ = m[1][-1][0]
255            if apThis:
256              if log != None:
257                log.info( 'Setting %s to %s' % (targ,m[2][1]) )
258              ##print 'Setting %s to %s' % (targ,m[2][1])
259              thisval = self.ga.get( targ, None )
260              self.ga[targ] = m[2][1]
261              self.atMapLog.write( '@:"%s","%s","%s","%s","%s"\n' % (self.fpath, 'ga', targ, thisval, m[2][1]) )
262##
263              if targ in globalAttributesInFn:
264                i = globalAttributesInFn.index(targ)
265                thisval = self.fparts[ i ]
266                self.fparts[ i ] = m[2][1]
267                self.fn = string.join( self.fparts, '_' ) + '.nc'
268                self.atMapLog.write( '@fn:"%s","%s","%s"\n' % (self.fpath, thisval, m[2][1]) )
269        else:
270          print 'Token %s not recognised' % m[1][0][0]
Note: See TracBrowser for help on using the repository browser.