source: CCCC/trunk/ceda_cc/comp_mip.py @ 212

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

undated comp_mpi

Line 
1from fcc_utils2 import mipTableScan
2from config_c4 import CC_CONFIG_DIR
3import re, os, string
4
5ml = ['CORDEX_3h', 'CORDEX_6h', 'CORDEX_Aday', 'CORDEX_day', 'CORDEX_grids', 'CORDEX_mon' ]
6ml = ['CORDEX_3h', 'CORDEX_6h', 'CORDEX_fx', 'CORDEX_day', 'CORDEX_mon', 'CORDEX_sem' ]
7newMip = 'SPECS'
8newMip = 'CORDEX'
9newMip = 'CCMI'
10ml2 = ['CMIP5_3hr', 'CMIP5_6hrPlev', 'CMIP5_Amon', 'CMIP5_cfDay', 'CMIP5_cfOff', 'CMIP5_day', 'CMIP5_grids', 'CMIP5_Lmon', 'CMIP5_OImon', 'CMIP5_Oyr',
11       'CMIP5_6hrLev', 'CMIP5_aero', 'CMIP5_cf3hr', 'CMIP5_cfMon', 'CMIP5_cfSites', 'CMIP5_fx', 'CMIP5_LImon', 'CMIP5_Oclim', 'CMIP5_Omon'] 
12ml2 = ['CMIP5_3hr', 'CMIP5_6hrPlev', 'CMIP5_Amon', 'CMIP5_cfDay', 'CMIP5_cfOff', 'CMIP5_day', 'CMIP5_grids', 'CMIP5_Lmon',
13       'CMIP5_6hrLev', 'CMIP5_aero', 'CMIP5_cf3hr', 'CMIP5_cfMon', 'CMIP5_cfSites', 'CMIP5_fx', 'CMIP5_LImon'] 
14
15cfsntab = 'cf/cf-standard-name-table.xml'
16cordex_dkrz = 'CORDEX_variables_requirement_table_upgedated-1.csv'
17cordex_dkrz = 'CORDEX_variables_requirement_table_all.csv'
18cordex_dkrz_pat = 'cordex_dkrz/CORDEX_variables_requirement_table_%s.csv'
19cordex_dkrz_pat = 'cordex_dkrz_oct/CORDEX_variables_requirement_table_%s.csv'
20re_sn = re.compile( 'entry id="(.*)"' )
21re_sna = re.compile( 'alias id="(.*)"' )
22##alias id="atmosphere_water_vapor_content"
23##entry id="age_of_sea_ice"'
24def gen_sn_list( pathn ):
25  assert os.path.isfile( pathn ), '%s not found ' % pathn
26  snl = []
27  snla = []
28  for l in open(pathn).readlines():
29    m = re_sn.findall(l )
30    if len(m) > 0:
31      for i in m:
32        snl.append( i )
33    m = re_sna.findall(l )
34    if len(m) > 0:
35      for i in m:
36        snla.append( i )
37  return (snl,snla)
38
39def tlist_to_dict( ll ):
40
41   ee = {} 
42   for l in ll:
43     ee[l[0]] = ( l[1], l[2] )
44   return ee
45
46class comp(object):
47
48  def __init__(self, snl, snla=None, ec1=None,tag=None):
49    self.id = 'comp'
50    self.snl = snl
51    self.snla = snla
52    self.ec1 = ec1
53    self.tag=tag
54
55
56  def comp(self, e1, e2,checkCellMethods=False,tag=None ):
57    self.tag=tag
58   
59    ##e1 = tlist_to_dict( t1 )
60    ##e2 = tlist_to_dict( t2 )
61    self.nn_sn = 0
62    thisSnl = []
63
64    checkAll = True
65    keys = e1.keys()
66    keys.sort()
67    self.nn_var = len(keys)
68    for k in keys:
69      e0 = 0
70      f2 = False
71      f3 = False
72      f4 = False
73      if e1[k][1]['standard_name'] in [None,'None']:
74        if e1[k][1].get('long_name',None) not in [None,'None']:
75          print 'WARNING[A]: standard name for %s [%s] not set' % (k,e1[k][1].get('long_name') )
76        else:
77          print 'WARNING[A]: standard name for %s not set' % k
78      else:
79        if e1[k][1]['standard_name'] not in self.snl:
80          if e1[k][1]['standard_name'] not in self.snla:
81            print 'ERROR[0]: standard name %s for %s [%s] not in snl or snla' % (e1[k][1]['standard_name'], k, e1[k][2] )
82          else:
83            print 'WARNING: standard name %s for %s not in snl' % (e1[k][1]['standard_name'], k )
84            if e1[k][1]['standard_name'] not in thisSnl:
85               thisSnl.append( e1[k][1]['standard_name'] )
86        else:
87            if e1[k][1]['standard_name'] not in thisSnl:
88               thisSnl.append( e1[k][1]['standard_name'] )
89
90      if self.ec1 != None:
91        if k not in self.ec1.keys():
92          print 'ERROR[1]: variable %s [%s] not in CORDEX variable requirements list' % (k,e1[k][2])
93          vrln = None
94        else:
95          vrln = self.ec1[k][1]
96          if e1[k][1]['long_name'] != self.ec1[k][1]:
97            f2 = True
98          if checkCellMethods: 
99            if e1[k][1]['cell_methods'] != self.ec1[k][3]:
100              if not (e1[k][1]['cell_methods']=="None" and string.strip(self.ec1[k][3]) == "time:"):
101                f3 = True
102          if checkAll: 
103            if (e1[k][1].has_key( 'positive' ) and self.ec1[k][4] == '') or ( (not e1[k][1].has_key( 'positive' )) and self.ec1[k][4] != ''):
104                f4 = True
105            elif e1[k][1].has_key( 'positive' ):
106              if e1[k][1]['positive'] != self.ec1[k][4]:
107                if not (e1[k][1]['positive']=="None" and string.strip(self.ec1[k][4]) == ""):
108                  f4 = True
109            if (e1[k][1].has_key( 'modeling_realm' ) and self.ec1[k][5] == '') or ( (not e1[k][1].has_key( 'modeling_realm' )) and self.ec1[k][5] != ''):
110                f4 = True
111            elif e1[k][1].has_key( 'modeling_realm' ):
112              if e1[k][1]['modeling_realm'] != self.ec1[k][5]:
113                if not (e1[k][1]['modeling_realm']=="None" and string.strip(self.ec1[k][5]) == ""):
114                  f4 = True
115       
116      self.nn_sn = len(thisSnl)
117      cks = ['units', 'long_name', 'standard_name']
118      suppress4B = True
119      if k in e2.keys():
120        if e1[k][1] != e2[k][1]:
121          ne1 = 0
122          nmm = []
123          for k2 in cks:
124             if e1[k][1][k2] != e2[k][1][k2]:
125                ne1 += 1
126                nmm.append(k2)
127          if ne1 > 0:
128                v1 = map( lambda x: e1[k][1][x], nmm )
129                v2 = map( lambda x: e2[k][1][x], nmm )
130                print 'ERROR[4A]: Anomaly between MIP tables: %s:: %s -- %s -- %s {%s} ' % (k, str(nmm), str(v1), str(v2), tag )
131          else:
132             if not suppress4B:
133                print 'ERROR[4B]: Anomaly between MIP tables: %s:: %s -- %s [%s]' % (k, str(e1[k][1]), str( e2[k][1] ), vrln )
134          e0 = 1
135        else:
136          ##print '%s OK -- %s -- %s' % (k,str(e1[k][1]), str( e2[k][1] ) )
137          e0 = 2
138      else:
139        ##print '%s not in table 2' % k
140        e0 = 3
141
142      xxx = k
143      if self.tag != None:
144         xxx += '[%s]' % self.tag
145      if self.ec1 != None:
146        if f2 and (e0 == 2):
147           print 'ERROR[2]: Difference between CORDEX/CMIP5 MIP tables and VR: %s:: %s [%s] --- %s' % (k,e1[k][1]['long_name'],e1[k][2], self.ec1[k][1])
148        elif f2 and (e0 == 3):
149           print 'ERROR[3]: Difference between CORDEX MIP tables and VR: %s:: %s [%s] --- %s' % (k,e1[k][1]['long_name'],e1[k][2], self.ec1[k][1])
150        elif f2:
151           print 'ERROR[5]: Difference between CORDEX MIP tables and VR %s: %s --- %s' % (xxx,e1[k][1]['long_name'], self.ec1[k][1])
152        if f3:
153           print 'ERROR[6]: Difference between CORDEX MIP tables and VR in cell_methods: %s:: %s --- %s' % (k,e1[k][1]['cell_methods'], self.ec1[k][3])
154        if f4:
155           print 'ERROR[7]: Difference between CORDEX MIP tables and VR in positive, realm: %s:: %s,%s --- %s' % (xxx,e1[k][1].get('positive','None'),e1[k][1].get('modeling_realm','None'), self.ec1[k][4:6])
156       
157base=CC_CONFIG_DIR
158print base
159snl,snla = gen_sn_list( os.path.join(base, cfsntab) )
160print 'Len snl = %s' % len(snl)
161
162dkrz_cordex_version = 4
163ec1 = {}
164if newMip == 'CORDEX':
165 if dkrz_cordex_version == 1:
166  ll = open( os.path.join(base, cordex_dkrz) ).readlines()
167  for l in ll[9:74]:
168    bits = string.split( l, ',' )
169    var = bits[1]
170    ln = bits[13]
171    sn = bits[14]
172    if sn not in snl + snla:
173      print 'ERROR: CORDEX DKRZ sn %s for %s not in snl/snla' % (sn, var)
174    ec1[var] = ( sn,ln)
175 elif dkrz_cordex_version == 2:
176  for tab in ['3hr','6hr','day','mon','sem','fx']:
177     ll = open( os.path.join(base, cordex_dkrz_pat % tab) ).readlines()
178     for l in ll[3:]:
179        bits = string.split( l, ',' )
180        if (tab != 'fx' and len( bits ) != 7) or (tab == 'fx' and len( bits ) != 5):
181          print 'cant safely parse %s [%s]' % (l,tab)
182#1,sund,Duration of Sunshine,duration_of_sunshine,s,sum,
183        var,ln,sn,units = bits[1:5]
184        if tab != 'fx':
185          cm,pos = bits[5:7]
186        else:
187          cm,pos = [None,None]
188        if sn not in snl + snla:
189           print 'ERROR: CORDEX DKRZ [%s] sn %s for %s not in snl/snla' % (tab,sn, var)
190        ec1[var] = ( sn,ln,units,cm,pos)
191 elif dkrz_cordex_version in [3,4]:
192  eeee = {}
193  eca = {}
194  ll = open( os.path.join(base, cordex_dkrz_pat % 'all') ).readlines()
195  for l in ll[2:]:
196        bits = string.split( string.strip(l), ',' )
197        if dkrz_cordex_version == 4:
198          bits = map( lambda x: string.strip(x, '"' ), bits)
199        if string.strip(bits[0]) == '':
200           break
201#1,sund,Duration of Sunshine,duration_of_sunshine,s,sum,
202        var,units = bits[1:3]
203        ln,sn,pos,realm   = bits[12:16]
204        if sn not in snl + snla:
205           print 'ERROR: CORDEX DKRZ [%s] sn %s for %s not in snl/snla' % ('all',sn, var)
206        assert pos in ['','up','down'], 'Unexpected value for pos [%s] in %s' % (pos,l)
207        eca[var] = ( units,ln,sn,pos,realm )
208
209  for tab in ['3hr','6hr','day','mon','sem','fx']:
210     ee  = {}
211     ll = open( os.path.join(base, cordex_dkrz_pat % tab) ).readlines()
212     for l in ll[2:]:
213        bits = string.split( l, ',' )
214        if dkrz_cordex_version == 4:
215          bits = map( lambda x: string.strip(x, '"' ), bits)
216        if string.strip(bits[0]) == '':
217           break
218#1,sund,Duration of Sunshine,duration_of_sunshine,s,sum,
219        var,cm = bits[1:3]
220        cm = 'time: ' + cm
221        units,ln,sn,pos,realm = eca[var] 
222        ec1[var] = ( sn,ln,units,cm,pos,realm)
223        ee[var] = ( sn,ln,units,cm,pos,realm)
224     eeee[tab] = ee
225
226if newMip == 'SPECS':
227  newMipDir = 'specs_vocabs/mip/'
228  mpat = 'SPECS_%s'
229  ml = ['SPECS_Amon', 'SPECS_fx', 'SPECS_Lmon', 'SPECS_Omon', 'SPECS_6hrLev', 'SPECS_day', 'SPECS_OImon']
230elif newMip == 'CCMI':
231  ml = ['CCMI1_Amon_v2_complete']
232  ml = ['CCMI1_annual_comp-v3.txt', 'CCMI1_daily_comp-v3.txt', 'CCMI1_fixed_comp-v2.txt', 'CCMI1_hourly_comp-v3.txt', 'CCMI1_monthly_comp-v3.txt']
233  ml = ['CCMI1_annual', 'CCMI1_daily', 'CCMI1_fixed', 'CCMI1_hourly', 'CCMI1_monthly']
234  newMipDir = 'ccmi_vocabs/mip/'
235  mpat = 'CCMI1_%s_v1_complete'
236  newMipDir = 'ccmi1-cmor-tables/Tables/'
237elif newMip == 'CORDEX':
238  newMipDir = 'cordex_vocabs/mip/'
239  mpat = 'CORDEX_%s'
240
241def validate( t,cc ):
242  if t == 'all':
243    l1 = {}
244    l2 = {}
245    for m in ml:
246      print 'base: ',base
247      l1 = ms.scan_table( open( os.path.join(base, newMipDir + m) ).readlines(), None, asDict=True, appendTo=l1, lax=True, tag=m, project=newMip)
248    ms.nn_tab = len(ml)
249    for m in ml2:
250      l2 = ms.scan_table( open( os.path.join(base, 'cmip5_vocabs/mip/' + m) ).readlines(), None, asDict=True, appendTo=l2, lax=True, tag=m, warn=False)
251    ms.nn_tab2 = len(ml2)
252    ccm = False
253    tag = " vs. cmip5"
254  else:
255    l2 = {}
256    for m in ml2:
257      l2 = ms.scan_table( open( os.path.join(base, 'cmip5_vocabs/mip/' + m) ).readlines(), None, asDict=True, appendTo=l2, lax=True, tag=m, warn=False)
258    k = { '3hr':'3h', '6hr':'6h' }.get( t,t )
259    l1 = ms.scan_table( open( os.path.join(base, newMipDir + mpat % k) ).readlines(), None, asDict=True, project=newMip)
260    ccm = True
261    tag = t
262  cc.comp( l1, l2, checkCellMethods=ccm, tag=tag )
263
264tlist = ['3hr','6hr','day','mon','sem','fx']
265tlist = ['Amon']
266tlist = ['Amon', 'fx', 'Lmon', 'Omon', '6hrLev', 'day', 'OImon']
267doAll = True
268if doAll:
269    ms = mipTableScan()
270    ec1 = None
271    c = comp( snl,snla=snla, ec1=ec1)
272    validate('all',c)
273    print """Number of tables=%s\nNumber of variables=%s\nNumber of standard names=%s\n""" % (ms.nn_tab,c.nn_var,c.nn_sn)
274else:
275  for tab in tlist:
276    ms = mipTableScan()
277    print 'Validating table %s ' % tab
278    if newMip in ['CCMI','SPECS']:
279      ec1 = None
280    else:
281      ec1=eeee[tab]
282      print eeee[tab].keys()
283    c = comp( snl,snla=snla, ec1=ec1)
284    validate(tab,c)
Note: See TracBrowser for help on using the repository browser.