source: FCC2/trunk/source/comp_mip.py @ 63

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/FCC2/trunk/source/comp_mip.py@63
Revision 63, 9.0 KB checked in by mjuckes, 8 years ago (diff)

comp_mip update for CCMI

Line 
1from fcc_utils import mipTableScan
2import re, os, string
3
4ml = ['CORDEX_3h', 'CORDEX_6h', 'CORDEX_Aday', 'CORDEX_day', 'CORDEX_grids', 'CORDEX_mon' ]
5ml = ['CORDEX_3h', 'CORDEX_6h', 'CORDEX_fx', 'CORDEX_day', 'CORDEX_mon', 'CORDEX_sem' ]
6ml = ['CCMI1_Amon_v1_complete']
7newMip = 'CCMI'
8ml2 = ['CMIP5_3hr', 'CMIP5_6hrPlev', 'CMIP5_Amon', 'CMIP5_cfDay', 'CMIP5_cfOff', 'CMIP5_day', 'CMIP5_grids', 'CMIP5_Lmon', 'CMIP5_OImon', 'CMIP5_Oyr',
9       'CMIP5_6hrLev', 'CMIP5_aero', 'CMIP5_cf3hr', 'CMIP5_cfMon', 'CMIP5_cfSites', 'CMIP5_fx', 'CMIP5_LImon', 'CMIP5_Oclim', 'CMIP5_Omon'] 
10ml2 = ['CMIP5_3hr', 'CMIP5_6hrPlev', 'CMIP5_Amon', 'CMIP5_cfDay', 'CMIP5_cfOff', 'CMIP5_day', 'CMIP5_grids', 'CMIP5_Lmon',
11       'CMIP5_6hrLev', 'CMIP5_aero', 'CMIP5_cf3hr', 'CMIP5_cfMon', 'CMIP5_cfSites', 'CMIP5_fx', 'CMIP5_LImon'] 
12
13cfsntab = 'cf-standard-name-table.xml'
14cordex_dkrz = 'CORDEX_variables_requirement_table_upgedated-1.csv'
15cordex_dkrz = 'CORDEX_variables_requirement_table_all.csv'
16cordex_dkrz_pat = 'cordex_dkrz/CORDEX_variables_requirement_table_%s.csv'
17cordex_dkrz_pat = 'cordex_dkrz_sep12/CORDEX_variables_requirement_table_%s.csv'
18re_sn = re.compile( 'entry id="(.*)"' )
19re_sna = re.compile( 'alias id="(.*)"' )
20##alias id="atmosphere_water_vapor_content"
21##entry id="age_of_sea_ice"'
22def gen_sn_list( pathn ):
23  assert os.path.isfile( pathn ), '%s not found ' % pathn
24  snl = []
25  snla = []
26  for l in open(pathn).readlines():
27    m = re_sn.findall(l )
28    if len(m) > 0:
29      for i in m:
30        snl.append( i )
31    m = re_sna.findall(l )
32    if len(m) > 0:
33      for i in m:
34        snla.append( i )
35  return (snl,snla)
36
37def tlist_to_dict( ll ):
38
39   ee = {} 
40   for l in ll:
41     ee[l[0]] = ( l[1], l[2] )
42   return ee
43
44class comp:
45
46  def __init__(self, snl, snla=None, ec1=None,tag=None):
47    self.id = 'comp'
48    self.snl = snl
49    self.snla = snla
50    self.ec1 = ec1
51    self.tag=tag
52
53
54  def comp(self, e1, e2,checkCellMethods=False,tag=None ):
55    self.tag=tag
56   
57    ##e1 = tlist_to_dict( t1 )
58    ##e2 = tlist_to_dict( t2 )
59
60    checkAll = True
61    keys = e1.keys()
62    keys.sort()
63    for k in keys:
64      e0 = 0
65      f2 = False
66      f3 = False
67      f4 = False
68      if e1[k][1]['standard_name'] in [None,'None']:
69        print 'ERROR[A]: standard name for %s not set' % k
70      elif e1[k][1]['standard_name'] not in self.snl:
71        if e1[k][1]['standard_name'] not in self.snla:
72          print 'ERROR[0]: standard name %s for %s [%s] not in snl or snla' % (e1[k][1]['standard_name'], k, e1[k][2] )
73        else:
74          print 'WARNING: standard name %s for %s not in snl' % (e1[k][1]['standard_name'], k )
75      if self.ec1 != None:
76        if k not in self.ec1.keys():
77          print 'ERROR[1]: variable %s [%s] not in CORDEX variable requirements list' % (k,e1[k][2])
78          vrln = None
79        else:
80          vrln = self.ec1[k][1]
81          if e1[k][1]['long_name'] != self.ec1[k][1]:
82            f2 = True
83          if checkCellMethods: 
84            if e1[k][1]['cell_methods'] != self.ec1[k][3]:
85              if not (e1[k][1]['cell_methods']=="None" and string.strip(self.ec1[k][3]) == "time:"):
86                f3 = True
87          if checkAll: 
88            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] != ''):
89                f4 = True
90            elif e1[k][1].has_key( 'positive' ):
91              if e1[k][1]['positive'] != self.ec1[k][4]:
92                if not (e1[k][1]['positive']=="None" and string.strip(self.ec1[k][4]) == ""):
93                  f4 = True
94            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] != ''):
95                f4 = True
96            elif e1[k][1].has_key( 'modeling_realm' ):
97              if e1[k][1]['modeling_realm'] != self.ec1[k][5]:
98                if not (e1[k][1]['modeling_realm']=="None" and string.strip(self.ec1[k][5]) == ""):
99                  f4 = True
100       
101      cks = ['units', 'long_name', 'standard_name']
102      suppress4B = True
103      if k in e2.keys():
104        if e1[k][1] != e2[k][1]:
105          ne1 = 0
106          nmm = []
107          for k2 in cks:
108             if e1[k][1][k2] != e2[k][1][k2]:
109                ne1 += 1
110                nmm.append(k2)
111          if ne1 > 0:
112                print 'ERROR[4A]: Anomaly bewteen MIP tables: %s:: %s ' % (k, str(nmm) )
113          else:
114             if not suppress4B:
115                print 'ERROR[4B]: Anomaly bewteen MIP tables: %s:: %s -- %s [%s]' % (k, str(e1[k][1]), str( e2[k][1] ), vrln )
116          e0 = 1
117        else:
118          ##print '%s OK -- %s -- %s' % (k,str(e1[k][1]), str( e2[k][1] ) )
119          e0 = 2
120      else:
121        ##print '%s not in table 2' % k
122        e0 = 3
123
124      xxx = k
125      if self.tag != None:
126         xxx += '[%s]' % self.tag
127      if self.ec1 != None:
128        if f2 and (e0 == 2):
129           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])
130        elif f2 and (e0 == 3):
131           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])
132        elif f2:
133           print 'ERROR[5]: Difference between CORDEX MIP tables and VR %s: %s --- %s' % (xxx,e1[k][1]['long_name'], self.ec1[k][1])
134        if f3:
135           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])
136        if f4:
137           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])
138       
139base='/home/users/prototype/cordex/exarch/FCC2/trunk/work/'
140snl,snla = gen_sn_list( base + cfsntab )
141print 'Len snl = %s' % len(snl)
142
143dkrz_cordex_version = 3
144ec1 = {}
145if dkrz_cordex_version == 1:
146  ll = open( base + cordex_dkrz ).readlines()
147  for l in ll[9:74]:
148    bits = string.split( l, ',' )
149    var = bits[1]
150    ln = bits[13]
151    sn = bits[14]
152    if sn not in snl + snla:
153      print 'ERROR: CORDEX DKRZ sn %s for %s not in snl/snla' % (sn, var)
154    ec1[var] = ( sn,ln)
155elif dkrz_cordex_version == 2:
156  for tab in ['3hr','6hr','day','mon','sem','fx']:
157     ll = open( base + cordex_dkrz_pat % tab ).readlines()
158     for l in ll[3:]:
159        bits = string.split( l, ',' )
160        if (tab != 'fx' and len( bits ) != 7) or (tab == 'fx' and len( bits ) != 5):
161          print 'cant safely parse %s [%s]' % (l,tab)
162#1,sund,Duration of Sunshine,duration_of_sunshine,s,sum,
163        var,ln,sn,units = bits[1:5]
164        if tab != 'fx':
165          cm,pos = bits[5:7]
166        else:
167          cm,pos = [None,None]
168        if sn not in snl + snla:
169           print 'ERROR: CORDEX DKRZ [%s] sn %s for %s not in snl/snla' % (tab,sn, var)
170        ec1[var] = ( sn,ln,units,cm,pos)
171elif dkrz_cordex_version == 3:
172  eeee = {}
173  eca = {}
174  ll = open( base + cordex_dkrz_pat % 'all' ).readlines()
175  for l in ll[2:]:
176        bits = string.split( string.strip(l), ',' )
177        if string.strip(bits[0]) == '':
178           break
179#1,sund,Duration of Sunshine,duration_of_sunshine,s,sum,
180        var,units = bits[1:3]
181        ln,sn,pos,realm   = bits[12:16]
182        if sn not in snl + snla:
183           print 'ERROR: CORDEX DKRZ [%s] sn %s for %s not in snl/snla' % ('all',sn, var)
184        assert pos in ['','up','down'], 'Unexpected value for pos [%s] in %s' % (pos,l)
185        eca[var] = ( units,ln,sn,pos,realm )
186
187  for tab in ['3hr','6hr','day','mon','sem','fx']:
188     ee  = {}
189     ll = open( base + cordex_dkrz_pat % tab ).readlines()
190     for l in ll[2:]:
191        bits = string.split( l, ',' )
192        if string.strip(bits[0]) == '':
193           break
194#1,sund,Duration of Sunshine,duration_of_sunshine,s,sum,
195        var,cm = bits[1:3]
196        cm = 'time: ' + cm
197        units,ln,sn,pos,realm = eca[var] 
198        ec1[var] = ( sn,ln,units,cm,pos,realm)
199        ee[var] = ( sn,ln,units,cm,pos,realm)
200     eeee[tab] = ee
201
202newMipDir = '/cordex_vocabs/mip/'
203mpat = 'CORDEX_%s'
204newMipDir = '/ccmi_vocabs/mip/'
205mpat = 'CCMI1_%s_v1_complete'
206def validate( t,cc ):
207  if t == 'all':
208    l1 = {}
209    l2 = {}
210    for m in ml:
211      l1 = ms.scan_table( open( base + newMipDir + m ).readlines(), None, asDict=True, appendTo=l1, lax=True, tag=m)
212    for m in ml2:
213      l2 = ms.scan_table( open( base + '/cmip5_vocabs/mip/' + m ).readlines(), None, asDict=True, appendTo=l2, lax=True, tag=m)
214    ccm = False
215  else:
216    l2 = {}
217    for m in ml2:
218      l2 = ms.scan_table( open( base + '/cmip5_vocabs/mip/' + m ).readlines(), None, asDict=True, appendTo=l2, lax=True, tag=m)
219    k = { '3hr':'3h', '6hr':'6h' }.get( t,t )
220    l1 = ms.scan_table( open( base + newMipDir + mpat % k ).readlines(), None, asDict=True)
221    ccm = True
222  cc.comp( l1, l2, checkCellMethods=ccm, tag=t )
223
224tlist = ['3hr','6hr','day','mon','sem','fx']
225tlist = ['Amon']
226for tab in tlist:
227  ms = mipTableScan()
228  print 'Validating table %s ' % tab
229  if newMip == 'CCMI':
230    ec1 = None
231  else:
232    ec1=eeee[tab]
233    print eeee[tab].keys()
234  c = comp( snl,snla=snla, ec1=ec1)
235  validate(tab,c)
Note: See TracBrowser for help on using the repository browser.