source: CMIP6dreqbuild/trunk/srcMisc/extractMipInfo.py @ 374

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/srcMisc/extractMipInfo.py@376
Revision 374, 22.5 KB checked in by mjuckes, 5 years ago (diff)

update

Line 
1
2import collections, glob, string, re, json, sys
3from fcc_utils2 import mipTableScan, snlist, tupsort
4from config_c4 import CC_CONFIG_DIR
5
6def uniquify( ll ):
7  ll.sort()
8  l0 = [ll[0],]
9  for l in ll[1:]:
10    if l != l0[-1]:
11      l0.append(l)
12  return l0
13
14heightRequired = ['tas','tasmax','tasmin','huss','sfcWind','sfcWindmax','wsgsmax','uas','vas']
15cmip5_ignore = ['pfull','phalf','depth','depth_c','eta','nsigma','vertices_latitude','vertices_longitude','ztop','ptop','p0','z1','z2','href','k_c','a','a_bnds','ap','ap_bnds','b','b_bnds','sigma','sigma_bnds','zlev','zlev_bnds','zfull','zhalf']
16cmip5_ignore = ['depth','depth_c','eta','nsigma','vertices_latitude','vertices_longitude','ztop','ptop','p0','z1','z2','href','k_c','a','a_bnds','ap','ap_bnds','b','b_bnds','sigma','sigma_bnds','zlev','zlev_bnds']
17cmip5AxesAtts = ['axis', 'bounds_values', 'climatology', 'coords_attrib', 'formula', 'index_only', 'long_name', 'must_call_cmor_grid', 'must_have_bounds', 'out_name', 'positive', 'requested', 'requested_bounds', 'standard_name', 'stored_direction', 'tolerance', 'type', 'units', 'valid_max', 'valid_min', 'value', 'z_bounds_factors', 'z_factors']
18cmip5Atts = ['cell_measures', 'cell_methods', 'comment', 'deflate', 'deflate_level', 'long_name', 'modeling_realm', 'ok_max_mean_abs', 'ok_min_mean_abs', 'out_name', 'shuffle', 'standard_name', 'type', 'units', 'valid_max', 'valid_min', 'positive', 'flag_meanings', 'flag_values']
19
20
21NT_mip = collections.namedtuple( 'mip',['label','dir','pattern'] )
22NT_var = collections.namedtuple( 'var',['name','sn','snStat','realm','units','longName','comment','mip'] )
23NT_canvari = collections.namedtuple( 'canonicalVariation',['conditions','text', 'ref'] )
24vlist = [
25('uas',
26"eastward_wind",
27'Eastward Near-Surface Wind Speed',
28'Eastward Near-Surface Wind',
29'WRONG LONG NAME (*speed* included)'),
30('vas',
31"northward_wind",
32'Northward Near-Surface Wind Speed',
33'Northward Near-Surface Wind',
34'WRONG LONG NAME (*speed* included)'),
35("snc",
36"surface_snow_area_fraction",
37"Snow Area Fraction",
38"Surface Snow Area Fraction",
39"WRONG LONG NAME (*surface* omitted)"),
40("prsn",
41"snowfall_flux", 
42"Solid Precipitation",
43"Snowfall Flux",
44"WRONG LONG NAME"),
45("tntscpbl",
46"tendency_of_air_temperature_due_to_stratiform_cloud_and_precipitation_and_boundary_layer_mixing",
47"Tendency of Air Temperature due to Stratiform Cloud Condensation and Evaporation",
48"Tendency of Air Temperature Due to Stratiform Cloud and Precipitation and Boundary Layer Mixing",
49'WRONG LONG NAME'),
50("tas",
51"air_temperature",
52"Air Temperature",
53"Near-Surface Air Temperature",
54'WRONG LONG NAME'),
55("cfadDbze94",
56"histogram_of_equivalent_reflectivity_factor_over_height_above_reference_ellipsoid",
57"CloudSat Radar Reflectivity CFAD",
58"CloudSat Radar Reflectivity",
59"INCONSISTENT LONG NAME"),
60("cfadLidarsr532",
61"histogram_of_backscattering_ratio_over_height_above_reference_ellipsoid",
62"CALIPSO Scattering Ratio CFAD",
63"CALIPSO Scattering Ratio",
64"INCONSISTENT LONG NAME"),
65("cl",
66"cloud_area_fraction_in_atmosphere_layer",
67"Cloud Area Fraction",
68"Cloud Area Fraction in Atmosphere Layer",
69"INCONSISTENT LONG NAME"),
70("clcalipso",
71"cloud_area_fraction_in_atmosphere_layer",
72"CALIPSO Cloud Fraction",
73"CALIPSO Cloud Area Fraction",
74'WRONG LONG NAME'),
75("cltisccp",
76"cloud_area_fraction",
77"ISCCP Total Total Cloud Fraction",
78"ISCCP Total Cloud Fraction",
79'WRONG LONG NAME'),
80("reffclwc",
81"effective_radius_of_convective_cloud_liquid_water_particle",
82"Convective Cloud Droplet Effective Radius",
83"Hydrometeor Effective Radius of Convective Cloud Liquid Water",
84'INCONSISTENT LONG NAMES'),
85("reffclws",
86"effective_radius_of_stratiform_cloud_liquid_water_particle",
87'Stratiform Cloud Droplet Effective Radius',
88'Hydrometeor Effective Radius of Stratiform Cloud Liquid Water',
89'INCONSISTENT LONG NAMES' ) ]
90
91
92class helper:
93
94  def __init__(self):
95    self.applycv = True
96    self.re1 = re.compile( '"(.*)"=="(.*)"' )
97
98    self.cmip5Tables= ['CMIP5_3hr', 'CMIP5_6hrPlev', 'CMIP5_Amon', 'CMIP5_cfDay', 'CMIP5_cfOff', 'CMIP5_day', 'CMIP5_grids', 'CMIP5_Lmon', 'CMIP5_OImon', 'CMIP5_Oyr',
99  'CMIP5_6hrLev', 'CMIP5_aero', ' CMIP5_cf3hr', 'CMIP5_cfMon', 'CMIP5_cfSites', 'CMIP5_fx', 'CMIP5_LImon', 'CMIP5_Oclim', 'CMIP5_Omon' ]
100    self.cmip5DefPoint = ['CMIP5_3hr', 'CMIP5_6hrPlev', 'CMIP5_cfOff', 'CMIP5_6hrLev', ' CMIP5_cf3hr', 'CMIP5_cfSites' ]
101
102    self.canonvar = [ NT_canvari( (('table','CMIP5_3hr'),), 'This is sampled synoptically.', '' ),
103                      NT_canvari( (), 'The flux is computed as the mass divided by the area of the grid cell.', 'This is calculated as the convective mass flux divided by the area of the whole grid cell (not just the area of the cloud).' ),
104            ]
105
106    self.canonvar = []
107    for l in open( 'config/canonicalVariations.txt' ).readlines():
108      if l[0] != '#':
109        ix = l.index(':')
110        s = string.strip( l[ix:] )
111        r = self.re1.findall( s )
112        assert len(r) == 1, 'Cannot parse: %s' % s
113        self.canonvar.append( NT_canvari( (), r[0][0], r[0][1] ) )
114
115  def match(self,a,b):
116      if type(a) == type( 'X' ) and type(b) == type( 'X' ):
117        a0,b0 = map( lambda x: string.replace(x, '__ABSENT__',''), [a,b] )
118        return string.strip( string.replace(a0, '  ', ' '), '"') == string.strip( string.replace(b0, '  ', ' '), '"')
119      else:
120        return a == b
121
122  def checkCond( self, table, var, conditions ):
123    val = True
124    for ck, cv in conditions:
125      if ck == 'table':
126        val &= table == cv
127      elif ck == 'var':
128        val &= var == cv
129
130    return val
131       
132     
133
134class snsub:
135
136  def __init__(self):
137    pass
138
139  def isFalseSn(self,var,sn):
140    if sn == 'mole_concentration_of_molecular_oxygen_in_sea_water':
141      return (True,'mole_concentration_of_dissolved_molecular_oxygen_in_sea_water', 'INVALID STANDARD NAME')
142    elif var == 'rldscs' and sn == 'downwelling_longwave_flux_in_air_assuming_clear_sky':
143      return (True,'surface_downwelling_longwave_flux_in_air_assuming_clear_sky','WRONG STANDARD NAME (should be surface)' )
144    elif var == 'clisccp' and sn == 'cloud_area_fraction_in_atmosphere_layer':
145      return (True, 'isccp_cloud_area_fraction', 'WRONG STANDARD NAME (should be isccp)' )
146    return (False,'no match','')
147
148  def isFalseLn(self,var,ln):
149    for tt in vlist:
150       if var == tt[0] and ln == tt[2]:
151         return (True, tt[3], tt[4] )
152    return (False,'no match','')
153
154
155class mipCo:
156
157  def __init__(self,mips,helper=None):
158    self.vl0 = []
159    self.al0 = []
160    self.tl = []
161    self.dl = []
162    self.td = {}
163    self.dd = {}
164    self.helper = helper
165    for mip in mips:
166      self._scan(mip)
167
168  def _scan(self,mip):
169   
170 ## dl = glob.glob( '%s%s' % (mip.dir,mip.pattern) )
171    dl = glob.glob( '%s/%s%s' % (CC_CONFIG_DIR, mip.dir,mip.pattern) )
172    dl.sort()
173    for d in dl:
174     if d[-5:] != 'grids':
175      tab = string.split( d, '/')[-1]
176      isoceanic = tab[:7] == "CMIP5_O"
177      l2 = ms.scan_table( open( d ).readlines(), None, asDict=True, lax=True, tag="x", warn=True)
178      l2k = []
179      usedDims = []
180      for k in l2.keys():
181        if k not in cmip5_ignore:
182          l2k.append(k)
183          if l2[k][0] != 'scalar':
184            usedDims += l2[k][0]
185      l2k.sort()
186      usedDims.sort()
187      usedDims = uniquify( usedDims )
188     
189      ##self.al0 += ms.adict.keys()
190      self.vl0 += l2k
191      self.tl.append( [tab,l2, l2k,isoceanic] )
192      self.td[tab] = l2
193      ##self.dd[tab] = ms.adict.copy()
194      self.dd[tab] = {}
195      for k in ms.adict.keys():
196        if k not in usedDims:
197          print "WARNING[X1]: axis %s declared and not used in table %s" % (k,tab)
198      for u in usedDims:
199        if ms.adict.has_key(u):
200           self.dd[tab][u] = ms.adict[u]
201        else:
202           print 'WARNING[X2]: USED DIMENSION %s not in table %s' % (u,tab)
203      ##self.dl.append( [tab, ms.adict.copy()] )
204      self.dl.append( [tab, self.dd[tab].copy() ] )
205      self.al0 += self.dd[tab].keys()
206
207    self.vl0.sort()
208    self.vl = []
209    self.vl.append( self.vl0[0] )
210    self.vdict = { self.vl[0]:[] }
211    for v in self.vl0[1:]:
212      if v != self.vl[-1]:
213        self.vl.append(v)
214        self.vdict[v] = []
215    self.al0.sort()
216    self.al = [self.al0[0],]
217    self.adict = { self.al[0]:[] }
218    for v in self.al0[1:]:
219      if v != self.al[-1]:
220        self.al.append(v)
221        self.adict[v] = []
222
223    for t in self.tl:
224      for k in t[2]:
225        self.vdict[k].append(t[0])
226
227## create list of tables for each dimension.
228    for a in self.dl:
229      for k in a[1].keys():
230        self.adict[k].append(a[0])
231
232    self.dims = self.adict.keys()
233    self.dims.sort()
234    self.vars = self.vdict.keys()
235    self.vars.sort()
236    ##for v in self.vars:
237      ##l = self.vdict[v]
238      ##l.sort()
239##  print v, l, td[l[0]][v][1].get('standard_name','__NO_STANDARD_NAME__')
240
241class runcheck1:
242  def __init__( self, m, thisatts, isAxes=False):
243    self.errors = []
244    if not isAxes:
245      vars = m.vars
246      vdict = m.vdict
247      td = m.td
248      ix = 1
249      xxx = ''
250    else:
251      vars = m.dims
252      vdict = m.adict
253      td = m.dd
254      ix = 0
255      xxx = 'dim: '
256
257    self.ix = ix
258    self.vars = vars
259    self.vdict = vdict
260# dictionary td[tab][var][ix][attribute]
261    self.td = td
262    vd2 = {}
263    for v in vars:
264     l = vdict[v]
265     l.sort()
266     if len(l) > 1:
267       for att in thisatts:
268        if att != "__name__":
269       ##for att in ['standard_name','units']:
270         if att == '__dimensions__':
271           atl = map( lambda x: string.join( td[x][v][0] ), l )
272         else:
273           atl = map( lambda x: td[x][v][ix].get(att,'__ABSENT__'), l )
274         atl.sort()
275         av = [atl[0],]
276         for a in atl[1:]:
277           if a != av[-1]:
278             av.append(a)
279         if att == 'standard_name':
280           for a in av:
281             if a not in snl and a not in snla:
282               print "ERROR[A1]: ",xxx,"INVALID STANDARD NAME: ",a,v
283               self.errors.append( "INVALID STANDARD NAME: %s [%s]" % (a,v) )
284         if len(av) > 1:
285           ee = {}
286   
287           for a in [True,False]:
288             ee[a] = []
289   
290           isol = []
291           for x in l:
292             a = td[x][v][ix].get(att,'__ABSENT__')
293             try:
294              if att == 'standard_name' or ( att == 'long_name' and vd2[v][0] == 2):
295               iso = x[:7] == 'CMIP5_O'
296               tt = snsubber.isFalseSn( v, a )
297              elif att == 'long_name':
298               tt = snsubber.isFalseLn( v, a )
299               dims = td[x][v][0]
300               iso = 'depth0m' in dims
301              else:
302               iso = False
303               tt = (False,)
304         ##    iso = False
305             except:
306               print att,v
307               raise
308             isol.append((iso,x))
309             if tt[0]:
310               print 'INFO[Y1]: Substituting ',v,a,tt
311               ee[iso].append( tt[1] )
312             else:
313               ee[iso].append( a )
314   
315           for a in [True,False]:
316             ok = True
317             if len(ee[a]) > 1 :
318               for x in ee[a][1:]:
319                 if x != ee[a][0]:
320                   ok = False
321   
322             if not ok:
323                print xxx,'E001: Multiple values : ',att,v,ee
324                for t in isol:
325                  if t[0] == a:
326                    tab = t[1]
327                    if att in ['standard_name','long_name']:
328                      print "E002",xxx,tab,td[tab][v][ix].get('standard_name','__ABSENT__'),td[tab][v][ix].get('long_name','__ABSENT__')
329                    else:
330                      print "E003",xxx,tab,td[tab][v][ix].get(att,'__ABSENT__')
331                   
332           if att == "standard_name":
333             vd2[v] = (2,[ee[True],ee[False]] )
334         else:
335           if att == "standard_name":
336             tt = snsubber.isFalseSn( v, av[0] )
337             if tt[0]:
338               print 'INFO[A2]: Substituting ',v,av[0],tt
339               vd2[v] = (1, tt[1])
340             else:
341               vd2[v] = (1, av)
342     elif len(l) == 1:
343           tab = vdict[v][0]
344           a = td[tab][v][ix].get('standard_name','__ABSENT__')
345           tt = snsubber.isFalseSn( v, a )
346           if tt[0]:
347             print 'INFO[A3]: Substituting ',v,a,tt
348             vd2[v] = (1, tt[1])
349           else:
350             vd2[v] = (1, a)
351           ##print 'MULTIPLE VALUES: ',v,att,av
352     else:
353      print "WARNING[X4]: ",xxx, 'Zero length element: %s' % v
354
355  def chkDims( self, reqh=None):
356    pass
357   
358class typecheck1:
359  def __init__( self, m, thisatts,helper=None):
360    self.type2Atts = ['positive','comment', 'long_name', 'modeling_realm', 'out_name', 'standard_name', 'type', 'units', 'flag_meanings', 'flag_values']
361    self.type3Atts = ['positive','long_name','modeling_realm', 'out_name', 'standard_name', 'type', 'units', 'flag_meanings', 'flag_values']
362    self.type4Atts = ['positive','modeling_realm', 'out_name', 'standard_name', 'type', 'units', 'flag_meanings', 'flag_values']
363    self.type2Atts = ['positive','comment', 'long_name', 'modeling_realm', 'out_name', 'standard_name', 'type', 'units']
364    self.type3Atts = ['positive','long_name','modeling_realm', 'out_name', 'standard_name', 'type', 'units']
365    self.type4Atts = ['positive','modeling_realm', 'standard_name', 'type', 'units']
366    self.m = m
367    vars = m.vars
368    vdict = m.vdict
369    self.helper=helper
370    td = m.td
371    vd2 = {}
372    type1, type2, type3, type4, type5 = [[],[],[],[],[],] 
373    vd2 = {}
374    for v in vars:
375     l = vdict[v]
376     dl = map( lambda x: string.join( td[x][v][0] ), l )
377     vd2[v] = str( uniquify( dl ) )
378    json.dump( vd2, open( 'mipInfo.json', 'w' ) )
379    for v in vars:
380     l = vdict[v]
381     l.sort()
382     if len(l) == 1: 
383       type1.append(v)
384     elif len(l) > 1:
385       adict = {}
386       for att in thisatts:
387         if att == '__dimensions__':
388           atl = map( lambda x: (string.join( td[x][v][0] ),x), l )
389         else:
390           atl = map( lambda x: (td[x][v][1].get(att,'__ABSENT__'),x), l )
391         atl.sort( tupsort(0).cmp )
392         a0 = atl[0][0]
393         if a0 == None:
394           a0 = ""
395         av = [a0,]
396         for a,tab in atl[1:]:
397           if a == None:
398             a = ""
399           if a != av[-1]:
400             if self.helper != None and self.helper.applycv:
401               thisok=False
402               pmatch = False
403               for cond,src,targ in self.helper.canonvar:
404                 if string.find(a,src) != -1 or  string.find(av[-1],src) != -1:
405                   ##print 'Potential match ---- ',a
406                   ##print src,'###',targ
407                   ##print av[-1]
408                   pmatch = True
409                 if self.helper.checkCond( tab, v, cond ):
410                   if self.helper.match(string.replace( a, src, targ ), av[-1]) or self.helper.match(string.replace( av[-1], src, targ ), a):
411                     thisok = True
412               if thisok:
413                 print 'INFO[typecheck]: conditional match found', tab, v
414               else:
415                 if pmatch:
416                   ##print '########### no matvh found'
417                   pass
418                 av.append(a)
419             else:
420               av.append(a)
421         adict[att] = av
422       
423## check for type 2
424       tval = None
425       ##if adict[ 'positive' ] == ['__ABSENT__']:
426       if all( map( lambda x: len(adict[x]) == 1, self.type2Atts )):
427           tval = 2
428       elif all( map( lambda x: len(adict[x]) == 1, self.type3Atts )):
429           tval = 3
430       elif all( map( lambda x: len(adict[x]) == 1, self.type4Atts )):
431           tval = 4
432       else:
433           l = map( lambda x: '%s:%s, ' % (x,len(adict[x]) ), self.type2Atts )
434       if tval == 2:
435         type2.append( v)
436       elif tval == 3:
437         type3.append( v)
438       elif tval == 4:
439         type4.append( v)
440       else:
441         type5.append(v)
442    xx = float( len(vars) )
443    print "INFO[XXX]", string.join( map( lambda x: '%s (%5.1f%%);' % (x,x/xx*100), [len(type1), len(type2), len(type3), len(type4), len(type5)] ) )
444    self.type1 = type1
445    self.type2 = type2
446    self.type3 = type3
447    self.type4 = type4
448    self.type5 = type5
449
450  def exportHtml( self, typecode ):
451
452    allAtts = ['__dimensions__', 'cell_methods', 'comment', 'long_name', 'modeling_realm', 'out_name', 'standard_name', 'type', 'units', 'valid_max', 'valid_min', 'positive', 'ok_max_mean_abs', 'ok_min_mean_abs', 'flag_meanings', 'flag_values']
453    fixedType1Tmpl = """:%(standard_name)s [%(units)s]</h3>
454        %(__dimensions__)s<br/>
455        %(long_name)s<br/>
456       realm: %(modeling_realm)s; out_name: %(out_name)s; type: %(type)s, <br/>
457       cell_methods: %(cell_methods)s; comment: %(comment)s<br/>
458"""
459    fixedType2TmplA = """:%(standard_name)s [%(units)s]</h3>
460        %(long_name)s<br/>
461       realm: %(modeling_realm)s; out_name: %(out_name)s; type: %(type)s, <br/>
462       comment: %(comment)s<br/>
463"""
464    fixedType2TmplB = "<li>%s [%s]: %s -- (%s,%s,%s,%s)</li>\n"
465       
466    fixedType3TmplA = """:%(standard_name)s [%(units)s]</h3>
467       realm: %(modeling_realm)s; out_name: %(out_name)s; type: %(type)s <br/>
468"""
469    fixedType3TmplB = "<li>%s [%s]: %s: %s [%s]</li>\n"
470    fixedType4TmplB = "<li>%s [%s]: %s [%s]</li>\n"
471    fixedType5TmplA = """ [%(units)s]</h3>
472       out_name: %(out_name)s; type: %(type)s <br/>
473"""
474    fixedType5TmplB = "<li>%s [%s]: %s, %s [%s]: %s, %s:: %s, %s</li>\n"
475       
476    if typecode == 1:
477      oo = open( 'type1.html', 'w' )
478      self.type1.sort()
479      ee = {}
480      for v in self.type1:
481        tab = self.m.vdict[v][0]
482        if not ee.has_key(tab):
483          ee[tab] = []
484        ee[tab].append( v )
485      keys = ee.keys()
486      keys.sort()
487      for k in keys:
488         oo.write( '<h2>Table %s</h2>\n' % k )
489         for v in ee[k]:
490            try:
491              etmp = {}
492              for a in allAtts:
493                etmp[a] = self.m.td[k][v][1].get( a, 'unset' )
494              etmp['__dimensions__'] = string.join( self.m.td[k][v][0] )
495              oo.write( '<h3>' + v + (fixedType1Tmpl % etmp) )
496            except:
497              print k, self.m.td[k][v][1].keys()
498              raise
499      oo.close()
500    elif typecode == 2:
501      oo = open( 'type2.html', 'w' )
502      self.type2.sort()
503      oo.write( '<h2>Variables with fixed attributes</h2>\n' )
504      for v in self.type2:
505            l = self.m.vdict[v]
506            etmp = {}
507            for a in allAtts:
508                etmp[a] = self.m.td[l[0]][v][1].get( a, 'unset' )
509            oo.write( '<h3>' + v + (fixedType2TmplA % etmp) )
510            oo.write( '<ul>\n' )
511            for t in l:
512              dims = string.join( self.m.td[t][v][0] )
513              sa = tuple( [t,dims,] + map( lambda x: self.m.td[t][v][1].get( x, 'unset' ), ['cell_methods','valid_max', 'valid_min', 'ok_max_mean_abs', 'ok_min_mean_abs'] ) )
514              oo.write( fixedType2TmplB % sa )
515            oo.write( '</ul>\n' )
516      oo.close()
517           
518    elif typecode in [3,4,5]:
519      oo = open( 'type%s.html' % typecode, 'w' )
520      thistype,h2,al,tmplA,tmplB = { 3:(self.type3,"Variables with varying comment",['long_name','comment','cell_methods'], fixedType3TmplA, fixedType3TmplB),
521                      4:(self.type4,"Variables with varying long_name",['long_name','cell_methods'],fixedType3TmplA, fixedType4TmplB),
522                      5:(self.type5,"Remaining variables",['standard_name','long_name','out_name', 'modeling_realm','positive','type','units'],fixedType5TmplA, fixedType5TmplB) }[typecode]
523 ##['positive','modeling_realm', 'out_name', 'standard_name', 'type', 'units']
524      thistype.sort()
525      oo.write( '<h2>%s</h2>\n' % h2 )
526      for v in thistype:
527            l = self.m.vdict[v]
528            etmp = {}
529            for a in allAtts:
530                etmp[a] = self.m.td[l[0]][v][1].get( a, 'unset' )
531            oo.write( '<h3>' + v + (tmplA % etmp) )
532            oo.write( '<ul>\n' )
533            for t in l:
534              dims = string.join( self.m.td[t][v][0] )
535              sa = tuple( [t,dims,] + map( lambda x: self.m.td[t][v][1].get( x, 'unset' ), al ) )
536              oo.write( tmplB % sa )
537            oo.write( '</ul>\n' )
538      oo.close()
539           
540class run(object):
541
542  def __init__(self):
543    pass
544
545  def  run(self):
546    self.m = mipCo( mips ) 
547    self.json()
548    al = []
549    for k0 in self.m.dd.keys():
550      for k1 in self.m.dd[k0].keys():
551        al += self.m.dd[k0][k1][0].keys()
552    ald = uniquify( al )
553    ald.sort()
554    i = ald.index('standard_name')
555    ald.pop(i)
556    ald = ['standard_name', ] + ald
557    self.ald = ald
558
559    return self.m,ald
560
561  def getTupList(self):
562    vl = []
563    keys = self.m.vdict.keys()
564    keys.sort()
565    for k in keys:
566      for t in self.m.vdict[k]:
567  ##NT_var = collections.namedtuple( 'mip',['name','sn','snStat','realm','units','longName','comment'] )
568        sn, r, units, ln, c = map( lambda x: self.m.td[t][k][1].get(x,None), ['standard_name','modeling_realm','units','long_name','comment'] ) 
569        mipid = string.split(t,'_')[0]
570        if c == '':
571          c = None
572        v = NT_var( k, sn, 'exists', r, units, ln, c,mipid )
573        vl.append(v)
574    self.tupList = vl
575    return vl
576
577  def compTupList(self):
578    tl1 = uniquify(self.tupList)
579    tl2 = [tl1[0],]
580###  these lines comment on all differences of variables with the same name, including differences in comments.
581    for t in tl1[1:]:
582      if t[:7] == tl2[-1][:7]:
583        pass
584      elif t[:3] == tl2[-1][:3] and t[4:6] == tl2[-1][4:6]:
585        if (t.mip == 'CMIP5' and tl2[-1].mip == 'CCMI1') or (t.mip == 'CCMI1' and tl2[-1].mip == 'CMIP5'):
586          tl2[-1] = t
587        else:
588          print 'What to do??'
589          print tl2[-1]
590          print t
591      else:
592        tl2.append(t)
593    return tl1, tl2
594
595  def runchecks(self):
596    self.v = runcheck1( self.m, self.ald, isAxes=False )
597## check consistency of dimension
598    self.r2 = runcheck1( self.m, self.ald, isAxes=True )
599    return self.v, self.r2
600
601  def json(self):
602    keys = self.m.adict.keys()
603    keys.sort()
604    fh = open( 'axes_json.txt', 'w' )
605    for k in keys:
606      ee = self.m.dd[self.m.adict[k][0]][k][0]
607      ee["__name__"] = k
608      fh.write( json.dumps( ee ) + '\n' )
609    fh.close()
610
611ms = mipTableScan()
612snc = snlist()
613snl, snla = snc.gen_sn_list( )
614snsubber = snsub()
615
616mips = { "cmip5":NT_mip( 'cmip5','cmip5_vocabs/mip/', 'CMIP5_*' ),
617"ccmi":NT_mip( 'ccmi', 'ccmi_vocabs/mip/', 'CCMI1_*'),
618"pmip":NT_mip( 'pmip', 'pmip3_vocabs/mip/', 'PMIP3_*'),
619"cordex":NT_mip( 'cordex', 'cordex_vocabs/mip/', 'CORDEX_*'),
620"specs":NT_mip( 'specs', 'specs_vocabs/mip/', 'SPECS_*') }
621
622mipl = ['pmip']
623mipl = mips.keys()
624mips = map( lambda x: mips[x], mipl )
625r = run()
626
627m,ald = r.run()
628
629tl = r.getTupList()
630tl1,tl2 = r.compTupList()
631v,r2 = r.runchecks()
632
633allatts = ms.al
634thisatts = ['standard_name','units','long_name','__dimensions__']
635## need to have standard name first.
636for a in allatts:
637  if a not in thisatts:
638    thisatts.append(a)
639
640h = helper()
641s = typecheck1( m, thisatts, helper=h)
642s.exportHtml( 1 )
643s.exportHtml( 2 )
644s.exportHtml( 3 )
645s.exportHtml( 4 )
646s.exportHtml( 5 )
Note: See TracBrowser for help on using the repository browser.