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

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

misc

Line 
1import dreq, collections, string, os, utils_wb
2import htmlTemplates as tmpl
3import xml, re
4import xml.dom, xml.dom.minidom
5import sets
6
7from utils_wb import uniCleanFunc
8
9empty=re.compile('^$')
10
11src1 = '../workbook/trial_20150831.xml'
12
13dq = dreq.loadDreq(dreqXML=src1)
14inx = dq.inx
15##inx.makeVarRefs()
16ix_rql_uuid = {}
17ix_rqvg_uuid = {}
18ix_ovar_uuid = {}
19ix_gpi_uuid = {}
20list_gp_ovar = collections.defaultdict( list )
21xr_var_ovar = collections.defaultdict( list )
22xr_var_gpi = collections.defaultdict( list )
23rql_by_name = collections.defaultdict( list )
24
25def makeVarRefs(uuid, var, iref_by_uuid):
26    varRefs = {}
27    for thisuuid in var.uuid.keys():
28      if iref_by_uuid.has_key(thisuuid):
29        ee1 = collections.defaultdict( list )
30        for k,i in iref_by_uuid[thisuuid]:
31          sect,thisi = uuid[i]
32          if sect == 'groupItem':
33            ee1[sect].append( '%s.%s' % (thisi.mip, thisi.group) )
34          elif sect == 'ovar':
35            ee1[sect].append( thisi.mipTable )
36          elif sect == 'revisedTabItem':
37            ee1[sect].append( '%s.%s' % (thisi.mip, thisi.table) )
38      varRefs[thisuuid] = ee1
39    return varRefs
40
41varRefs = makeVarRefs( inx.uuid, inx.var, inx.iref_by_uuid)
42
43class updates(object):
44  delToks = sets.Set( ['inc','omit'] )
45  def __init__(self,fndup,fnmult,idir='rev1'):
46    assert os.path.isdir( idir ), 'Directory %s not found' % idir
47    self.fdup = '%s/%s' % (idir,fndup)
48    self.fmult = '%s/%s' % (idir,fnmult)
49    for p in [self.fdup,self.fmult]:
50      assert os.path.isfile( p ), 'File %s not found' % p
51    self.repl = {}
52    self.upd = {}
53    self.twins = []
54    self.ddel = {}
55
56  def scandup(self):
57    ii = open( self.fdup ).readlines()
58    nn = (len(ii)-1)/2
59    for i in range(nn):
60      l1 = string.split( ii[i*2+1], '\t' )
61      l2 = string.split( ii[i*2+2], '\t' )
62      xx = l1[8:10]
63      yy = l2[8:10]
64      if xx[1] == '' and yy[1] == xx[0]:
65        ths = 0
66        assert not self.repl.has_key( yy[0] ), 'duplicate replacement request for %s' % yy[0]
67        self.repl[ yy[0] ] = yy[1] 
68      elif yy[1] == '' and xx[1] == yy[0]:
69        ths = 1
70        assert not self.repl.has_key( xx[0] ), 'duplicate replacement request for %s' % xx[0]
71        self.repl[ xx[0] ] = xx[1] 
72      elif l1[10] == 'twin' and  l2[10] == 'twin':
73        ths = 2
74        self.twins.append( l1[8] )
75        self.twins.append( l2[8] )
76      elif l1[10] in self.delToks and l2[10] in self.delToks:
77        ths = 3
78        self.ddel[ l1[8] ] = (l1[10],l1[11])
79        self.ddel[ l2[8] ] = (l2[10],l2[11])
80      else:
81        ths = -1
82        print 'ERROR.xxx.0001: Match failed'
83        print l1
84        print l2
85        assert False
86
87  def scanmult(self):
88    ii = open( self.fmult ).readlines()
89    nn = (len(ii)-1)/3
90    for i in range(nn):
91      l1 = string.split( ii[i*3+1], '\t' )
92      l2 = string.split( ii[i*3+2], '\t' )
93      l3 = string.split( ii[i*3+3], '\t' )
94      yy = [l1[9],l2[9],l3[9]]
95      xx = [l1[8],l2[8],l3[8]]
96      zz = (l1,l2,l3)
97      for j in range(3):
98        if yy[j] != '':
99          assert yy[j] in xx, 'Invalid replacement option, %s' % yy[j]
100          assert  not self.repl.has_key( xx[j] ), 'duplicate replacement request for %s' % xx[j]
101          self.repl[ xx[j] ] = yy[j]
102        elif zz[j][10] == 'twin':
103          self.twins.append( zz[j][8] )
104        elif zz[j][11] == 'update':
105          tags = map( string.strip, string.split( zz[j][13], ',' ) )
106          self.upd[ xx[j] ] = { 'provNote':zz[j][12], 'tags':tags, 'label':zz[j][0], 'title':zz[j][1] }
107
108###
109### varDup and varMult created in first parse ----- then editted to select options
110### 2nd pass through then generates the replace and remove options -- taking into account cross references
111### the results of the 2nd pass go back to ../workbook to generate a new set of inputs.
112###
113up = updates('varDup_20150724.csv', 'varMult_20150725.csv')
114##up.scandup()
115up.scanmult()
116
117urep = True
118urep = False
119if urep:
120  oo = open( 'uuidreplace.csv', 'w' )
121  oo2 = open( 'uuidremove.csv', 'w' )
122  for k in up.repl.keys():
123    if inx.iref_by_uuid.has_key(k):
124      kn = up.repl[k]
125      for tag,ki  in inx.iref_by_uuid[k]:
126         try:
127           oo.write( '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % (k,kn,tag,ki, inx.uuid[k][1].label,  inx.uuid[kn][1].label, inx.uuid[ki][1].label) )
128         except:
129           print k,kn,ki
130           raise
131    else:
132      oo2.write( k + '\n' )
133  oo.close()
134  oo2.close()
135  oo = open( 'uuidupdate.csv', 'w' )
136  for k in up.upd.keys():
137      ee = up.upd[k]
138      oo.write( string.join( [k,ee['provNote'],string.join(ee['tags']),ee['label'], ee['title'] ], '\t') + '\n' )
139  oo.close()
140else:
141  oo2 = open( 'uuidremove2.csv', 'w' )
142  for i in dq.coll['var'].items:
143    if not inx.iref_by_uuid.has_key(i.uuid):
144      oo2.write( string.join( [i.uuid,i.label,i.title,i.prov,i.description], '\t') + '\n' )
145  oo2.close()
146
147### check back references.
148nbr = 0
149lbr = []
150for k in inx.iref_by_uuid.keys():
151  if not inx.uuid.has_key(k):
152   nbr += 1
153   lbr.append(k)
154print 'Missing references: ', nbr
155### can now apply mappings, create updated records and write to new xml?
156
157for i in dq.coll['requestLink'].items:
158   rql_by_name[i.label].append( i.uuid )
159   ix_rql_uuid[i.uuid] = i
160
161for i in dq.coll['requestVarGroup'].items:
162   ix_rqvg_uuid[i.uuid] = i
163
164
165oo = open( 'uuidinsert.csv', 'w' )
166for i in dq.coll['revisedTabItem'].items:
167  if i.uuid == '__new__':
168    if inx.var.label.has_key( i.label ):
169      if len( inx.var.label[i.label] ) == 1:
170        v = inx.uuid[ inx.var.label[i.label][0] ][1]
171        oo.write( string.join( ['unique',i.label,v.label,v.uuid,v.prov,i.mip], '\t' ) + '\n' )
172      else:
173        oo.write( string.join( ['ambiguous',i.label,i.mip,str(len(inx.var.label[i.label] ) ) ], '\t' ) + '\n' )
174oo.close()
175   
176oo = open( 'varMult.csv', 'w' )
177oo2 = open( 'varDup.csv', 'w' )
178oo3 = open( 'varStar.csv', 'w' )
179hs = ['label','title','sn','units','description','prov','procnote','procComment','uuid']
180oo.write( string.join(hs, '\t' ) + '\n' )
181oo2.write( string.join(hs, '\t' ) + '\n' )
182oo3.write( string.join(hs, '\t' ) + '\n' )
183ks = inx.var.label.keys()
184ks.sort()
185emptySet = sets.Set( ['','unset'] )
186def entryEq(a,b):
187  return a == b or (a in emptySet and b in emptySet)
188
189deferredRecs = []
190for k in ks:
191  if len(inx.var.label[k]) == 2:
192    v1 = inx.var.uuid[inx.var.label[k][0]]
193    v2 = inx.var.uuid[inx.var.label[k][1]]
194    cc = map( lambda x: entryEq( v1.__dict__[x], v2.__dict__[x]), ['title','sn','units','description']  )
195    if all(cc):
196### where duplicates are identical , collect and output at end of file.
197      deferredRecs.append( string.join(map( lambda x: v1.__dict__[x], hs) + [v2.uuid,'identical'], '\t' ) + '\n' )
198      deferredRecs.append( string.join(map( lambda x: v2.__dict__[x], hs) + ['',''], '\t' ) + '\n' )
199    else:
200      oo2.write( string.join(map( lambda x: v1.__dict__[x], hs) + ['',''], '\t' ) + '\n' )
201      oo2.write( string.join(map( lambda x: v2.__dict__[x], hs) + ['',''], '\t' ) + '\n' )
202     
203  elif len(inx.var.label[k]) > 1:
204    for i in inx.var.label[k]:
205      oo.write( string.join(map( lambda x: inx.var.uuid[i].__dict__[x], hs), '\t' ) + '\n' )
206
207  if k[-2:] == '--':
208    for i in (inx.var.label[k] + inx.var.label[k[:-2]]):
209      oo3.write( string.join(map( lambda x: inx.var.uuid[i].__dict__[x], hs), '\t' ) + '\n' )
210
211## output auto-filled records for identical duplicates at end of varDup file.
212for r in deferredRecs:
213  oo2.write( r )
214oo.close()
215oo2.close()
216oo3.close()
217
218
219for i in dq.coll['groupItem'].items:
220   list_gp_ovar[i.gpid].append( i.uuid )
221
222vns = inx.var.label.keys()
223vns.sort()
224for v in vns:
225  if len( inx.var.label[v] ) > 1:
226     print 'INFO.001.0001:',v, string.join( map( lambda x: inx.var.uuid[x].sn, inx.var.label[v] ), ';' )
227
228nok = 0
229nerr = 0
230for i in dq.coll['ovar'].items:
231   vid = i.vid
232   ix_ovar_uuid[i.uuid] = i
233   xr_var_ovar[vid].append( i.uuid )
234   if not inx.var.uuid.has_key(vid):
235     print 'missing key:',i.__dict__
236     nerr += 1
237   else:
238     nok += 1
239
240nok = 0
241nerr = 0
242for i in dq.coll['groupItem'].items:
243   vid = i.vid
244   ix_gpi_uuid[i.uuid] = i
245   xr_var_gpi[vid].append( i.uuid )
246   if not inx.var.uuid.has_key(vid):
247     nerr += 1
248   else:
249     nok += 1
250print 'groupItem to var crossref: nok = %s, nerr = %s' % (nok, nerr)
251
252class rqHtml(object):
253
254  def __init__(self,odir='./html/'):
255    self.odir = odir
256    if not os.path.isdir(odir):
257      os.mkdir(odir)
258
259  def mkRqlHtml(self,name):
260     ## [u'comment', u'uuid', u'tab', u'title', u'label', u'grid', 'defaults', u'objective', u'mip', 'globalDefault', u'gridreq']
261    if len( rql_by_name[name] ) == 1:
262      self.mkRqlHtml01(rql_by_name[name][0], name )
263    else:
264      self.mkRqlHtmlGp(name)
265
266  def mkRqlHtmlGp(self,name):
267    ee = {}
268    ee['title'] = 'CMIP Request Link %s (with multiple definitions)' % name
269    self.pageName = 'rql__%s.html' % name
270    al =[]
271    for i in range( len( rql_by_name[name] ) ):
272      this = ix_rql_uuid[rql_by_name[name][i]]
273      al.append( tmpl.item % {'item':'<a href="rql__%s__%s.html">[%s]</a>: %s' % (name,i,i,this.title) } )
274    ee['items'] = string.join(al, '\n' )
275    ee['introduction'] = ''
276    ee['htmlBody'] = tmpl.indexWrapper % ee
277    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
278    self.pageHtml = tmpl.pageWrapper % ee
279    self.write()
280    for i in range( len( rql_by_name[name] ) ):
281      self.mkRqlHtml01(rql_by_name[name][i],i)
282
283  def mkRqlHtml01(self,id, tag):
284    this = ix_rql_uuid[id]
285    ee = {}
286    if this.label == tag:
287      ee['title'] = 'CMIP Request Link %s' % tag
288      self.pageName = 'rql__%s.html' % tag
289    else:
290      ee['title'] = 'CMIP Request Link %s[%s]' % (this.label,tag)
291      self.pageName = 'rql__%s__%s.html' % (this.label,tag)
292    atts = this.__dict__.keys()
293    atts.sort()
294    al =[]
295    for a in atts:
296      if a not in ['defaults','globalDefault']:
297        al.append( tmpl.item % {'item':'<b>%s</b>: %s' % (a,this.__dict__.get(a,'-- Not Set --')) } )
298    ee['items'] = string.join(al, '\n' )
299    ee['introduction'] = ''
300    ee['htmlBody'] = tmpl.indexWrapper % ee
301    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
302    self.pageHtml = tmpl.pageWrapper % ee
303    self.write()
304     
305  def mkVarHtml(self,name):
306    if len( inx.var.label[name] ) == 1:
307      self.mkVarHtml01(inx.var.label[name][0], name )
308    else:
309      self.mkVarHtmlGp(name)
310
311  def mkVarHtmlGp(self,name):
312    ee = {}
313    ee['title'] = 'CMIP Variable %s (with multiple definitions)' % name
314    self.pageName = 'var__%s.html' % name
315    al =[]
316    for i in range( len( inx.var.label[name] ) ):
317      this = inx.var.uuid[inx.var.label[name][i]]
318      al.append( tmpl.item % {'item':'<a href="var__%s__%s.html">[%s]</a>: %s' % (name,i,i,this.title) } )
319    ee['items'] = string.join(al, '\n' )
320    ee['introduction'] = ''
321    ee['htmlBody'] = tmpl.indexWrapper % ee
322    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
323    self.pageHtml = tmpl.pageWrapper % ee
324    self.write()
325    ##print 'Multi var: %s' % name
326    for i in range( len( inx.var.label[name] ) ):
327      self.mkVarHtml01(inx.var.label[name][i],i)
328
329  def mkVarHtml01(self,id, tag):
330    this = inx.var.uuid[id]
331    ee = {}
332    if this.label == tag:
333      ee['title'] = 'CMIP Variable %s' % tag
334      self.pageName = 'var__%s.html' % tag
335    else:
336      ee['title'] = 'CMIP Variable %s[%s]' % (this.label,tag)
337      self.pageName = 'var__%s__%s.html' % (this.label,tag)
338    atts = this.__dict__.keys()
339    atts.sort()
340    al =[]
341    for a in atts:
342      if a not in ['defaults','globalDefault']:
343        al.append( tmpl.item % {'item':'<b>%s</b>: %s' % (a,this.__dict__.get(a,'-- Not Set --')) } )
344
345    if inx.iref_by_uuid.has_key(this.uuid):
346      assert varRefs.has_key(this.uuid), 'Problem with collected references'
347      ee1 = varRefs[this.uuid]
348      ks = ee1.keys()
349      ks.sort()
350      for k in ks:
351        al.append( tmpl.item % {'item':'<b>%s</b>: %s' % (k,string.join(ee1[k])) } )
352    ee['items'] = string.join(al, '\n' )
353    ee['introduction'] = ''
354    ee['htmlBody'] = tmpl.indexWrapper % ee
355    ee['htmlHead'] = '''<title>%(title)s</title>''' % ee
356    self.pageHtml = tmpl.pageWrapper % ee
357    self.write()
358
359  def varHtml(self):
360    for k in inx.var.label.keys():
361      self.mkVarHtml(k)
362 
363  def rqlHtml(self):
364    for k in rql_by_name.keys():
365      self.mkRqlHtml(k)
366 
367  def write(self):
368    oo = open( '%s/%s' % (self.odir,self.pageName), 'w' )
369    oo.write( self.pageHtml )
370    oo.close()
371
372   
373vh = rqHtml()
374vh.varHtml()
375vh.rqlHtml()
376
377if nerr == 0:
378  print 'CHECK 001: %s records checked, no missing references' % nok
379
380##for k in xr_var_ovar.keys():
381  ##if len( xr_var_ovar[k] ) > 1:
382     ##print inx.var.uuid[k].label, map( lambda x: ix_ovar_uuid[x].mipTable,  xr_var_ovar[k]  )
383
384shps = {'': 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}
385vshpchkMap = {'':'', u'all model levels above 400hPa':'alevStrat', u'all':'Xlev', 3.0:'plev3', '4.0':'plev4', \
386            36.0:'plev36', u'soil levels':'sdepth', \
387            1.0:'sfc?', \
388           16.0:'plev16', 7.0:'plev7', 40.0:'plev40', u'all*':'Xlev', 14.0:'plev14', u'Model levels or 27Plevs':'alev|plev27', \
389           u'17 (or 23 )':'plev17|plev23', u'17 (or 23)':'plev17|plev23', \
390           27.0:'plev27', 17.0:'plev17', u'17 (or23)':'plev17|plev23', 8.0:'plev8', u'all model levels':'alev', 5.0:'plev5'}
391ks = vshpchkMap.keys()
392for k in ks:
393  if type(k) == type(0.):
394     vshpchkMap[str(k)] = vshpchkMap[k]
395
396print vshpchkMap.keys()
397
398tsmap = { 'mean':[u'daily mean', u'time mean', u'time: day',
399                u'Cumulative annual fraction', u'Time mean', u'weighted time mean', u'time: mean', u'mean', u'Mean'],
400          '__unknown__':['','dummyAt'],
401          'point':[ u'Instantaneous (end of year)', u'point', u'Synoptic', u'instantaneous', u'time: point', u'synoptic'] }
402tsmap2 = {}
403for k in tsmap.keys():
404  for i in tsmap[k]:
405    tsmap2[i] = k
406
407ee = collections.defaultdict( int )
408for i in dq.coll['groupItem'].items:
409  tst = tsmap2[ i.tstyle ]
410  dd = ''
411  if 'X' in i.shape:
412    dd += 'latitude '
413  if 'Y' in i.shape:
414    dd += 'longitude '
415  if 'Z' in i.shape:
416    if i.levels == '':
417      print 'ERROR.001.0001: no levels specified', i.label, i.title
418    else:
419      zdim = vshpchkMap[i.levels]
420      dd +=  zdim
421  ## print '%s::%s::%s|%s' % (i.shape, i.levels, i.tstyle, dd)
422
423class tcmp(object):
424  def __init__(self):
425    pass
426  def cmp(self,x,y):
427    return cmp(x.title,y.title)
428
429def atRepr(l,x):
430  v = l.__dict__[x]
431  if v == '__unset__':
432    return ''
433  else:
434    return v
435 
436def dumpcsv( fn, key, atl ):
437  oo = open(fn, 'w' )
438  ll = dq.coll[key].items[:]
439  ll.sort( tcmp().cmp )
440  oo.write( string.join( atl, '\t' ) + '\n' )
441  for l in ll:
442    oo.write( string.join( map( lambda x: atRepr(l,x), atl), '\t' ) + '\n' )
443  oo.close()
444
445def atlSort( ll ):
446  oo = []
447  l1 = ['label','title']
448  l2 = ['uuid','defaults','globalDefault']
449  for i in l1:
450    if i in ll:
451      oo.append(i)
452  ll.sort()
453  for i in ll:
454    if i not in l1 + l2:
455      oo.append(i)
456  if 'uuid' in ll:
457    oo.append( 'uuid' )
458  return oo
459
460for k in dq.coll.keys():
461  if len( dq.coll[k].items ) > 0:
462    expl = dq.coll[k].items[0]
463    atl = atlSort( expl.__dict__.keys() )
464    print k, atl
465    dumpcsv( 'csv2/%s.csv' % k, k, atl )
466 
467oo = open( 'var1.csv', 'w' )
468ks = ['label','title','sn','units','description','prov','procnote','procComment','uuid']
469ks2 = [ 'ovar','groupItem','revisedTabItem']
470oo.write( string.join(ks + ks2, '\t' ) + '\n' )
471for i in dq.coll['var'].items:
472   if i.label[-2:] != '--':
473     ee1 = varRefs.get( i.uuid, {} )
474     r2 = map( lambda x: string.join( ee1.get(x, [] ) ), ks2 )
475     oo.write( string.join(map( lambda x: i.__dict__[x], ks) + r2, '\t' ) + '\n' )
476oo.close()
477
478class annotate(object):
479  def __init__(self,src,dreq):
480    assert os.path.isfile( src), '%s not found' % src
481    self.doc = xml.dom.minidom.parse( src  )
482    self.dreq = dreq
483
484  def missingRefs(self,mrefs,clear=True):
485    this = self.doc.getElementsByTagName('remarks')[0]
486    if clear:
487      dil = this.getElementsByTagName('item')
488      for d in dil:
489        this.removeChild(d)
490    for k in mrefs.keys():
491      if len(  mrefs[k] ) == 1:
492        tid = mrefs[k][0][2]
493        tattr = mrefs[k][0][1]
494        tn = None
495      else:
496        tid = None
497        ee = collections.defaultdict(int)
498        tn = str( len( mrefs[k] ) )
499        for t in mrefs[k]:
500          s = self.dreq.inx.uuid[t[2]][0]
501          ee['%s.%s' % (s,t[1])] += 1
502        if len( ee.keys() ) == 1:
503          tattr = ee.keys()[0]
504        else:
505          tattr = '__multiple__'
506      item = self.doc.createElement( 'item' )
507      item.setAttribute( 'uuid', k ) 
508      item.setAttribute( 'tattr', tattr ) 
509      if tn != None:
510        item.setAttribute( 'techNote', tn ) 
511      if tid != None:
512        item.setAttribute( 'tid', tid ) 
513      item.setAttribute( 'class', 'missingLink' ) 
514      item.setAttribute( 'description', 'Missing links detected and marked for fixing' ) 
515      item.setAttribute( 'prov', 'scanDreq.py:annotate' ) 
516      this.appendChild( item )
517 
518    txt = self.doc.toprettyxml(indent='\t', newl='\n', encoding=None)
519    oo = open( 'annotated_20150731.xml', 'w' )
520    lines = string.split( txt, '\n' )
521    for line in lines:
522      l = utils_wb.uniCleanFunc( string.strip(line) )
523      if empty.match(l):
524        continue
525      else:
526        oo.write(l + '\n')
527    oo.close()
528
529doAnno = True
530if doAnno:
531  an = annotate( dq.c.vsamp, dq )
532  an.missingRefs( dq.inx.missingIds )
Note: See TracBrowser for help on using the repository browser.