source: CMIP6dreqbuild/trunk/src/workbook/importWbMods.py @ 988

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/workbook/importWbMods.py
Revision 988, 16.4 KB checked in by mjuckes, 3 years ago (diff)

check

Line 
1from utils_wb import workbook
2import string, collections, uuid, shelve
3import xlrd
4import importWbRef
5import loadcf
6##import ivg
7
8nt__varGroup = collections.namedtuple( 'varGroup', ['uid','label','title','mip','ref','refNote'] )
9
10
11class loadVarGroupInfo20(object):
12  def __init__(self):
13    sh = shelve.open( '../framework/inSh/sh__requestScoping', 'r' )
14    ks = [k for k in sh.keys() if k[0] != '_']
15    self.link2uid = {}
16    self.vglab2uid = {}
17    for k in ks:
18      assert k[-3:] in ['__1','__0'], 'Unexpected key in sh__requestScoping: %s' % k
19      if k[-3:] == '__0':
20        self.vgid2linklab[k[:3]] = sh[k]
21      else:
22        self.vglab2uid[k[:3]] = sh[k]
23
24class loadGroups(object):
25  def __init__(self):
26    wb = workbook( '../framework/ingest/sortedVarGroups.xls' )
27    sh = wb.book.sheet_by_name( 'Sheet1' )
28    self.vg = {}
29    self.uidByLabel = {}
30   
31    for i in range( sh.nrows ):
32      rr = [x.value for x in sh.row(i)]
33      if len(rr[0]) > 0 and rr[0][0] != '#':
34        uid, label, title, mip, ref, refNote = [rr[x] for x in [7,0,5,1,8,6] ]
35        assert uid not in self.vg, 'DUPLICATE variable group id: %s\n%s\n%s\n' % (uid,str(self.vg[uid]),str([uid, label, title, mip, ref, refNote]) )
36        self.vg[uid] = nt__varGroup._make( [uid, label, title, mip, ref, refNote] )
37        assert label not in self.uidByLabel, 'DUPLICATE variable group label: %s' % label
38        self.uidByLabel[label] = uid
39     
40
41class loadMipMaps(object):
42  def __init__(self,mip):
43    nt__mapr = collections.namedtuple( 'mapr', ['vid1','sn','lab1','vid2','lab2','group','mip','k','kk','table','freq'] )
44    knownMips = {'SIMIP':'simipMap2.csv'}
45    assert mip in knownMips, 'mip %s not recognised' % mip
46    ##['CFMIP-OImon', '64c8d0c2-9671-11e5-b0d6-ac72891c3257', 'sea_ice_thickness', 'sit', 0, 1, 'f081b01e-960a-11e5-a98a-ac72891c3257', 'sithick']
47    ii = open('inputs/%s' % knownMips[mip] )
48    self.records = []
49    for l in ii.readlines():
50      rr = [string.strip(x) for x in string.split( l, '\t') ]
51      rr[7] = int(rr[7])
52      rr[8] = int(rr[8])
53      self.records.append( nt__mapr._make(  rr ) )
54    self.ss = collections.defaultdict( list )
55    self.ee = {}
56    for r in self.records:
57      self.ss[r.vid1].append( r )
58      self.ee[r.lab1] = r.lab2
59
60class loadStr(object):
61  def __init__(self):
62    """Information on structure records. cmmap [dict] defines how to map old cell methods string to new.
63            cminfo .. provides a tuple (title,label,uid) for each cell methods string"""
64
65    wb = xlrd.open_workbook( 'inputs/structRef.xls' )
66    sh = shelve.open( '../framework/inSh/structRef', 'r' )
67    self.uidByLab = {}
68    for k in sh.keys():
69      if k[0] != '_':
70        u,l = sh[k][7:9]
71        self.uidByLab[l] = u
72    sh.close()
73
74    sh = shelve.open( '../framework/inSh/structRef02', 'r' )
75    for k in sh:
76      if k not in self.uidByLab:
77        self.uidByLab[k] = sh[k]
78    sh.close()
79    ii = open( 'inputs/strUidMap.txt' )
80    for l in ii.readlines():
81      k,v = l.strip().split()
82      if k not in self.uidByLab:
83        self.uidByLab[k] = v
84   
85
86    self.lookupinfo = {'cols':['temp. shape','spat. shape','odims','coords','cmeth','cmea','flags']}
87    self.lookup = {}
88    self.labMap = {}
89    self.uidMap = {}
90    self.mods = collections.defaultdict(dict)
91
92
93    for s in wb.sheet_names():
94      sht = wb.sheet_by_name( s )
95      for i in range(1,sht.nrows):
96        r = [x.value for x in sht.row(i)]
97        xx = r[0]
98        if len(xx) > 8 and xx[0] == '*' and (xx[8] == ':' or xx[9] == ':'):
99            ixc = xx.index( ':' )
100            self.labMap[r[1]] = xx[1:ixc]
101            self.uidMap[self.uidByLab[r[1]]] = self.uidByLab[xx[1:ixc]]
102            print 'INFO.str.00010: ',s,r[1],xx[1:ixc],self.uidByLab[r[1]],self.uidByLab[xx[1:ixc]]
103
104        if s != '__mods__':
105        ### tlab, splab, odims, coords, cell_met, cell_mea, flag mean
106          t = (s,r[3],r[4],r[5],r[6],r[7],r[8])
107          if t in self.lookup:
108            if self.lookup[t] == r[1]:
109              print 'INFO:loadstr.00015: skipping preset lookup: %s' % r[1]
110            elif r[1] in self.labMap and self.lookup[t] in self.labMap and self.labMap[r[1]] == self.labMap[self.lookup[t] ]:
111              print 'INFO:loadstr.00010: duplicate lookup tuple, automating redirect [a]: ',t
112              self.lookup[t] = self.labMap[r[1]]
113            elif r[1] in self.labMap and self.labMap[r[1]] == self.lookup[t]:
114              print 'INFO:loadstr.00011: duplicate lookup tuple, automating redirect [b]: ',t
115            elif self.lookup[t] in self.labMap and self.labMap[self.lookup[t] ] == r[1]:
116              print 'INFO:loadstr.00012: duplicate lookup tuple, automating redirect [c]: ',t
117              self.lookup[t] = r[1]
118            else:
119              print 'SEVERE:loadstr.0001: duplicate lookup tuple: ',t
120              print 'SEVERE.loadstr.0002: ',r[1], self.lookup[t]
121          print 'INFO.loadstr.00022: ',r[1],t
122          self.lookup[t] = r[1]
123## Label        Title   Spatial shape   Other dims      coords  cell methods    cell measures   flag meanings   flag values     Spatial shape (title)   Spatial dimensions
124        if len(xx) > 8 and xx[0] == '@':
125          a,b = xx[1:].split( '=' )
126          if a in [ 'cell_measures','cell_methods']:
127            self.mods[r[1]][a] = b
128          else:
129            print 'SEVERE.loadstr.0002: unrecognised directive [%s]: %s' % (r[1],a)
130
131class loadVars(object):
132  def __init__(self,opt=1,map01=None):
133    cf = loadcf.cf()
134    self.loadRevisedSn()
135    if opt == 0:
136      wb = workbook( 'inputs/var.xls' )
137    else:
138      wb = workbook( 'inputs/vars_20170326.xls' )
139    #x = ['label', 'title', 'description', 'procComment', 'procnote', 'prov', 'provmip', 'sn', 'units', 'uid','defaultp','replaced_by']
140    #nt_var = collections.namedtuple( 'var', x )
141
142    self.mapx1 = {}
143    ii = open( 'inputs/simip_rename.csv', 'r' )
144    for l in ii.readlines():
145      bits = string.split( string.strip( l ), '\t' )
146      if bits[1] != '*':
147        print 'ERROR: unexpected line in inputs/simip_rename.csv: ',l
148      else:
149        self.mapx1[bits[4]]  = bits[2]
150    ii.close()
151
152    self.d1 = collections.OrderedDict()
153    self.c1 = collections.defaultdict(list)
154    d2 = {}
155    s1 = wb.book.sheet_by_name(u'var')
156    ssn = set()
157    for i in range(s1.nrows):
158      try:
159        rr = [x.value for x in s1.row(i)]
160        if rr[0][0] != '#':
161          uid = rr[9]
162          assert uid not in self.d1, 'Duplicate uid in var.xls: %s, %s' % (uid,str(rr) )
163          try:
164            rr[10] = int( rr[10] )
165          except:
166            print 'FATAL.type: ',rr
167            raise
168
169          assert rr[0].find('_') == -1, 'FATAL ERROR: underscore in variable name : %s' % str(rr)
170
171          var = rr[0]
172          if var in self.snbyvar:
173            kk = var
174            ssn.add( var )
175            ix = self.snbyvar[kk]
176            ##print '%s:: %s, %s: %s' % (var, rr[7], self.snrecs[ix][7], self.snrecs[ix][9])
177            snx = self.snrecs[ix][9]
178            if snx[-1] == '?':
179              snx = snx[:-1]
180            cfok = rr[7]  in cf.names or rr[7] in cf.alias
181            if snx not in cf.names and snx not in cf.alias:
182               if cfok:
183                 print 'ERROR.sn.02008: Attempt replace valid standard name: %s: %s' % (var,snx)
184               else:
185                 print 'WARN.sn.02005: Inserting invalid standard name: %s: %s [replace: %s]' % (var,snx,rr[7])
186                 rr[7] = snx
187            else:
188              rr[7] = snx
189          elif var in self.snbyvar2:
190
191            snx = self.snbyvar2[var][4]
192            if snx[-1] == '?':
193              snx = snx[:-1]
194            if snx not in cf.names and snx not in cf.alias:
195               print 'ERROR.sn.02009: Attempt to impose invalid standard name: %s: %s' % (var,self.snbyvar2[var])
196            else:
197              if snx not in cf.names:
198                 print 'WARN.sn.02009: Imposing standard name alias: %s: %s [%s]' % (var,self.snbyvar2[var],cf.alias[snx])
199              rr[7] = snx
200              print 'INFO.sn.02002: updating standard name: %s [%s]' % (rr[7],var)
201         
202          self.d1[uid] = [str(x) for x in rr]
203          self.c1[rr[0]].append( uid )
204          if string.strip( rr[11] ) != '':
205            d2[uid] = (string.strip(rr[11]),rr[0] )
206      except:
207        print rr
208        raise
209
210    snf = set( self.snbyvar.keys() ).difference( ssn )
211    assert len( list(snf) ) == 0, 'Difference in var lists %s: check inputs/reviewedSN.xls' % str(snf)
212
213    mm = []
214    mmm = []
215
216    self.vmap= {}
217    for k in d2:
218      if d2[k][0] not in self.c1:
219        mm.append( (d2[k],k) )
220      elif len( self.c1[ d2[k][0] ] ) > 1:
221        mmm.append( (k,   d2[k][0], self.c1[ d2[k][0] ] ) )
222      else:
223        self.vmap[k] = self.c1[ d2[k][0] ][0]
224
225
226    if map01 != None:
227      for k in map01:
228    ##for k in self.mapx1:
229        u1 = None
230        u2 = None
231        if len( self.c1[k] ) == 1:
232          u1  =  self.c1[k][0]
233        else:
234          print 'ERROR: ambigous variable label: %s' % k
235        k2 = map01[k]
236        if len( self.c1[k2] ) == 1:
237          u2  =  self.c1[k2][0]
238        else:
239          print 'ERROR: ambigous variable label: %s' % k2
240        if None not in [u1,u2]:
241           self.vmap[u1] = u2
242           rr = self.d1[u1]
243           print 'WARN.obsolete.001: ambigous variable label: %s, %s, %s' % (k2,u1,u2)
244           self.d1[u1] = rr
245    assert len( mm ) == 0, 'Mappings not all valid: %s' % str(mm)
246    assert len( mmm ) == 0, 'Mappings not all unambiguous: %s' % str(mmm)
247
248  def loadRevisedSn(self):
249    wb = workbook( 'inputs/reviewedSN.xls' )
250
251    sht = wb.book.sheet_by_name( 'Sheet1' )
252    self.snrecs = []
253    self.snbyvar = {}
254    self.snbyvar2 = {}
255    self.snix = collections.defaultdict( list )
256    self.snix0 = collections.defaultdict( dict )
257    ix = -1
258    for i in range( sht.nrows ):
259      rr = [str(x.value) for x in sht.row(i)]
260      var = rr[6]
261      vn = string.replace( var, '_', '-' )
262      sn0 = rr[7]
263      sn1 = rr[9]
264      flg = rr[10]
265      if flg[:2] == 'ex' and var[-1:] != '*':
266        self.snrecs.append(rr)
267        ix += 1
268        assert vn not in self.snbyvar, 'Duplicate variable name %s' % vn
269        self.snbyvar[vn] = ix
270        self.snix0[sn0][vn] = ix
271        self.snix[sn1].append( vn )
272    ii = open( 'inputs/varStandardNameUpdates.csv', 'r' )
273    for l in ii.readlines():
274      rr = l.strip().split( '\t' )
275      if rr[0][0] != '#' and rr[2] in ['2','6']:
276        if rr[1] in self.snbyvar2:
277          assert rr[3:] == self.snbyvar2[rr[1]][3:], 'Duplication of variable names in varStandardNameUpdates.csv: %s' % (str(rr),str(self.snbyvar2[rr[1]]) )
278        else:
279          self.snbyvar2[rr[1]] = rr
280    ii.close()
281   
282class loadFixes(object):
283  def __init__(self):
284    wb = workbook( 'CMIP6_issues_and_fixes.xls' )
285
286    self.d1 = {}
287    self.fixcmv = {}
288    self.fixcmvx = collections.defaultdict( list )
289    self.fixcmvextra = collections.defaultdict( dict )
290    self.d3 = {}
291    self.fixcmvinfo = ['label','uid','table','mode','uid2','prov']
292    s1 = wb.book.sheet_by_name(u'var')
293    for i in range(1,s1.nrows):
294      rr = [x.value for x in s1.row(i)]
295      if string.find( rr[0], '::' ) != -1:
296        a,b = string.split( rr[0], '::' )
297        assert str(a ) not in self.d1, 'Duplicate variable name in var sheet: %s' % rr[0]
298        rr[0] = b
299        self.d1[a] = rr
300      else:
301        assert str(rr[0] ) not in self.d1, 'Duplicate variable name in var sheet: %s' % rr[0]
302        self.d1[  str(rr[0]) ] = rr
303 
304    self.relations = []
305    self.relationlinks = []
306    self.relationinfo = ['label','title','description','uid','relation']
307    self.relationlinkinfo = ['label','title','uid','rlid','rid']
308    for fn in ['cmvDup_04.xls', 'cmvDup_06.xls', 'cmvDup_08.xls']:
309      self.loadCmvDup(fn=fn)
310    self.loadCmvDup002()
311    self.checkFix()
312
313    for i in sorted( self.fixcmvx.keys() ):
314      if len( self.fixcmvx[i] ) > 1:
315         print 'WARN.fixcmv.001: duplicated entries:',i
316         for k in self.fixcmvx[i]:
317           if k in self.fixcmv:
318              print 'WARN.fixcmv.00101: ',k,self.fixcmv[k]
319           else:
320              print 'WARN.fixcmv.00102: ', k
321      else:
322        print 'INFO.fixcmv.00103: ',i,self.fixcmvx[i][0]
323
324  def checkFix(self):
325    cc = collections.defaultdict( int )
326    kk = 0
327    targs = dict()
328    rms = set()
329    for u,r in self.fixcmv.items():
330      assert u == r[1], 'Bad record: %s -- %s' % (u,str(r))
331      cc[r[3]] += 1
332      kk += 1
333      if r[3] == 'replace':
334         targs[ r[4] ] = u
335      if r[3] in ['replace','delete']:
336         rms.add( u )
337
338    for k in sorted( cc.keys() ):
339      print 'INFO.cmvfix.01001: action %s: %s (%s)' % (k,cc[k],kk)
340
341    se1 = {u for u in rms if u in targs}
342    if len(se1) > 0:
343      print 'SEVERE.cmvfix.09001: %s target variables deleted' % len(se1)
344      for u in se1:
345        uu = targs[u]
346        print 'SEVERE.cmvfix.09002: %s -- %s \n %s ----- %s' % (u,str( self.fixcmv[u] ), uu, str( self.fixcmv[uu] ) )
347      assert False, 'Errors fatal'
348
349  def loadCmvDup002( self, fn='cmv_duplication.csv' ):
350    ii = open( 'inputs/' + fn, 'r' )
351    for l in ii.readlines():
352      bits = l.strip().split('\t')
353      if bits[0] == 'NEXT':
354        var = bits[4]
355      elif bits[0] == '+':
356        if bits[1] != '':
357          uid = bits[2]
358          toid = bits[1]
359          tab = bits[3]
360          prov = bits[6]
361          self.fixcmv[uid] = (var,uid,tab,'replace',toid,prov,fn)
362         
363  def loadCmvDup( self, fn='cmvDup_01.xls' ):
364    ##self.fixcmvinfo = ['label','uid','table','mode','uid2','prov']
365    wb = workbook( 'inputs/' + fn )
366    items = []
367    sht = wb.book.sheet_by_name( 'Sheet1' )
368    item = {'__file__':fn }
369    for i in range( sht.nrows ):
370      r = sht.row(i)
371      if r[0].value == '####':
372        items.append( item )
373        item = {'__file__':fn }
374      elif r[0].value == '@VAR:':
375        item['__var__'] = r
376      else:
377        id = str( r[2].value )
378        if id == '':
379          print 'WARN .. multiple variables encountered and not dealt with ....'
380        else:
381          item[id] = r
382          for x in r[:2]:
383            if str( x.value ) != '':
384              item['__flag__'] = True
385
386    knownrelations = {'tm':('masking','Different Masking'), 'tv':('vertical','Different Vertical Structure'), \
387                      'txy':('spatial','Different spatial structure'), \
388                      'ttm':('time-mean','Different temporal processing')}
389    for i in items:
390       if not i.get('__flag__',False):
391         ##print 'Skipping item: ',i
392         pass
393       else:
394         cc = collections.defaultdict( list )
395         for k in i:
396           if k[0] != '_':
397             r = [ str( x.value ) for x in i[k] ]  + [i['__file__'],]
398             u2 = r[1]
399             opt = r[0]
400             if r[3] in [ 'prsn','prlq','pr']:
401                  print 'INFO.prxx.0001: ',r
402           
403             self.fixcmvx[  '%s.%s.%s' % (r[3],r[7],r[9]) ].append( k )
404             if u2 != '':
405               assert u2 in i, 'Attempt to replace with unrecognised uid: %s ... \n %s' % (u2, str(i) )
406               rr = [r[3],k,r[7], 'replace', u2,r[9],i['__file__']] 
407
408               if k in self.fixcmv:
409                  print 'ERROR.cmv.0001: duplicate record: ',self.fixcmv[k],rr
410
411               self.fixcmv[k] = rr
412               self.fixcmvextra['cmvDup'][k] = r
413
414             if opt != '' and opt != 'xxx':
415               if string.find(opt,' ') != -1:
416                 for o in string.split( opt ):
417                   cc[o].append(k)
418               else:
419                 cc[opt].append(k)
420
421         for o in cc:
422           assert len( cc[o] ) > 1, 'Attempt to encode singleton relationship: %s .. %s' % (o,str(i))
423           assert o in knownrelations, 'Key not recognised %s .... %s' % (o,str(i) )
424           rlid = str( uuid.uuid1() )
425           s = list( { str( i[k][3].value ) for k in cc[o] } )
426           assert len( s ) == 1, 'Multiple labels'
427           lab = string.replace(s[0], '-', '' )
428           reln = knownrelations[o]
429           self.relations.append( ['%s__%s' % (o,lab), '%s [%s]' % (lab,reln[0]), reln[1], rlid, reln[0] ] )
430           kkk = 0
431           for k in cc[o]:
432             r = i[ k ]
433             kkk+=1
434             t,v,p = tuple( [str( r[j].value ) for j in [7,3,9] ] )
435             tvp = (t,v,p)
436             self.relationlinks.append( (['%s__%s_%s' % (o,lab,kkk), '%s [%s] {%s}' % (lab,reln[0],kkk),str( uuid.uuid1() ), rlid, k], tvp) )
437           
438 
439class run(object):
440  def __init__(self):
441    self.fix = loadFixes()
442    self.ls = importWbRef.loadSpatial()
443    self.cm = importWbRef.loadCmorDims()
444    self.cellm = importWbRef.loadCellm()
445    self.mmsi = loadMipMaps( 'SIMIP' )
446    self.vars = loadVars(map01=self.mmsi.ee)
447    self.str = loadStr()
448    self.vg = loadGroups()
449
450if __name__ == '__main__':
451  r = run()
Note: See TracBrowser for help on using the repository browser.