source: CCCC/trunk/ceda_cc/file_utils.py @ 180

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

merged from branches-mnj (which was branched from branches-sp)

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