source: CMIP6dreqbuild/trunk/src/framework/scanDreq.py @ 884

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/framework/scanDreq.py@884
Revision 884, 34.0 KB checked in by mjuckes, 3 years ago (diff)

added key VIACSAB integration code

Line 
1from dreqPy import dreq
2import collections, string, os, utils_wb
3import htmlTemplates as tmpl
4import xml, re, uuid
5import xml.dom, xml.dom.minidom
6import sets
7import xlsxwriter
8
9knowna = [ 'LS3MIP [LWday]', 'LS3MIP [LEday]', 'CFMIP [cf1hrClimMon]', 'HighResMIP [3hr_cloud]',
10           'CFMIP [cf3hr_sim_new]', 'C4MIP [L_3hr]', 'DAMIP [DAMIP_day]', 'DAMIP [DAMIP_3hr_p2]',
11           'DynVar [DYVR_daily_c]', 'PMIP [PMIP-6hr]', 'HighResMIP [1hrLev]', 'PMIP [PMIP-Amon-02]',
12           'PMIP [PMIP-day-02]', 'PMIP [PMIP-aero-02]']
13knownl = [ 'PMIP [PMIP-Lmon-02]']
14knowno = [ 'DAMIP [DAMIP_Omon_p2]', 'FAFMIP [fafOyr]', 'PMIP [PMIP-Omon-02]']
15
16from utils_wb import uniCleanFunc
17from utils_wb import workbook
18
19if os.path.isfile( 'refDefaultP.txt' ):
20  refpix = {}
21  for l in open( 'refDefaultP.txt' ).readlines():
22    bits = string.split( string.strip(l), '\t' )
23    assert len(bits) == 4, 'Bad record found in %s' % 'refDefaultP.txt'
24    refpix[bits[0]] = (bits[1],bits[2], int(bits[3]) )
25else:
26  refpix = None
27
28empty=re.compile('^$')
29
30src1 = '../workbook/trial2_20150831.xml'
31
32dq = dreq.loadDreq(dreqXML=src1)
33inx = dq.inx
34##inx.makeVarRefs()
35ix_rql_uid = {}
36ix_rqvg_uid = {}
37ix_ovar_uid = {}
38ix_gpi_uid = {}
39list_gp_ovar = collections.defaultdict( list )
40xr_var_ovar = collections.defaultdict( list )
41xr_var_gpi = collections.defaultdict( list )
42rql_by_name = collections.defaultdict( list )
43
44def makeVarRefs(uid, var, iref_by_uid):
45    varRefs = {}
46    for thisuid in var.uid.keys():
47      if iref_by_uid.has_key(thisuid):
48        ee1 = collections.defaultdict( list )
49        for k,i in iref_by_uid[thisuid]:
50          thisi = uid[i]
51          sect = thisi._h.label
52          if sect == 'groupItem':
53            ee1[sect].append( '%s.%s' % (thisi.mip, thisi.group) )
54          elif sect == 'ovar':
55            ee1[sect].append( thisi.mipTable )
56          elif sect == 'revisedTabItem':
57            ee1[sect].append( '%s.%s' % (thisi.mip, thisi.table) )
58        varRefs[thisuid] = ee1
59    return varRefs
60
61varRefs = makeVarRefs( inx.uid, inx.var, inx.iref_by_uid)
62
63class addUnits(object):
64  def __init__(self,dq,wbi='units/units.xlsx'):
65    eqs = [('N m-1', 'kg s-2', 'J m-2'), ('Pa', 'N m-2', 'kg m-1 s-2'), ('cm-1','km-1','m-1')     ]
66    eqss = ['N m-1','Pa','m-1','m','s','1','m s-2','m2','m3' ]
67
68    wb = workbook( wbi )
69    sh = wb.book.sheet_by_name('units')
70    self.repl = {}
71    self.uu = {}
72    for j in range(1,sh.nrows):
73      r = sh.row(j)
74      if len(r) > 5 and r[5].value != u'':
75        self.repl[ r[0].value ] = r[5].value
76      else:
77        self.uu[r[0].value] = [x.value for x in r]
78
79    for k in self.repl:
80      if self.repl[k] not in self.uu:
81        print 'Bad replacement found: %s --> %s' % (k,self.repl[k])
82
83    for i in dq.coll['var'].items:
84      if i.units in self.repl:
85        u = self.repl[i.units]
86      else:
87        u = i.units
88      u = string.strip(str(u))
89      if str(u) == '1.0':
90        u = '1'
91      if u not in self.uu:
92        if u == "1.0":
93          if float(u) not in self.uu:
94            print 'UNITS NOT FOUND: %s (%s)' % (u,i.label)
95        else:
96            print 'UNITS NOT FOUND: %s (%s)' % (u,i.label)
97
98  def uid(self,u0):
99    if u0 in self.repl:
100      u = self.repl[u0]
101    else:
102      u = u0
103    if u in self.uu:
104      return self.uu[u][7]
105    elif u == '1.0' and float(u) in self.uu:
106      return self.uu[float(u)][7]
107    else:
108      return None
109
110
111class updates(object):
112  delToks = sets.Set( ['inc','omit'] )
113  def __init__(self,fndup,fnmult,idir='rev1'):
114    assert os.path.isdir( idir ), 'Directory %s not found' % idir
115    self.fdup = '%s/%s' % (idir,fndup)
116    self.fmult = '%s/%s' % (idir,fnmult)
117    for p in [self.fdup,self.fmult]:
118      assert os.path.isfile( p ), 'File %s not found' % p
119    self.repl = {}
120    self.upd = {}
121    self.twins = []
122    self.ddel = {}
123    self.cmvrepl = {}
124
125  def writeCmvUpd( self, inx, fnrp='CMVreplace.csv'):
126    oo = open( fnrp, 'w' )
127    for k in self.cmvrepl.keys():
128      if inx.iref_by_uid.has_key(k):
129        kn = self.cmvrepl[k]
130        for tag,ki  in inx.iref_by_uid[k]:
131           vu = [ inx.uid.has_key(kk) for kk in [k,kn,ki] ]
132           if all( vu ):
133             oo.write( '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (k,kn,tag,ki, inx.uid[k].label,  inx.uid[kn].label, inx.uid[ki].label) )
134           else:
135             print 'ERROR.088.0003: Bad index in replace info: %s .. %s .. %s' % ( str([k,kn,ki]), str(vu), tag )
136      else:
137        print 'ERROR.088.0004: Bad index in replace info: %s' %  k
138    oo.close()
139
140  def writeVarUpd(self, inx, fnrp='uuidreplace.csv', fnrm='uuidremove.csv', fnup='uuidupdate.csv'):
141    oo = open( fnrp, 'w' )
142    oo2 = open( fnrm, 'w' )
143    for k in self.repl.keys():
144      if inx.iref_by_uid.has_key(k):
145        kn = self.repl[k]
146        for tag,ki  in inx.iref_by_uid[k]:
147           vu = [ inx.uid.has_key(kk) for kk in [k,kn,ki] ]
148           if all( vu ):
149             oo.write( '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (k,kn,tag,ki, inx.uid[k].label,  inx.uid[kn].label, inx.uid[ki].label) )
150           else:
151             print 'ERROR.088.0001: Bad index in replace info: %s .. %s .. %s' % ( str([k,kn,ki]), str(vu), tag )
152      else:
153        oo2.write( k + '\n' )
154    oo.close()
155    oo2.close()
156    oo = open( fnup, 'w' )
157    for k in self.upd.keys():
158        ee = self.upd[k]
159        oo.write( string.join( [k,ee['provNote'],string.join(ee['tags']),ee['label'], ee['title'] ], '\t') + '\n' )
160    oo.close()
161
162  def scandup(self):
163    ii = open( self.fdup ).readlines()
164    nn = (len(ii)-1)/2
165    for i in range(nn):
166      l1 = string.split( ii[i*2+1], '\t' )
167      l2 = string.split( ii[i*2+2], '\t' )
168      xx = l1[8:10]
169      yy = l2[8:10]
170      if xx[1] == '' and yy[1] == xx[0]:
171        ths = 0
172        assert not self.repl.has_key( yy[0] ), 'duplicate replacement request for %s' % yy[0]
173        self.repl[ yy[0] ] = yy[1] 
174      elif yy[1] == '' and xx[1] == yy[0]:
175        ths = 1
176        assert not self.repl.has_key( xx[0] ), 'duplicate replacement request for %s' % xx[0]
177        self.repl[ xx[0] ] = xx[1] 
178      elif l1[10] == 'twin' and  l2[10] == 'twin':
179        ths = 2
180        self.twins.append( l1[8] )
181        self.twins.append( l2[8] )
182      elif l1[10] in self.delToks and l2[10] in self.delToks:
183        ths = 3
184        self.ddel[ l1[8] ] = (l1[10],l1[11])
185        self.ddel[ l2[8] ] = (l2[10],l2[11])
186      elif xx[1] == '' and yy[1] == "":
187        print 'WARN.087.00001: uncorrected duplication ..... %s ' %  str( l1[:5] )
188      else:
189        ths = -1
190        print 'ERROR.xxx.0001: Match failed'
191        print l1
192        print l2
193        assert False
194
195  def scancmvdup(self):
196    wb = workbook( 'csv2/CMORvar.xls' )
197    sht = wb.book.sheet_by_name( 'Sheet1' )
198    for i in range(sht.nrows):
199      rr = sht.row(i)
200      if len(rr) == 21 and str( rr[20].value ) != '':
201        kn = rr[20].value
202        ko = rr[18].value
203        vn = rr[0].value
204        self.cmvrepl[ ko ] = kn
205        print '%s: replace %s with %s' % (vn,ko,kn)
206
207  def scanmult(self):
208    ii = open( self.fmult ).readlines()
209    nn = (len(ii)-1)/3
210    for i in range(nn):
211      l1 = string.split( ii[i*3+1], '\t' )
212      l2 = string.split( ii[i*3+2], '\t' )
213      l3 = string.split( ii[i*3+3], '\t' )
214      yy = [l1[9],l2[9],l3[9]]
215      xx = [l1[8],l2[8],l3[8]]
216      zz = (l1,l2,l3)
217      for j in range(3):
218        if yy[j] != '':
219          assert yy[j] in xx, 'Invalid replacement option, %s' % yy[j]
220          assert  not self.repl.has_key( xx[j] ), 'duplicate replacement request for %s' % xx[j]
221          self.repl[ xx[j] ] = yy[j]
222        elif zz[j][10] == 'twin':
223          self.twins.append( zz[j][8] )
224        elif zz[j][11] == 'update':
225          tags = map( string.strip, string.split( zz[j][13], ',' ) )
226          self.upd[ xx[j] ] = { 'provNote':zz[j][12], 'tags':tags, 'label':zz[j][0], 'title':zz[j][1] }
227
228###
229### varDup and varMult created in first parse ----- then editted to select options
230### 2nd pass through then generates the replace and remove options -- taking into account cross references
231### the results of the 2nd pass go back to ../workbook to generate a new set of inputs.
232###
233up = updates('varDup.csv', 'varMult.csv', idir='rev2')
234up.scandup()
235up.scancmvdup()
236up.scanmult()
237
238urep = False
239urep = True
240if urep:
241  up.writeVarUpd( inx, fnrp='uuidreplace.csv', fnrm='uuidremove.csv', fnup='uuidupdate.csv')
242  up.writeCmvUpd( inx, fnrp='CMVreplace.csv')
243else:
244  oo2 = open( 'uuidremove2.csv', 'w' )
245  for i in dq.coll['var'].items:
246    if not inx.iref_by_uid.has_key(i.uid):
247      oo2.write( string.join( [i.uid,i.label,i.title,i.prov,i.description], '\t') + '\n' )
248  oo2.close()
249
250### check back references.
251nbr = 0
252lbr = []
253for k in inx.iref_by_uid.keys():
254  if not inx.uid.has_key(k):
255   nbr += 1
256   lbr.append(k)
257print 'Missing references: ', nbr
258### can now apply mappings, create updated records and write to new xml?
259
260for i in dq.coll['requestLink'].items:
261   rql_by_name[i.label].append( i.uid )
262   ix_rql_uid[i.uid] = i
263
264for i in dq.coll['requestVarGroup'].items:
265   ix_rqvg_uid[i.uid] = i
266
267
268if dq.coll.has_key( 'revisedTabItem' ):
269  thisk = 'revisedTabItem'
270else:
271  thisk = 'requestVar'
272oo = open( 'uuidinsert.csv', 'w' )
273for i in dq.coll[thisk].items:
274  if i.uid == '__new__':
275    if inx.var.label.has_key( i.label ):
276      if len( inx.var.label[i.label] ) == 1:
277        v = inx.uid[ inx.var.label[i.label][0] ]
278        oo.write( string.join( ['unique',i.label,v.label,v.uid,v.prov,i.mip], '\t' ) + '\n' )
279      else:
280        oo.write( string.join( ['ambiguous',i.label,i.mip,str(len(inx.var.label[i.label] ) ) ], '\t' ) + '\n' )
281oo.close()
282   
283oo = open( 'varMult.csv', 'w' )
284oo2 = open( 'varDup.csv', 'w' )
285oo3 = open( 'varStar.csv', 'w' )
286hs = ['label','title','sn','units','description','prov','procnote','procComment','uid']
287oo.write( string.join(hs, '\t' ) + '\n' )
288oo2.write( string.join(hs, '\t' ) + '\n' )
289oo3.write( string.join(hs, '\t' ) + '\n' )
290ks = inx.var.label.keys()
291ks.sort()
292emptySet = sets.Set( ['','unset'] )
293def entryEq(a,b):
294  return a == b or (a in emptySet and b in emptySet)
295
296deferredRecs = []
297for k in ks:
298  if len(inx.var.label[k]) == 2:
299    v1 = inx.var.uid[inx.var.label[k][0]]
300    v2 = inx.var.uid[inx.var.label[k][1]]
301    cc = map( lambda x: entryEq( v1.__dict__[x], v2.__dict__[x]), ['title','sn','units','description']  )
302    if all(cc):
303### where duplicates are identical , collect and output at end of file.
304      pv1 = string.find( v1.__dict__['prov'], 'OMIP.' ) != -1
305      pv2 = string.find( v2.__dict__['prov'], 'OMIP.' ) != -1
306      if pv2:
307        vp = v2
308        vo = v1
309      else:
310        if not pv1:
311          print 'WARN.088.00002: no preference: %s, %s, %s' % (v1.__dict__['label'],v1.__dict__['prov'],v2.__dict__['prov'])
312        vp = v1
313        vo = v2
314      deferredRecs.append( string.join(map( lambda x: vo.__dict__[x], hs) + [vp.uid,'identical'], '\t' ) + '\n' )
315      deferredRecs.append( string.join(map( lambda x: vp.__dict__[x], hs) + ['',''], '\t' ) + '\n' )
316    else:
317      oo2.write( string.join(map( lambda x: v1.__dict__[x], hs) + ['',''], '\t' ) + '\n' )
318      oo2.write( string.join(map( lambda x: v2.__dict__[x], hs) + ['',''], '\t' ) + '\n' )
319     
320  elif len(inx.var.label[k]) > 1:
321    for i in inx.var.label[k]:
322      oo.write( string.join(map( lambda x: inx.var.uid[i].__dict__[x], hs), '\t' ) + '\n' )
323
324  if k[-2:] == '--':
325    for i in (inx.var.label[k] + inx.var.label[k[:-2]]):
326      oo3.write( string.join(map( lambda x: inx.var.uid[i].__dict__[x], hs), '\t' ) + '\n' )
327
328## output auto-filled records for identical duplicates at end of varDup file.
329for r in deferredRecs:
330  oo2.write( r )
331oo.close()
332oo2.close()
333oo3.close()
334
335
336
337vns = inx.var.label.keys()
338vns.sort()
339for v in vns:
340  if len( inx.var.label[v] ) > 1:
341     print 'INFO.001.0001:',v, string.join( map( lambda x: inx.var.uid[x].sn, inx.var.label[v] ), ';' )
342
343nok = 0
344nerr = 0
345if dq.coll.has_key( 'ovar' ):
346  thisk = 'ovar'
347else:
348  thisk = 'CMORvar'
349for i in dq.coll[thisk].items:
350   vid = i.vid
351   ix_ovar_uid[i.uid] = i
352   xr_var_ovar[vid].append( i.uid )
353   if not inx.var.uid.has_key(vid):
354     print 'missing key:',i.label, i.prov, vid
355     nerr += 1
356   else:
357     nok += 1
358
359class rqHtml(object):
360
361  def __init__(self,odir='./htmlSc/'):
362    self.odir = odir
363    if not os.path.isdir(odir):
364      os.mkdir(odir)
365
366  def mkRqlHtml(self,name):
367     ## [u'comment', u'uid', u'tab', u'title', u'label', u'grid', 'defaults', u'objective', u'mip', 'globalDefault', u'gridreq']
368    if len( rql_by_name[name] ) == 1:
369      self.mkRqlHtml01(rql_by_name[name][0], name )
370    else:
371      self.mkRqlHtmlGp(name)
372
373  def mkRqlHtmlGp(self,name):
374    ee = {}
375    ee['title'] = 'CMIP Request Link %s (with multiple definitions)' % name
376    self.pageName = 'rql__%s.html' % name
377    al =[]
378    for i in range( len( rql_by_name[name] ) ):
379      this = ix_rql_uid[rql_by_name[name][i]]
380      al.append( tmpl.item % {'item':'<a href="rql__%s__%s.html">[%s]</a>: %s' % (name,i,i,this.title) } )
381    ee['items'] = string.join(al, '\n' )
382    ee['introduction'] = ''
383    ee['htmlBody'] = tmpl.indexWrapper % ee
384    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
385    self.pageHtml = tmpl.pageWrapper % ee
386    self.write()
387    for i in range( len( rql_by_name[name] ) ):
388      self.mkRqlHtml01(rql_by_name[name][i],i)
389
390  def mkRqlHtml01(self,id, tag):
391    this = ix_rql_uid[id]
392    ee = {}
393    if this.label == tag:
394      ee['title'] = 'CMIP Request Link %s' % tag
395      self.pageName = 'rql__%s.html' % tag
396    else:
397      ee['title'] = 'CMIP Request Link %s[%s]' % (this.label,tag)
398      self.pageName = 'rql__%s__%s.html' % (this.label,tag)
399    atts = this.__dict__.keys()
400    atts.sort()
401    al =[]
402    for a in atts:
403      if a not in ['defaults','globalDefault']:
404        al.append( tmpl.item % {'item':'<b>%s</b>: %s' % (a,this.__dict__.get(a,'-- Not Set --')) } )
405    ee['items'] = string.join(al, '\n' )
406    ee['introduction'] = ''
407    ee['htmlBody'] = tmpl.indexWrapper % ee
408    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
409    self.pageHtml = tmpl.pageWrapper % ee
410    self.write()
411     
412  def mkVarHtml(self,name):
413    if len( inx.var.label[name] ) == 1:
414      self.mkVarHtml01(inx.var.label[name][0], name )
415    else:
416      self.mkVarHtmlGp(name)
417
418  def mkVarHtmlGp(self,name):
419    ee = {}
420    ee['title'] = 'CMIP Variable %s (with multiple definitions)' % name
421    self.pageName = 'var__%s.html' % name
422    al =[]
423    for i in range( len( inx.var.label[name] ) ):
424      this = inx.var.uid[inx.var.label[name][i]]
425      al.append( tmpl.item % {'item':'<a href="var__%s__%s.html">[%s]</a>: %s' % (name,i,i,this.title) } )
426    ee['items'] = string.join(al, '\n' )
427    ee['introduction'] = ''
428    ee['htmlBody'] = tmpl.indexWrapper % ee
429    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
430    self.pageHtml = tmpl.pageWrapper % ee
431    self.write()
432    ##print 'Multi var: %s' % name
433    for i in range( len( inx.var.label[name] ) ):
434      self.mkVarHtml01(inx.var.label[name][i],i)
435
436  def mkVarHtml01(self,id, tag):
437    this = inx.var.uid[id]
438    ee = {}
439    if this.label == tag:
440      ee['title'] = 'CMIP Variable %s' % tag
441      self.pageName = 'var__%s.html' % tag
442    else:
443      ee['title'] = 'CMIP Variable %s[%s]' % (this.label,tag)
444      self.pageName = 'var__%s__%s.html' % (this.label,tag)
445    atts = this.__dict__.keys()
446    atts.sort()
447    al =[]
448    for a in atts:
449      if a not in ['defaults','globalDefault']:
450        al.append( tmpl.item % {'item':'<b>%s</b>: %s' % (a,this.__dict__.get(a,'-- Not Set --')) } )
451
452    if inx.iref_by_uid.has_key(this.uid):
453      assert varRefs.has_key(this.uid), 'Problem with collected references'
454      ee1 = varRefs[this.uid]
455      ks = ee1.keys()
456      ks.sort()
457      for k in ks:
458        al.append( tmpl.item % {'item':'<b>%s</b>: %s' % (k,string.join(ee1[k])) } )
459    ee['items'] = string.join(al, '\n' )
460    ee['introduction'] = ''
461    ee['htmlBody'] = tmpl.indexWrapper % ee
462    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
463    self.pageHtml = tmpl.pageWrapper % ee
464    self.write()
465
466  def varHtml(self):
467    for k in inx.var.label.keys():
468      self.mkVarHtml(k)
469 
470  def rqlHtml(self):
471    for k in rql_by_name.keys():
472      self.mkRqlHtml(k)
473 
474  def write(self):
475    oo = open( '%s/%s' % (self.odir,self.pageName), 'w' )
476    oo.write( self.pageHtml )
477    oo.close()
478
479   
480vh = rqHtml()
481vh.varHtml()
482vh.rqlHtml()
483
484if nerr == 0:
485  print 'CHECK 001: %s records checked, no missing references' % nok
486
487shps = {'': 64, 'XYZKT': 13, '4-element vector': 2, 'XYT': 476, '2D vector field ': 2, 'KZT': 4, '2D vector field': 2, 'XYZ': 27, 'XYZT': 204, '2D': 83, 'scalar': 14, 'XY': 88, '?': 21, '2D ': 1, 'XYKT': 3, 'YZT': 16, 'ZST1': 15, 'XKT': 2, 'BasinYT': 1}
488vshpchkMap = {'':'', u'all model levels above 400hPa':'alevStrat', u'all':'Xlev', 3.0:'plev3', '4.0':'plev4', \
489            36.0:'plev36', u'soil levels':'sdepth', \
490            1.0:'sfc?', \
491           16.0:'plev16', 7.0:'plev7', 40.0:'plev40', u'all*':'Xlev', 14.0:'plev14', u'Model levels or 27Plevs':'alev|plev27', \
492           u'17 (or 23 )':'plev17|plev23', u'17 (or 23)':'plev17|plev23', \
493           27.0:'plev27', 17.0:'plev17', u'17 (or23)':'plev17|plev23', 8.0:'plev8', u'all model levels':'alev', 5.0:'plev5'}
494ks = vshpchkMap.keys()
495for k in ks:
496  if type(k) == type(0.):
497     vshpchkMap[str(k)] = vshpchkMap[k]
498
499tsmap = { 'mean':[u'daily mean', u'time mean', u'time: day',
500                u'Cumulative annual fraction', u'Time mean', u'weighted time mean', u'time: mean', u'mean', u'Mean'],
501          '__unknown__':['','dummyAt'],
502          'point':[ u'Instantaneous (end of year)', u'point', u'Synoptic', u'instantaneous', u'time: point', u'synoptic'] }
503tsmap2 = {}
504for k in tsmap.keys():
505  for i in tsmap[k]:
506    tsmap2[i] = k
507
508if dq.coll.has_key( 'groupItem' ):
509  ee = collections.defaultdict( int )
510  for i in dq.coll['groupItem'].items:
511    tst = tsmap2[ i.tstyle ]
512    dd = ''
513    if 'X' in i.shape:
514      dd += 'latitude '
515    if 'Y' in i.shape:
516      dd += 'longitude '
517    if 'Z' in i.shape:
518      if i.levels == '':
519        print 'ERROR.001.0001: no levels specified', i.label, i.title
520      else:
521        zdim = vshpchkMap[i.levels]
522        dd +=  zdim
523  ## print '%s::%s::%s|%s' % (i.shape, i.levels, i.tstyle, dd)
524  for i in dq.coll['groupItem'].items:
525     list_gp_ovar[i.gpid].append( i.uid )
526
527  nok = 0
528  nerr = 0
529  for i in dq.coll['groupItem'].items:
530     vid = i.vid
531     ix_gpi_uid[i.uid] = i
532     xr_var_gpi[vid].append( i.uid )
533     if not inx.var.uid.has_key(vid):
534       nerr += 1
535     else:
536       nok += 1
537  ##print 'groupItem to var crossref: nok = %s, nerr = %s' % (nok, nerr)
538
539
540class tcmp(object):
541  def __init__(self):
542    pass
543  def cmp(self,x,y):
544    return cmp(x.title,y.title)
545
546def atRepr(l,x,optional=False):
547  if x != None:
548    if optional:
549      v = l.__dict__.get(x, '' )
550    else:
551      v = l.__dict__[x]
552  else:
553    v = l
554  if v == '__unset__':
555    return ''
556  elif type(v) in [ type([]), type(())]:
557    if type(v) == type(()):
558      print 'INFO.tuple.00001:',l,x,v
559    return string.join([str(i) for i in v])
560  else:
561    return v
562
563class xlsx(object):
564  def __init__(self,fn):
565    self.wb = xlsxwriter.Workbook(fn)
566
567  def newSheet(self,name):
568    self.worksheet = self.wb.add_worksheet(name=name)
569    return self.worksheet
570
571  def close(self):
572    self.wb.close()
573 
574def dumpxlsx( fn, key, atl):
575  wb = xlsx( fn )
576  sht = wb.newSheet( key )
577  j = 0
578  for i in range(len(atl)):
579     sht.write( j,i, atl[i] )
580  ll = dq.coll[key].items[:]
581  ll.sort( tcmp().cmp )
582  for l in ll:
583    uid = atRepr(l,'uid')
584    j+=1
585    i=0
586    for x in atl:
587       sht.write( j,i, atRepr(l,x) )
588       i+=1
589    if key == 'var' and refpix != None:
590      if uid in refpix:
591        p = refpix[uid][2]
592      else:
593        p = 201
594      sht.write( j,i, p )
595  wb.close()
596     
597def dumpcsv( fn, key, atl, optionalSet='' ):
598  oo = open(fn, 'w' )
599  ll = dq.coll[key].items[:]
600  ll.sort( tcmp().cmp )
601  oo.write( string.join( atl, '\t' ) + '\n' )
602  for l in ll:
603    try:
604      oo.write( string.join( map( lambda x: str(atRepr(l,x,x in optionalSet)), atl), '\t' ) + '\n' )
605    except:
606      print 'SEVERE.090.0001: print %s' % str(atl)
607      print l
608      print key
609      raise
610  oo.close()
611
612def atlSort( ll ):
613  oo = []
614  l1 = ['label','title']
615  l2 = ['uid','defaults','globalDefault']
616  for i in l1:
617    if i in ll:
618      oo.append(i)
619  ll.sort()
620  for i in ll:
621    if i not in l1 + l2:
622      oo.append(i)
623  if 'uid' in ll:
624    oo.append( 'uid' )
625  return oo
626
627for k in dq.coll.keys():
628  if len( dq.coll[k].items ) > 0:
629    expl = dq.coll[k].items[0]
630    atl = atlSort( expl.__dict__.keys() )
631    atl1 = [a for a in atl if a != 'parent' and a[0] != '_']
632    ###print k, atl1
633    optionalSet = set( [a for a in atl1 if not expl.__class__.__dict__[a].required] )
634    dumpcsv( 'csv2/%s.csv' % k, k, atl1, optionalSet=optionalSet )
635    if k == 'var':
636       dumpxlsx( 'csv2/var.xlsx', k, atl1 )
637 
638class annotate(object):
639  def __init__(self,src,dreq):
640    assert os.path.isfile( src), '%s not found' % src
641    self.doc = xml.dom.minidom.parse( src  )
642    self.dreq = dreq
643    self.removedUids = {}
644
645  def iniVar(self,dq):
646    a = addUnits(dq)
647    this = self.doc.getElementsByTagName('var')[0]
648    dil = this.getElementsByTagName('item')
649    self.vid = {}
650    for item in dil:
651      uid = item.getAttribute( 'uid' ) 
652      title = item.getAttribute( 'title' ) 
653      label = item.getAttribute( 'label' ) 
654      self.vid[uid] = (label,title)
655      units = item.getAttribute( 'units' ) 
656      if units in a.repl:
657        print 'INFO.units.0001: replacing %s --> %s' % (units,a.repl[ units ])
658        units = a.repl[ units ]
659      u2 = a.uid( units )
660      if u2 == None:
661        units = string.strip( str(units) )
662        u2 = a.uid( units )
663      if u2 != None:
664        item.setAttribute( 'unid', u2 )
665      else:
666        print 'Units not recognised: %s (%s) -- %s' % (units,label, type(units))
667     
668  def strTtl(self,dq):
669    this = self.doc.getElementsByTagName('cellMethods')[0]
670    dil = this.getElementsByTagName('item')
671    eecm = {}
672    for item in dil:
673      eecm[item.getAttribute( 'uid' )] = item.getAttribute( 'label' )
674
675    that = self.doc.getElementsByTagName('spatialShape')[0]
676    dil = that.getElementsByTagName('item')
677    ee1 = {}
678    for item in dil:
679      uid = item.getAttribute( 'uid' )
680      lab = item.getAttribute( 'label' )
681      ttl = item.getAttribute( 'title' )
682      ee1[uid] = (lab,ttl)
683
684    this = self.doc.getElementsByTagName('structure')[0]
685    dil = this.getElementsByTagName('item')
686   
687    filterStr = True
688    for item in dil:
689      uid = item.getAttribute( 'uid' ) 
690      lab = item.getAttribute( 'label' ) 
691      if len( dq.inx.iref_by_uid[uid] ) == 0 and filterStr:
692         print 'UNUSED STRUCTURE: %s, %s' % (lab,uid)
693         this.removeChild( item )
694         self.removedUids[uid] = 'structure: %s' % lab
695      else:
696        tmid = item.getAttribute( 'tmid' ) 
697        spid = item.getAttribute( 'spid' ) 
698        cmid = item.getAttribute( 'cmid' ) 
699        cml = eecm.get( cmid, '' )
700        if cml != '':
701          cml = ' [%s]' % cml
702        o = item.getAttribute( 'odims' ) 
703        c = item.getAttribute( 'coords' ) 
704        if spid not in ee1:
705          print 'SEVERE:spid.0001: spid not found: %s' % spid
706          sl = '__unknowm__'
707          st = '__unknowm__'
708        else:
709          sl,st = ee1[spid]
710        if tmid not in dq.inx.uid:
711          print 'BAD time record uid: ',tmid
712          print lab, uid
713          raise
714        title = '%s, %s [%s]' % (dq.inx.uid[tmid].title, st, sl) 
715        if string.strip( c ) != '' or string.strip( o ) != '':
716          title += ' {%s:%s}' % (o,c)
717        title += cml
718        print 'STRUCT: ',title,o,c
719        item.setAttribute( 'title', title )
720   
721
722  def rvgCheck(self,dq):
723    """Remove request variable groups which have no requestLink"""
724    this = self.doc.getElementsByTagName('requestVarGroup')[0]
725    dil = this.getElementsByTagName('item')
726    nn = 0
727    for item in dil:
728        uid = item.getAttribute( 'uid' ) 
729        if ('requestLink' not in dq.inx.iref_by_sect[uid].a) and ('tableSection' not in dq.inx.iref_by_sect[uid].a):
730          if item.getAttribute( 'label' ) in ['aermonthly']:
731             print 'WARN.0010: overriding variable group pruning: ',item.getAttribute( 'label' )
732          else:
733            ##self.removedUids[ uid ] = 'requestVarGroup:  %s' % item.getAttribute( 'label' )
734            ##this.removeChild(item)
735            print 'INFO.rvg.0001: New rvg?? ',uid, item.getAttribute( 'label' )
736            nn+=1
737    ##print 'WARN.Unused variable groups removed: %s' % nn
738    this = self.doc.getElementsByTagName('requestVar')[0]
739    dil = this.getElementsByTagName('item')
740    nn = 0
741    s1 = {i.uid for i in dq.coll['requestVarGroup'].items if i.uid not in self.removedUids}
742    for item in dil:
743        uid = item.getAttribute( 'uid' ) 
744        vid = item.getAttribute( 'vid' )
745        vgid = item.getAttribute( 'vgid' )
746        if vgid not in s1:
747          this.removeChild(item)
748          self.removedUids[ uid ] = 'requestVar:  %s' % item.getAttribute( 'label' )
749          nn+=1
750    print 'Unused request variables removed: %s' % nn
751       
752
753  def cmvCheck(self,dq):
754    this = self.doc.getElementsByTagName('CMORvar')[0]
755    dil = this.getElementsByTagName('item')
756    kk = 0
757    kka = 0
758    nrm0 = 0
759    nrm1 = 0
760    for item in dil:
761      title = item.getAttribute( 'title' ) 
762      if title[:6] == '__from':
763        kka += 1
764        vid = item.getAttribute( 'vid' ) 
765        if vid in self.vid:
766          title2 = self.vid[vid][1]
767          item.setAttribute( 'title', title2 )
768          kk += 1
769      realm = item.getAttribute( 'modeling_realm' )
770      if realm in ['','?']:
771        stid = item.getAttribute( 'stid' )
772        st = dq.inx.uid[stid]
773        odims = st.odims
774        this = None
775        if odims == 'iceband':
776          this = 'seaIce'
777        elif odims not in ['','?']:
778          this = 'atmos'
779        else:
780          sp = dq.inx.uid[st.spid]
781          if sp.label in ['TR-na','XY-O', 'YB-O', 'YB-R']:
782            this = 'ocean'
783          elif sp.label != 'XY-na':
784            this = 'atmos'
785          else:
786            prov = item.getAttribute( 'prov' )
787            if prov in knowna:
788              this = 'atmos'
789            elif prov in knowno:
790              this = 'ocean'
791            elif prov in knownl:
792              this = 'land'
793            else:
794              lab  = item.getAttribute( 'label' )
795              print 'ERROR.cmv.00006: no realm: %s, %s, %s, %s ..' % (lab,odims, sp.label, prov)
796        if this == None:
797          nrm1 += 1
798        else:
799          nrm0 += 1
800          item.setAttribute( 'modeling_realm', this )
801    print ('CMOR Var realms set: %s' % nrm0 )
802    if nrm1 > 0:
803      print ('SEVERE.cmv.00005: realm unset: %s' % nrm1)
804    print ('CMOR Var titles reset: %s [%s]' % (kk,kka))
805   
806  def mipProv(self,dq):
807    s1 = re.compile( '\[([a-zA-Z0-9]*)\]' )
808    cc = collections.defaultdict(list)
809    dd = collections.defaultdict(int)
810    mips = set()
811    for i in dq.coll['mip'].items:
812      mips.add( i.uid )
813    for i in dq.coll['var'].items:
814      cc[i.prov].append( i.label )
815
816    ee = {}
817    for i in sorted( cc.keys() ):
818      if i[:9] == 'CMIP6 end':
819        m = s1.findall( i )
820        assert len( m ) == 1, 'FAILED TO PARSE: %s' % i
821        this = m[0]
822      else:
823        i5 = i.find( 'CMIP5' ) != -1
824        io = i.find( 'OMIP' ) != -1
825        icx = i.find( 'CORDEX' ) != -1
826        ip = i.find( 'PMIP' ) != -1
827        icc = i.find( 'CCMI' ) != -1
828        isp = i.find( 'SPECS' ) != -1
829        icf = i.find( 'CFMIP' ) != -1
830        iac = i.find( 'AerChemMIP' ) != -1
831        if i5 and io:
832          print 'WARNING .. unclear provenance: ',i,cc[i]
833          this = 'CMIP5/OMIP'
834        elif i5:
835          this = 'CMIP5'
836        elif io:
837          this = 'OMIP'
838        elif icx:
839          this = 'CORDEX'
840        elif ip:
841          this = 'PMIP'
842        elif icc:
843          this = 'CCMI'
844        elif isp:
845          this = 'SPECS'
846        elif icf:
847          this = 'CFMIP'
848        elif iac:
849          this = 'AerChemMIP'
850        else:
851          print 'WARNING .. unclear provenance [2]: ',i,cc[i]
852          this = 'unknown'
853   
854      ee[i] = this
855      dd[this] += len( cc[i] )
856    self.dd = dd
857    self.ee = ee
858    this = self.doc.getElementsByTagName('var')[0]
859    dil = this.getElementsByTagName('item')
860    print 'FIXING var provmip attribute, %s items' % len(dil)
861    kk = 0
862    for item in dil:
863      kk += 1
864      p = item.getAttribute( 'prov' ) 
865      p0 = item.getAttribute( 'provmip' ) 
866      if p0 not in mips:
867        if p in mips:
868          item.setAttribute( 'provmip', p )
869        else:
870          assert ee.has_key(p), 'Unmatched key: %s' % p
871          assert ee[p] in mips, 'Unknown provenance: %s, %s' % (p,ee[p])
872          item.setAttribute( 'provmip', ee[p] )
873     
874  def fixCellMethods(self,dq):
875    this = self.doc.getElementsByTagName('structure')[0]
876    dil = this.getElementsByTagName('item')
877    cmrep = collections.defaultdict( set )
878    cmc = collections.defaultdict( int )
879    nrep = 0
880    for item in dil:
881      cm = item.getAttribute( 'cell_methods' ) 
882      if string.find( cm, "area: where" ) != -1:
883        cm1 = string.replace( cm, "area: where", "area: mean where" )
884        item.setAttribute( 'cell_methods', cm1 ) 
885        cmrep[cm].add(cm1)
886        cmc[cm1] += 1
887        nrep += 1
888      elif string.find( cm, "time:mean" ) != -1:
889        cm1 = string.replace( cm, "time:mean", "time: mean" )
890        item.setAttribute( 'cell_methods', cm1 ) 
891        cmrep[cm].add(cm1)
892        cmc[cm1] += 1
893        nrep += 1
894      elif string.find( cm, "weighted b " ) != -1:
895        cm1 = string.replace( cm, "weighted b ", "weighted by " )
896        item.setAttribute( 'cell_methods', cm1 ) 
897        cmrep[cm].add(cm1)
898        cmc[cm1] += 1
899        nrep += 1
900    print ('FIXED CELL METHODS .. %s' % nrep )
901    for k in cmc:
902      print ('%s: %s' % (k,cmc[k]) )
903
904
905  def sectionCopy(self,dq):
906    this = self.doc.getElementsByTagName('CMORvar')[0]
907    thisRqv = self.doc.getElementsByTagName('requestVar')[0]
908    xx = [i for i in dq.coll['requestVarGroup'].items if i.label == 'OMIP-Omon']
909    assert len(xx) == 1, 'OMIP-Omon request variable group not found'
910    omipOmonUid = xx[0].uid
911    dil = this.getElementsByTagName('item')
912    for item in dil:
913      mipt = item.getAttribute( 'mipTable' ) 
914      prov = item.getAttribute( 'prov' ) 
915      provn = item.getAttribute( 'provNote' ) 
916      if mipt == 'Oyr' and prov[:12] == "CMIP6 [OMIP]" and provn == 'bgc':
917        rowix = int( item.getAttribute( 'rowIndex' ) )
918        if rowix < 65:
919          var = item.getAttribute( 'label' )
920          new = item.cloneNode(True)
921          new.setAttribute( 'defaultPriority', '2' )
922          new.setAttribute( 'mipTable', 'Omon' )
923          new.setAttribute( 'prov', 'Copy from Oyr' )
924          new.setAttribute( 'provNote', 'sdq.001' )
925          vid =  str( uuid.uuid1() ) 
926          new.setAttribute( 'uid', vid )
927          this.appendChild( new )
928##
929## create request var
930##
931          new2 = self.doc.createElement( 'item' )
932          uid =  str( uuid.uuid1() ) 
933          new2.setAttribute( 'uid', uid )
934          new2.setAttribute( 'priority', '2' )
935          new2.setAttribute( 'vid', vid )
936          new2.setAttribute( 'vgid', omipOmonUid )
937          new2.setAttribute( 'mip', 'OMIP' )
938          new2.setAttribute( 'table', 'OMIP-Omon' )
939
940          if omipOmonUid not in dq.inx.uid:
941            print 'ERROR.005.0001: vgid %s not found' % omipOmonUid
942         
943          thisRqv.appendChild(new2)
944
945  def missingRefs(self,mrefs,dq,clear=True):
946    this = self.doc.getElementsByTagName('remarks')[0]
947    if clear:
948      dil = this.getElementsByTagName('item')
949      for d in dil:
950        this.removeChild(d)
951    for k in mrefs.keys():
952      if len(  mrefs[k] ) == 1:
953        tid = mrefs[k][0][2]
954        tattr = mrefs[k][0][1]
955        tn = None
956      else:
957        tid = None
958        ee = collections.defaultdict(int)
959        tn = str( len( mrefs[k] ) )
960        for t in mrefs[k]:
961          s = self.dreq.inx.uid[t[2]]._h.label
962          ee['%s.%s' % (s,t[1])] += 1
963        if len( ee.keys() ) == 1:
964          tattr = ee.keys()[0]
965        else:
966          tattr = '__multiple__'
967      if tid == None or (tid not in self.removedUids):
968        item = self.doc.createElement( 'item' )
969        assert type(k) == type( '' ), 'Attempt to set uid with bad type: %s' % str(k)
970        item.setAttribute( 'uid', k ) 
971        item.setAttribute( 'tattr', tattr ) 
972        if tn != None:
973          item.setAttribute( 'techNote', tn ) 
974        if tid != None:
975          item.setAttribute( 'tid', tid ) 
976          if tid not in dq.inx.uid:
977            print 'ERROR.005.0002: tid %s not found' % tid
978        item.setAttribute( 'class', 'missingLink' ) 
979        item.setAttribute( 'description', 'Missing links detected and marked for fixing' ) 
980        item.setAttribute( 'prov', 'scanDreq.py:annotate' ) 
981        this.appendChild( item )
982 
983    parent = self.doc.getElementsByTagName('annex')[0]
984    for this in parent.childNodes:
985      if this.nodeType == this.ELEMENT_NODE:
986        dil = this.getElementsByTagName('item')
987        print 'INFO.nodescan.00001: ',this.localName,len(dil)
988        for d in dil:
989          for k in item.attributes.keys():
990            v = item.getAttribute( k )
991            if type( v ) not in [type( '' ),type( u'' )]:
992              print 'SEVERE.0001: tuple in attribute value',this.localName,k,v
993    txt = self.doc.toprettyxml(indent='\t', newl='\n', encoding=None)
994    oo = open( 'out/annotated_20150731_i1.xml', 'w' )
995    lines = string.split( txt, '\n' )
996    for line in lines:
997      l = utils_wb.uniCleanFunc( string.strip(line) )
998      if empty.match(l):
999        continue
1000      else:
1001        oo.write(l + '\n')
1002    oo.close()
1003
1004def anno():
1005  oo = open( 'var1.csv', 'w' )
1006  ks = ['label','title','sn','units','description','prov','procnote','procComment','uid']
1007  ks2 = [ 'ovar','groupItem','revisedTabItem']
1008  oo.write( string.join(ks + ks2, '\t' ) + '\n' )
1009  for i in dq.coll['var'].items:
1010     if i.label[-2:] != '--':
1011       ee1 = varRefs.get( i.uid, {} )
1012       r2 = map( lambda x: string.join( atRepr( ee1.get(x, [] ), None ) ), ks2 )
1013       oo.write( string.join(map( lambda x: atRepr(i,x), ks) + r2, '\t' ) + '\n' )
1014  oo.close()
1015
1016  an = annotate( dq.c.vsamp, dq )
1017  ###an.sectionCopy(dq)
1018  an.iniVar( dq )
1019  an.fixCellMethods(dq)
1020  an.mipProv(dq)
1021  an.cmvCheck(dq)
1022  an.rvgCheck(dq)
1023  an.strTtl(dq)
1024  for k in an.removedUids:
1025    print 'WARN.REMOVED: %s: %s' % (k,an.removedUids[k])
1026  an.missingRefs( dq.inx.missingIds, dq )
1027
1028if __name__ == '__main__':
1029  anno()
Note: See TracBrowser for help on using the repository browser.