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

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

misc updates

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