source: CMIP6dreqbuild/trunk/src/framework/ing02/updOmip.py @ 1224

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/framework/ing02/updOmip.py
Revision 1224, 12.3 KB checked in by mjuckes, 2 years ago (diff)

01.00.26

Line 
1import shelve, collections, os
2import loadcf
3
4class flaggedDict(dict):
5  flag = collections.defaultdict( bool )
6
7class loadLnMods(object):
8  def __init__(self,ifile='inputs/OMIP_BGC_CHEM_changes_20180531.txt' ):
9    assert os.path.isfile(ifile), 'Input file not found: %s' % ifile
10
11    self.ii = [x for x in [l.strip() for l in open( ifile ).readlines()] if x != '' and x[0] != '#']
12    self.cc = collections.defaultdict( dict )
13
14    self.parse()
15
16  def parse(self):
17    tab = None
18    for l in self.ii:
19      if l[0] == ':':
20        tab = l.split()[0][2:]
21      else:
22        v,ln = [x.strip() for x in l.split(' ',1)]
23        self.cc[tab][v] = ln
24     
25   
26
27class upd(object):
28  oh = ['uid', 'comment', 'deflate_level', 'shuffle', 'ok_max_mean_abs', 'flag_meanings', 'type', 'ok_min_mean_abs', 'sn', 'deflate', 'title', 'valid_min', 'cell_methods', 'flag_values', 'cell_measures', 'out_name', 'modeling_realm', 'units', 'cell_methods_xx', 'valid_max', 'positive', 'var', 'mipTable', 'dimensions', 'vid', 'processing', 'gpid','rowIndex','ssect', 'priority']
29  ih = [u'label', u'mipTable', u'description', u'frequency', u'defaultPriority', u'deflate', u'deflate_level', u'mipTableSection', u'modeling_realm', u'mtid', u'positive', u'processing', u'prov', u'provNote', u'rowIndex', u'shuffle', u'stid', u'subGroup', u'title', u'type', u'uid', u'vid']
30  nt__refso = collections.namedtuple( 'refso', oh )
31  nt__l1sh = collections.namedtuple( 'l1sh', ih )
32  ixoh = nt__refso._make( range(len(oh)) ) 
33  ixih = nt__l1sh._make( range(len(ih)) )
34
35  cf = loadcf.cf()
36  def __init__(self):
37    self.sh = shelve.open( '../inSh/sh__refso_OMIP', 'r' )
38    lnm = loadLnMods()
39    self.lncc = lnm.cc
40
41  def close(self):
42    self.sh.close()
43
44
45  def update(self,go=False):
46    """Update:
47          (1) Standard names in var;
48          (2) Structures in CMORvar;
49          (3) Priorities in requestVar;
50       Remove:
51          (1) Redundant variables (defined as Oyr or Omon-2d at the same priority as Omon-3d)
52    """
53    redundant = [u'dissic', u'ph', u'po4', u'talk'] + [u'arag', u'calc', u'co3', u'co3abio', u'co3nat', u'co3satarag', u'co3satcalc', u'detoc', u'dissoc', u'nh4', u'zooc'] + [u'bacc', u'phycalc', u'phydiat', u'phydiaz', u'phymisc', u'phypico', u'zmeso', u'zmicro', u'zmisc']
54    ##
55    ##new priorities ... for Oyr, Omon-2d, Omon-3d
56    ##
57    redundant_pmap = {u'bacc': (2, 2, 3), u'co3satcalc': (2, 2, 3), u'phydiaz': (2, 2, 3), u'zmicro': (2, 2, 3), u'phydiat': (2, 2, 3), u'zmisc': (2, 2, 3), u'co3nat': (2, 2, 3), u'co3': (2, 2, 3), u'co3abio': (2, 2, 3), u'co3satarag': (2, 2, 3), u'ph': (1, 1, 2), u'calc': (2, 2, 3), u'detoc': (2, 2, 3), u'po4': (1, 1, 2), u'dissoc': (2, 2, 3), u'zmeso': (2, 2, 3), u'nh4': (2, 2, 3), u'arag': (2, 2, 3), u'phymisc': (2, 2, 3), u'phypico': (2, 2, 3), u'zooc': (2, 2, 3), u'dissic': (1, 1, 2), u'phycalc': (2, 2, 3), u'talk': (1, 1, 2)}
58
59##[u'longitude latitude olevel time', u'longitude latitude time', u'longitude latitude time depth0m', u'longitude latitude time depth100m', u'longitude latitude time olayer100m']
60    strids = {'longitude latitude time depth0m':('f9495c2e-80ba-11e6-ab6e-5404a60d96b5','str-a061'),
61              'longitude latitude olevel time':('f7e4000e-562c-11e6-a2a4-ac72891c3257','str-157'),
62              'longitude latitude time depth100m':('f948813c-80ba-11e6-ab6e-5404a60d96b5', 'str-a015'),
63              'longitude latitude time':('e9f9f6ca-c1ce-11e6-8067-ac72891c3257','str-a098'),
64              ('longitude latitude time','area: mean where sea depth: sum where sea time: mean'):('63c064e0-15f2-11e7-87e0-5404a60d96b5','str-d02'),
65              'longitude latitude time olayer100m':('63c0988e-15f2-11e7-87e0-5404a60d96b5','str-d06')
66             }
67##[u'str-157', u'str-a015', u'str-a061', u'str-a098', u'str-d02', u'str-d06']
68    shi = shelve.open( 'exports/l1sh/CMORvar' )
69    shv = shelve.open( 'exports/l1sh/var' )
70    shst = shelve.open( 'exports/l1sh/structure', 'r' )
71    shsp = shelve.open( 'exports/l1sh/spatialShape', 'r' )
72    shrqv = shelve.open( 'exports/l1sh/requestVar' )
73    ns = 0
74
75    ## index of variables in data request inputs ..
76    cmvix = dict()
77    tables = ['Omon','Oyr','Oday']
78    for k in shi.keys():
79      if k[0] != '_':
80        if shi[k][self.ixih.mipTable] in tables:
81          cmvix[ ( shi[k][self.ixih.mipTable] , shi[k][self.ixih.label] ) ] = k
82
83    ### index of variables in OMIP tables.
84    irecix = collections.defaultdict( dict)
85    for k in self.sh.keys():
86      if k[0] != '_':
87        if self.sh[k][self.ixoh.mipTable] in tables:
88          if self.sh[k][self.ixoh.var] not in ['pdi', 'dpocdtcalc', 'dpocdtpico', 'dpocdtdiaz', 'dms','prlq','zhalf']:
89            irecix[ self.sh[k][self.ixoh.mipTable] ][ self.sh[k][self.ixoh.var] ] = k
90
91    ## Omon, Omon-3d, Omon-oth
92    rqvgs = ['ef12e542-5629-11e6-9079-ac72891c3257','efc154f6-5629-11e6-9079-ac72891c3257','efc143a8-5629-11e6-9079-ac72891c3257']
93    remove_cmv = set()
94    remove_rqv = set()
95    pupdate = flaggedDict()
96
97    ## these variables were removed in 01.00.24
98    remove_redundant = False
99    if remove_redundant:
100      for v in redundant:
101        if ('Oyr',v) in cmvix:
102          remove_cmv.add( cmvix[ ('Oyr',v) ] )
103          if ('Omon','%sos' % v) in cmvix:
104            remove_cmv.add( cmvix[ ('Omon','%sos' % v) ] )
105          else:
106            print 'SEVERE: failed to identify variable to be removed: %s' % v
107            ns += 1
108        else:
109          print 'PROBLEM?: redundant variable not found: %s' % v
110    else:
111      for v,t in redundant_pmap.items():
112        if ('Oyr',v) in cmvix:
113          pupdate[ cmvix[ ('Oyr',v) ] ] = t[0]
114        else:
115          print 'ERROR.3dtr.001: redundant variable not found in Oyr: %s' % v
116        pupdate[ cmvix[ ('Omon',v) ] ] = t[2]
117        tt = ('Omon','%sos' % v)
118        if tt in cmvix:
119          pupdate[ cmvix[ tt ] ] = t[1]
120        else:
121          print 'ERROR.3dtr.002: redundant variable not found in Omon: %sos' % v
122
123    updates = dict()
124    for t in irecix:
125      for v in irecix[t]:
126        if (t,v) not in cmvix:
127           print 'SEVERE: failed to find variable: %s,%s' % (t,v)
128           ns += 1
129        else:
130           cmv = cmvix[(t,v)]
131           if cmv not in remove_cmv:
132             k = irecix[t][v]
133             r = self.sh[k]
134             p = str( int( float( r[self.ixoh.priority] ) ) )
135             if cmv in pupdate:
136                print 'INFO.pmap: mapping %s,%s priority %s --> %s' % (t,v,p,pupdate[cmv])
137                p = pupdate[cmv]
138                pupdate.flag[cmv] = True
139             dims = r[self.ixoh.dimensions]
140             sn = r[self.ixoh.sn]
141             cm = r[self.ixoh.cell_methods]
142             sect = r[self.ixoh.ssect]
143             if t == 'Omon' and sect.find( 'bgc' ) != -1:
144               if (dims,cm) in strids:
145                 stru,strl = strids[(dims,cm)]
146               else:
147                 stru,strl = strids[dims]
148             else:
149               stru = strl = None
150             updates[cmv] = (t,v,p,sn,cm,dims,stru,strl)
151
152    if all( [pupdate.flag[t] for t in pupdate] ):
153      print 'All 3d-tracer priority updates implemented'
154    else:
155      for t in sorted( pupdate.keys() ):
156        print 'ERROR: 3d-tracer priority update missed: %s' % t
157
158    iv = shrqv['__cols__'].index( 'vid' )
159    isn = shv['__cols__'].index( 'sn' )
160    ig = shrqv['__cols__'].index( 'vgid' )
161    ip = shrqv['__cols__'].index( 'priority' )
162    pchange = dict()
163    strchange = dict()
164    snchange = dict()
165    lnchange = dict()
166
167    itab = shi['__cols__'].index( 'mipTable' )
168    ilab = shi['__cols__'].index( 'label' )
169    itt = shi['__cols__'].index( 'title' )
170    for k in shi:
171      if k[0] != '_':
172        if shi[k][itab] in self.lncc and shi[k][ilab] in self.lncc[ shi[k][itab] ]:
173          lnchange[k] = self.lncc[ shi[k][itab] ][ shi[k][ilab] ]
174
175    for k in shrqv:
176      if k[0] != '_':
177        if shrqv[k][iv] in remove_cmv:
178           remove_rqv.add( k )
179        elif shrqv[k][iv] in updates and shrqv[k][ig] in rqvgs:
180           if str( shrqv[k][ip] ) != updates[shrqv[k][iv]][2]:
181              pchange[ k ] = updates[shrqv[k][iv]][2]
182           
183             ## updates[cmv] = (t,v,p,sn,cm,dims,stru,strl)
184    for cmv,tt in updates.items():
185             v = str( shi[cmv][self.ixih.vid] )
186             sn0 = shv[v][isn]
187             s = shi[cmv][self.ixih.stid]
188             if sn0 != tt[3] and tt[3] in self.cf.names:
189               if sn0 in self.cf.names:
190                  vlab = shv[v][ shv['__cols__'].index( 'label' ) ]
191                  print 'SEVERE: changing valid cf standard name: %s, %s: %s --> %s' % (v,vlab,sn0,tt[3])
192                  ns += 1
193               snchange[v] = tt[3]
194             if s != tt[6] and tt[6] != None:
195               strchange[cmv] = tt[6]
196
197    print 'UPDATE EVAL DONE', len( remove_cmv ), len( remove_rqv ), ', p:: ',len( pchange.keys() ), len( snchange.keys() ), len( strchange.keys() ), ', ln: ', len( lnchange.keys() )
198    assert ns == 0, 'SEVERE ERRORS ENCOUNTERED: %s' % ns
199    if go:
200      for cmv in strchange:
201        r = shi[cmv]
202        r[self.ixih.stid] = strchange[cmv]
203        shi[cmv] = r[:]
204      for cmv in lnchange:
205        r = shi[cmv]
206        r[itt] = lnchange[cmv]
207        shi[cmv] = r[:]
208      for u in pchange:
209        r = shrqv[u]
210        r[ip] = pchange[u]
211        shrqv[u] = r[:]
212      for v in snchange:
213        r = shv[v]
214        r[isn] = snchange[v]
215        shv[v] = r[:]
216      for cmv in remove_cmv:
217        del shi[cmv]
218      for rqv in remove_rqv:
219        del shrqv[rqv]
220    shi.close()
221    shv.close()
222    shst.close()
223    shsp.close()
224    shrqv.close()
225
226  def eval(self):
227    shi = shelve.open( 'exports/l1sh/CMORvar', 'r' )
228    shst = shelve.open( 'exports/l1sh/structure', 'r' )
229    shsp = shelve.open( 'exports/l1sh/spatialShape', 'r' )
230    shst_spid = shst['__cols__'].index( 'spid' )
231    shsp_label= shsp['__cols__'].index( 'label' )
232    ccx1 = collections.defaultdict( set )
233    ccx1b = collections.defaultdict( set )
234    ccx2 = collections.defaultdict( set )
235
236    for table in ['Omon','Oyr','Oday']:
237      print '############# %s #############' % table
238      s1k = set( [k for k,x in shi.items() if k[0] != '_' and x[self.ixih.mipTable] == table ] )
239      ##s1k = set( [k for k,x in shi.items() if k[0] != '_' and x[self.ixih.mipTable] == table and x[self.ixih.modeling_realm] == 'ocnBgChem'] )
240      s1 = set( [shi[k][self.ixih.label] for k in s1k] )
241      ##s0k = set( [k for k,x in self.sh.items() if k[0] != '_' and x[self.ixoh.mipTable] == table and x[self.ixoh.ssect].find( 'bgc' ) != -1] )
242      s0k = set( [k for k,x in self.sh.items() if k[0] != '_' and x[self.ixoh.mipTable] == table ] )
243      s0 = set( [self.sh[k][self.ixoh.var] for k in s0k] )
244
245      sstr = set()
246      for k in s1k:
247         r = self.nt__l1sh._make( shi[k] )
248         stru = shst[str(r.stid)]
249         sp = shsp[str(stru[shst_spid])]
250         ccx1b[r.label].add( (r.label,table,sp[shsp_label]) )
251         sstr.add( stru[shst['__cols__'].index( 'label' )] )
252      sdim = set()
253      for k in s0k:
254         r = self.nt__refso._make( self.sh[k] )
255         ccx1[r.out_name].add( (r.out_name,r.priority,table,r.dimensions) )
256         sdim.add( r.dimensions )
257
258      print 'NEW: ',len( s0 ), s0.difference( s1 ), sorted( list(sdim) )
259      print 'CURRENT: ',len( s1 ), s1.difference( s0 ), sorted( list( sstr ) )
260      s0xx = set( [k for k in s0k if self.sh[k][self.ixoh.sn] not in self.cf.names] )
261      s0xxa = set( [k for k in s0xx if self.sh[k][self.ixoh.sn][8:] in self.cf.names] )
262      print 'BAD NAMES: ',len(s0xx),len(s0xxa)
263      print sorted( [(self.sh[k][self.ixoh.sn],self.sh[k][self.ixoh.var]) for k in s0xx] )
264    for k in ccx1:
265      if k[-2:] == 'os' and k[:-2] in ccx1:
266        ko = k[:-2]
267      else:
268        ko = k
269      for t in  ccx1[k]:
270        ccx2[ko].add( t )
271    k3 = sorted([k for k in ccx2 if len( ccx2[k] ) > 2] )
272    npp = 0
273    ccy = collections.defaultdict( set )
274    for k in k3:
275      ee = {}
276      for x in ccx2[k]:
277        if x[2] == 'Omon':
278          if x[3].find( 'olevel' ) != -1:
279            ee['Omon-3d'] = x[1]
280          else:
281            ee['Omon-oth'] = x[1]
282        else:
283          ee['Oyr'] = x[1]
284      t = tuple( [ee[i] for i in ['Omon-3d','Oyr','Omon-oth']] )
285      ccy[t].add( k )
286      xx = set( [x[1] for x in ccx2[k]] )
287      if len( xx ) > 1:
288        print k, ccx2[k]
289      else:
290        npp += 1
291    print len(k3), npp
292    for k in sorted( ccy.keys() ):
293      print k,sorted(ccy[k])
294    shi.close()
295    shst.close()
296    shsp.close()
297 
298
299if __name__ == '__main__':
300  u = upd()
301  u.eval()
302  u.update(go=True)
303  u.close()
Note: See TracBrowser for help on using the repository browser.