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

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

various

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