source: CCCC/trunk/ceda_cc/extractMipInfo.py @ 217

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

updates tp extractMipInfo

Line 
1
2import collections, glob, string
3from fcc_utils2 import mipTableScan, snlist
4from config_c4 import CC_CONFIG_DIR
5
6ms = mipTableScan()
7snc = snlist()
8
9snl, snla = snc.gen_sn_list( )
10NT_mip = collections.namedtuple( 'mip',['label','dir','pattern'] )
11vlist = [
12('uas',
13"eastward_wind",
14'Eastward Near-Surface Wind Speed',
15'Eastward Near-Surface Wind',
16'WRONG LONG NAME (*speed* included)'),
17('vas',
18"northward_wind",
19'Northward Near-Surface Wind Speed',
20'Northward Near-Surface Wind',
21'WRONG LONG NAME (*speed* included)'),
22("snc",
23"surface_snow_area_fraction",
24"Snow Area Fraction",
25"Surface Snow Area Fraction",
26"WRONG LONG NAME (*surface* omitted)"),
27("prsn",
28"snowfall_flux", 
29"Solid Precipitation",
30"Snowfall Flux",
31"WRONG LONG NAME"),
32("tntscpbl",
33"tendency_of_air_temperature_due_to_stratiform_cloud_and_precipitation_and_boundary_layer_mixing",
34"Tendency of Air Temperature due to Stratiform Cloud Condensation and Evaporation",
35"Tendency of Air Temperature Due to Stratiform Cloud and Precipitation and Boundary Layer Mixing",
36'WRONG LONG NAME'),
37("tas",
38"air_temperature",
39"Air Temperature",
40"Near-Surface Air Temperature",
41'WRONG LONG NAME'),
42("cfadDbze94",
43"histogram_of_equivalent_reflectivity_factor_over_height_above_reference_ellipsoid",
44"CloudSat Radar Reflectivity CFAD",
45"CloudSat Radar Reflectivity",
46"INCONSISTENT LONG NAME"),
47("cfadLidarsr532",
48"histogram_of_backscattering_ratio_over_height_above_reference_ellipsoid",
49"CALIPSO Scattering Ratio CFAD",
50"CALIPSO Scattering Ratio",
51"INCONSISTENT LONG NAME"),
52("cl",
53"cloud_area_fraction_in_atmosphere_layer",
54"Cloud Area Fraction",
55"Cloud Area Fraction in Atmosphere Layer",
56"INCONSISTENT LONG NAME"),
57("clcalipso",
58"cloud_area_fraction_in_atmosphere_layer",
59"CALIPSO Cloud Fraction",
60"CALIPSO Cloud Area Fraction",
61'WRONG LONG NAME'),
62("cltisccp",
63"cloud_area_fraction",
64"ISCCP Total Total Cloud Fraction",
65"ISCCP Total Cloud Fraction",
66'WRONG LONG NAME'),
67("reffclwc",
68"effective_radius_of_convective_cloud_liquid_water_particle",
69"Convective Cloud Droplet Effective Radius",
70"Hydrometeor Effective Radius of Convective Cloud Liquid Water",
71'INCONSISTENT LONG NAMES'),
72("reffclws",
73"effective_radius_of_stratiform_cloud_liquid_water_particle",
74'Stratiform Cloud Droplet Effective Radius',
75'Hydrometeor Effective Radius of Stratiform Cloud Liquid Water',
76'INCONSISTENT LONG NAMES' ) ]
77
78class snsub:
79
80  def __init__(self):
81    pass
82
83  def isFalseSn(self,var,sn):
84    if sn == 'mole_concentration_of_molecular_oxygen_in_sea_water':
85      return (True,'mole_concentration_of_dissolved_molecular_oxygen_in_sea_water', 'INVALID STANDARD NAME')
86    elif var == 'rldscs' and sn == 'downwelling_longwave_flux_in_air_assuming_clear_sky':
87      return (True,'surface_downwelling_longwave_flux_in_air_assuming_clear_sky','WRONG STANDARD NAME (should be surface)' )
88    elif var == 'clisccp' and sn == 'cloud_area_fraction_in_atmosphere_layer':
89      return (True, 'isccp_cloud_area_fraction', 'WRONG STANDARD NAME (should be isccp)' )
90    return (False,'no match','')
91
92  def isFalseLn(self,var,ln):
93    for tt in vlist:
94       if var == tt[0] and ln == tt[2]:
95         return (True, tt[3], tt[4] )
96    return (False,'no match','')
97
98snsubber = snsub()
99
100mips = ( NT_mip( 'cmip5','cmip5_vocabs/mip/', 'CMIP5_*' ),
101         NT_mip( 'ccmi', 'ccmi_vocabs/mip/', 'CCMI1_*')  )
102mips = ( NT_mip( 'cmip5','cmip5_vocabs/mip/', 'CMIP5_*' ),
103          )
104
105cmip5_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']
106
107class mipCo:
108
109  def __init__(self,mips):
110    self.vl0 = []
111    self.tl = []
112    self.td = {}
113    for mip in mips:
114      self._scan(mip)
115
116  def _scan(self,mip):
117   
118 ## dl = glob.glob( '%s%s' % (mip.dir,mip.pattern) )
119    dl = glob.glob( '%s/%s%s' % (CC_CONFIG_DIR, mip.dir,mip.pattern) )
120    dl.sort()
121    for d in dl:
122      tab = string.split( d, '/')[-1]
123      isoceanic = tab[:7] == "CMIP5_O"
124      l2 = ms.scan_table( open( d ).readlines(), None, asDict=True, lax=True, tag="x", warn=True)
125      l2k = []
126      for k in l2.keys():
127        if k not in cmip5_ignore:
128          l2k.append(k)
129      l2k.sort()
130      self.vl0 += l2k
131      self.tl.append( [tab,l2, l2k,isoceanic] )
132      self.td[tab] = l2
133
134    self.vl0.sort()
135    self.vl = []
136    self.vl.append( self.vl0[0] )
137    self.vdict = { self.vl[0]:[] }
138    for v in self.vl0[1:]:
139      if v != self.vl[-1]:
140        self.vl.append(v)
141        self.vdict[v] = []
142
143    for t in self.tl:
144      for k in t[2]:
145        self.vdict[k].append(t[0])
146
147    self.vars = self.vdict.keys()
148    self.vars.sort()
149    ##for v in self.vars:
150      ##l = self.vdict[v]
151      ##l.sort()
152##  print v, l, td[l[0]][v][1].get('standard_name','__NO_STANDARD_NAME__')
153
154class runcheck1:
155  def __init__( self, m, thisatts):
156    vars = m.vars
157    vdict = m.vdict
158    td = m.td
159    vd2 = {}
160    for v in vars:
161     l = vdict[v]
162     l.sort()
163     if len(l) > 1:
164       for att in thisatts:
165       ##for att in ['standard_name','units']:
166         if att == '__dimensions__':
167           atl = map( lambda x: string.join( td[x][v][0] ), l )
168           print '#######', v,l,atl
169         else:
170           atl = map( lambda x: td[x][v][1].get(att,'__ABSENT__'), l )
171         atl.sort()
172         av = [atl[0],]
173         for a in atl[1:]:
174           if a != av[-1]:
175             av.append(a)
176         if att == 'standard_name':
177           for a in av:
178             if a not in snl and a not in snla:
179               print "INVALID STANDARD NAME: ",a
180         if len(av) > 1:
181           ee = {}
182   
183           for a in [True,False]:
184             ee[a] = []
185   
186           isol = []
187           for x in l:
188             a = td[x][v][1].get(att,'__ABSENT__')
189             try:
190              if att == 'standard_name' or ( att == 'long_name' and vd2[v][0] == 2):
191               iso = x[:7] == 'CMIP5_O'
192               tt = snsubber.isFalseSn( v, a )
193              elif att == 'long_name':
194               tt = snsubber.isFalseLn( v, a )
195               dims = td[x][v][0]
196               iso = 'depth0m' in dims
197              else:
198               iso = False
199               tt = (False,)
200         ##    iso = False
201             except:
202               print att,v
203               raise
204             isol.append((iso,x))
205             if tt[0]:
206               print 'Substituting ',v,a,tt
207               ee[iso].append( tt[1] )
208             else:
209               ee[iso].append( a )
210   
211           for a in [True,False]:
212             ok = True
213             if len(ee[a]) > 1 :
214               for x in ee[a][1:]:
215                 if x != ee[a][0]:
216                   ok = False
217   
218             if not ok:
219                print 'E001: Multiple values : ',att,v
220                for t in isol:
221                  if t[0] == a:
222                    tab = t[1]
223                    if att in ['standard_name','long_name']:
224                      print tab,td[tab][v][1].get('standard_name','__ABSENT__'),td[tab][v][1].get('long_name','__ABSENT__')
225                    else:
226                      print tab,td[tab][v][1].get(att,'__ABSENT__')
227                   
228           if att == "standard_name":
229             vd2[v] = (2,[ee[True],ee[False]] )
230         else:
231           if att == "standard_name":
232             tt = snsubber.isFalseSn( v, av[0] )
233             if tt[0]:
234               print 'Substituting ',v,av[0],tt
235               vd2[v] = (1, tt[1])
236             else:
237               vd2[v] = (1, av)
238     elif len(l) == 1:
239           tab = vdict[v][0]
240           a = td[tab][v][1].get('standard_name','__ABSENT__')
241           tt = snsubber.isFalseSn( v, a )
242           if tt[0]:
243             print 'Substituting ',v,a,tt
244             vd2[v] = (1, tt[1])
245           else:
246             vd2[v] = (1, a)
247           ##print 'MULTIPLE VALUES: ',v,att,av
248     else:
249      print 'Zero length element: %s' % v
250     
251   
252class typecheck1:
253  def __init__( self, m, thisatts):
254    self.type2Atts = ['positive','comment', 'long_name', 'modeling_realm', 'out_name', 'standard_name', 'type', 'units', 'flag_meanings', 'flag_values']
255    self.type3Atts = ['positive','modeling_realm', 'out_name', 'standard_name', 'type', 'units', 'flag_meanings', 'flag_values']
256    self.type4Atts = ['positive','modeling_realm', 'out_name', 'standard_name', 'type', 'units', 'flag_meanings', 'flag_values']
257    self.m = m
258    vars = m.vars
259    vdict = m.vdict
260    td = m.td
261    vd2 = {}
262    type1, type2, type3, type4, type5 = [[],[],[],[],[],] 
263    for v in vars:
264     l = vdict[v]
265     l.sort()
266     if len(l) == 1: 
267       type1.append(v)
268     elif len(l) > 1:
269       adict = {}
270       for att in thisatts:
271         if att == '__dimensions__':
272           atl = map( lambda x: string.join( td[x][v][0] ), l )
273           print '#######', v,l,atl
274         else:
275           atl = map( lambda x: td[x][v][1].get(att,'__ABSENT__'), l )
276         atl.sort()
277         av = [atl[0],]
278         for a in atl[1:]:
279           if a != av[-1]:
280             av.append(a)
281         adict[att] = av
282       
283## check for type 2
284       tval = None
285       ##if adict[ 'positive' ] == ['__ABSENT__']:
286       if all( map( lambda x: len(adict[x]) == 1, self.type2Atts )):
287           tval = 2
288       elif all( map( lambda x: len(adict[x]) == 1, self.type3Atts )):
289           tval = 3
290       else:
291           l = map( lambda x: '%s:%s, ' % (x,len(adict[x]) ), self.type2Atts )
292           ## print '%s: t3:: ' % v,string.join(l)
293       if tval == 2:
294         type2.append( v)
295       elif tval == 3:
296         type3.append( v)
297       else:
298         type4.append(v)
299    xx = float( len(vars) )
300    print string.join( map( lambda x: '%s (%5.1f%%);' % (x,x/xx*100), [len(type1), len(type2), len(type3), len(type4)] ) )
301    self.type1 = type1
302    self.type2 = type2
303    self.type3 = type3
304    self.type4 = type4
305
306  def exportHtml( self, typecode ):
307
308    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']
309    fixedType1Tmpl = """:%(standard_name)s [%(units)s]</h3>
310        %(__dimensions__)s<br/>
311        %(long_name)s<br/>
312       realm: %(modeling_realm)s; out_name: %(out_name)s; type: %(type)s, <br/>
313       cell_methods: %(cell_methods)s; comment: %(comment)s<br/>
314"""
315    fixedType2TmplA = """:%(standard_name)s [%(units)s]</h3>
316        %(long_name)s<br/>
317       realm: %(modeling_realm)s; out_name: %(out_name)s; type: %(type)s, <br/>
318       comment: %(comment)s<br/>
319"""
320    fixedType2TmplB = "<li>%s [%s]: %s -- (%s,%s,%s,%s)</li>\n"
321       
322    fixedType3TmplA = """:%(standard_name)s [%(units)s]</h3>
323       realm: %(modeling_realm)s; out_name: %(out_name)s; type: %(type)s <br/>
324"""
325    fixedType3TmplB = "<li>%s [%s]: %s: %s [%s]</li>\n"
326       
327    if typecode == 1:
328      oo = open( 'type1.html', 'w' )
329      self.type1.sort()
330      ee = {}
331      for v in self.type1:
332        tab = self.m.vdict[v][0]
333        if not ee.has_key(tab):
334          ee[tab] = []
335        ee[tab].append( v )
336      keys = ee.keys()
337      keys.sort()
338      for k in keys:
339         oo.write( '<h2>Table %s</h2>\n' % k )
340         for v in ee[k]:
341            try:
342              etmp = {}
343              for a in allAtts:
344                etmp[a] = self.m.td[k][v][1].get( a, 'unset' )
345              etmp['__dimensions__'] = string.join( self.m.td[k][v][0] )
346              oo.write( '<h3>' + v + (fixedType1Tmpl % etmp) )
347            except:
348              print k, self.m.td[k][v][1].keys()
349              raise
350      oo.close()
351    elif typecode == 2:
352      oo = open( 'type2.html', 'w' )
353      self.type2.sort()
354      oo.write( '<h2>Variables with fixed attributes</h2>\n' )
355      for v in self.type2:
356            l = self.m.vdict[v]
357            etmp = {}
358            for a in allAtts:
359                etmp[a] = self.m.td[l[0]][v][1].get( a, 'unset' )
360            oo.write( '<h3>' + v + (fixedType2TmplA % etmp) )
361            oo.write( '<ul>\n' )
362            for t in l:
363              dims = string.join( self.m.td[t][v][0] )
364              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'] ) )
365              oo.write( fixedType2TmplB % sa )
366            oo.write( '</ul>\n' )
367      oo.close()
368           
369    elif typecode == 3:
370      oo = open( 'type3.html', 'w' )
371      self.type3.sort()
372      oo.write( '<h2>Variables with varying long_name/comment</h2>\n' )
373      for v in self.type3:
374            l = self.m.vdict[v]
375            etmp = {}
376            for a in allAtts:
377                etmp[a] = self.m.td[l[0]][v][1].get( a, 'unset' )
378            oo.write( '<h3>' + v + (fixedType3TmplA % etmp) )
379            oo.write( '<ul>\n' )
380            for t in l:
381              dims = string.join( self.m.td[t][v][0] )
382              sa = tuple( [t,dims,] + map( lambda x: self.m.td[t][v][1].get( x, 'unset' ), ['long_name','comment','cell_methods'] ) )
383              oo.write( fixedType3TmplB % sa )
384            oo.write( '</ul>\n' )
385      oo.close()
386           
387m = mipCo( mips ) 
388
389allatts = ms.al
390thisatts = ['standard_name','units','long_name','__dimensions__']
391## need to have standard name first.
392for a in allatts:
393  if a not in thisatts:
394    thisatts.append(a)
395s =typecheck1( m, thisatts)
396s.exportHtml( 1 )
397s.exportHtml( 2 )
398s.exportHtml( 3 )
Note: See TracBrowser for help on using the repository browser.