Changeset 147


Ignore:
Timestamp:
16/04/14 14:00:25 (6 years ago)
Author:
mjuckes
Message:

Support for netCDF4 added. File metadata module move to new file_utils.py file

Location:
CCCC/trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • CCCC/trunk/README.txt

    r142 r147  
    4343------------ 
    4444 
    45 The library uses the cmds2 module to read NetCDF files. 
     45The library can uses the cdms2 module or the netCDF4 module to read NetCDF files. 
     46By default, it will use the cdms2 module if available. Support for the netCDF4 module has been added recently. 
    4647 
    4748OUTPUT 
  • CCCC/trunk/c4.py

    r143 r147  
    11 
    22# Standard library imports 
    3 import os, string, time, logging, sys, glob 
    4  
     3import os, string, time, logging, sys, glob, pkgutil 
     4 
     5## pkgutil is used in file_utils 
    56# Third party imports 
    67 
    7 try: 
    8   import cdms2 
    9   withCdms = True 
    10 except: 
    11   print 'Failed to import cdms2: will not be able to read NetCDF' 
    12   withCdms = False 
     8## Local imports with 3rd party dependencies 
     9#### netcdf --- currently only support for cmds2 -- re-arranged to facilitate support for alternative modules 
     10 
     11import file_utils 
     12 
     13from file_utils import fileMetadata, ncLib 
    1314 
    1415# Local imports 
     
    2223#rcm_version_id = <RCMVersionID>                      
    2324 
    24 class fileMetadata: 
    25  
    26   def __init__(self,dummy=False,attributeMappingsLog=None): 
    27       
    28      self.dummy = dummy 
    29      self.atMapLog = attributeMappingsLog 
    30      if self.atMapLog == None: 
    31        self.atMapLog = open( '/tmp/cccc_atMapLog.txt', 'a' ) 
    32  
    33   def close(self): 
    34     self.atMapLog.close() 
    35  
    36   def loadNc(self,fpath): 
    37     self.fpath = fpath 
    38     self.fn = string.split( fpath, '/' )[-1] 
    39     self.fparts = string.split( self.fn[:-3], '_' ) 
    40     self.ga = {} 
    41     self.va = {} 
    42     self.da = {} 
    43     if self.dummy: 
    44       self.makeDummyFileImage() 
    45       return 
    46     self.nc = cdms2.open( fpath ) 
    47     for k in self.nc.attributes.keys(): 
    48       self.ga[k] = self.nc.attributes[k] 
    49       if len( self.ga[k] ) == 1: 
    50         self.ga[k] = self.ga[k][0] 
    51     for v in self.nc.variables.keys(): 
    52       self.va[v] = {} 
    53       for k in self.nc.variables[v].attributes.keys(): 
    54         self.va[v][k] = self.nc.variables[v].attributes[k] 
    55       self.va[v]['_type'] = str( self.nc.variables[v].dtype ) 
    56       if v in ['plev','plev_bnds','height']: 
    57         self.va[v]['_data'] = self.nc.variables[v].getValue().tolist() 
    58  
    59     for v in self.nc.axes.keys(): 
    60       self.da[v] = {} 
    61       for k in self.nc.axes[v].attributes.keys(): 
    62         self.da[v][k] = self.nc.axes[v].attributes[k] 
    63       self.da[v]['_type'] = str( self.nc.axes[v].getValue().dtype ) 
    64       self.da[v]['_data'] = self.nc.axes[v].getValue().tolist() 
    65        
    66     self.nc.close() 
    67  
    68   def makeDummyFileImage(self): 
    69     for k in range(10): 
    70       self.ga['ga%s' % k] =  str(k) 
    71     for v in [self.fparts[0],]: 
    72       self.va[v] = {} 
    73       self.va[v]['standard_name'] = 's%s' % v 
    74       self.va[v]['long_name'] = v 
    75       self.va[v]['cell_methods'] = 'time: point' 
    76       self.va[v]['units'] = '1' 
    77       self.va[v]['_type'] = 'float32' 
    78  
    79     for v in ['lat','lon','time']: 
    80       self.da[v] = {} 
    81       self.da[v]['_type'] = 'float64' 
    82       self.da[v]['_data'] = range(5) 
    83     dlist = ['lat','lon','time'] 
    84     svals = lambda p,q: map( lambda y,z: self.da[y].__setitem__(p, z), dlist, q ) 
    85     svals( 'standard_name', ['latitude', 'longitude','time'] ) 
    86     svals( 'long_name', ['latitude', 'longitude','time'] ) 
    87     svals( 'units', ['degrees_north', 'degrees_east','days since 19590101'] ) 
    88  
    89   def applyMap( self, mapList, globalAttributesInFn, log=None ): 
    90     for m in mapList: 
    91       if m[0] == 'am001': 
    92         if m[1][0][0] == "@var": 
    93           if m[1][0][1] in self.va.keys(): 
    94             this = self.va[m[1][0][1]] 
    95             apThis = True 
    96             for c in m[1][1:]: 
    97               if c[0] not in this.keys(): 
    98                 apThis = False 
    99               elif c[1] != this[c[0]]: 
    100                 apThis = False 
    101             if m[2][0] != '': 
    102               targ = m[2][0] 
    103             else: 
    104               targ = m[1][-1][0] 
    105             if apThis: 
    106               if log != None: 
    107                 log.info( 'Setting %s to %s' % (targ,m[2][1]) ) 
    108               ##print 'Setting %s:%s to %s' % (m[1][0][1],targ,m[2][1]) 
    109               thisval = self.va[m[1][0][1]].get( targ, None ) 
    110               self.va[m[1][0][1]][targ] = m[2][1] 
    111               self.atMapLog.write( '@var:"%s","%s","%s","%s","%s"\n' % (self.fpath, m[1][0][1], targ, thisval, m[2][1] ) ) 
    112  
    113         elif m[1][0][0] == "@ax": 
    114           ##print 'checking dimension ',m[1][0][1], self.da.keys() 
    115           if m[1][0][1] in self.da.keys(): 
    116             ##print 'checking dimension [2]',m[1][0][1] 
    117             this = self.da[m[1][0][1]] 
    118             apThis = True 
    119             for c in m[1][1:]: 
    120               if c[0] not in this.keys(): 
    121                 apThis = False 
    122               elif c[1] != this[c[0]]: 
    123                 apThis = False 
    124             if m[2][0] != '': 
    125               targ = m[2][0] 
    126             else: 
    127               targ = m[1][-1][0] 
    128             if apThis: 
    129               if log != None: 
    130                 log.info( 'Setting %s to %s' % (targ,m[2][1]) ) 
    131               ##print 'Setting %s:%s to %s' % (m[1][0][1],targ,m[2][1]) 
    132               thisval = self.va[m[1][0][1]].get( targ, None ) 
    133               self.da[m[1][0][1]][targ] = m[2][1] 
    134               self.atMapLog.write( '@ax:"%s","%s","%s","%s","%s"\n' % (self.fpath, m[1][0][1], targ, thisval, m[2][1]) ) 
    135         elif m[1][0][0] == "@": 
    136             this = self.ga 
    137             apThis = True 
    138 ## apply change where attribute absent only 
    139             for c in m[1][1:]: 
    140               if c[0] not in this.keys(): 
    141                 if c[1] != '__absent__': 
    142                   apThis = False 
    143               elif c[1] == '__absent__' or c[1] != this[c[0]]: 
    144                 apThis = False 
    145             if m[2][0] != '': 
    146               targ = m[2][0] 
    147             else: 
    148               targ = m[1][-1][0] 
    149             if apThis: 
    150               if log != None: 
    151                 log.info( 'Setting %s to %s' % (targ,m[2][1]) ) 
    152               ##print 'Setting %s to %s' % (targ,m[2][1]) 
    153               thisval = self.ga.get( targ, None ) 
    154               self.ga[targ] = m[2][1] 
    155               self.atMapLog.write( '@:"%s","%s","%s","%s","%s"\n' % (self.fpath, 'ga', targ, thisval, m[2][1]) ) 
    156 ## 
    157               if targ in globalAttributesInFn: 
    158                 i = globalAttributesInFn.index(targ) 
    159                 thisval = self.fparts[ i ] 
    160                 self.fparts[ i ] = m[2][1] 
    161                 self.fn = string.join( self.fparts, '_' ) + '.nc' 
    162                 self.atMapLog.write( '@fn:"%s","%s","%s"\n' % (self.fpath, thisval, m[2][1]) ) 
    163         else: 
    164           print 'Token %s not recognised' % m[1][0][0] 
    165  
    166  
    16725class dummy: 
    16826   pass 
    169  
    17027 
    17128pathTmplDict = { 'CORDEX':'%(project)s/%(product)s/%(domain)s/%(institute)s/%(driving_model)s/%(experiment)s/%(ensemble)s/%(model)s/%(model_version)s/%(frequency)s/%(variable)s/files/%%(version)s/',   \ 
     
    498355    c4i = c4_init(args=args) 
    499356    isDummy  = c4i.project[:2] == '__' 
    500     if (not withCdms) and isDummy: 
    501        print withCdms, c4i.project 
     357    if (ncLib == dummy) and (not isDummy): 
     358       print ncLib, c4i.project 
    502359       print 'Cannot proceed with non-dummy project without cdms' 
    503360       raise 
  • CCCC/trunk/utils_c4.py

    r144 r147  
    9393    self.passCount = 0 
    9494    self.missingValue = 1.e20 
     95    from file_utils import ncLib 
     96    if ncLib == 'netCDF4': 
     97      import numpy 
     98      self.missingValue = numpy.float32(self.missingValue) 
    9599    self.parent = parent 
    96100    self.reportPass=reportPass 
     
    543547      self.test( 'plev' in va.keys(), 'plev coordinate not found %s' % str(va.keys()), abort=True, part=True ) 
    544548 
    545       ok &= self.test( int( va['plev']['_data'] ) == self.plevValues[varName],  \ 
     549      ok &= self.test( int( va['plev']['_data'][0] ) == self.plevValues[varName],  \ 
    546550                  'plev value [%s] does not match required [%s]' % (va['plev']['_data'],self.plevValues[varName] ), part=True ) 
    547551       
     
    589593                ##'height value [%s] does not match required [%s]' % (va['height']['_data'],self.heightValues[varName] ), part=True ) 
    590594 
    591       r = self.heightRange[varName] 
    592       ok &= self.test( r[0] <= va['height']['_data'] <= r[1], \ 
     595      ok1 = self.test( len( va['height']['_data'] ) == 1, 'More height values (%s) than expected (1)' % (len( va['height']['_data'])), part=True ) 
     596      if ok1: 
     597        r = self.heightRange[varName] 
     598        ok1 &= self.test( r[0] <= va['height']['_data'][0] <= r[1], \ 
    593599                'height value [%s] not in specified range [%s]' % (va['height']['_data'], (self.heightRange[varName] ) ), part=True ) 
     600 
     601      ok &= ok1 
    594602       
    595603      for k in heightAtDict.keys(): 
Note: See TracChangeset for help on using the changeset viewer.