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

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

release cand

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