source: CMIP6dreqbuild/trunk/src/workbook/importShDreq.py @ 382

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

misc

Line 
1"""Import data request from shelves and put onto compliant XML document.
2------------------------------------------------------------------------
3A new uuid is generated for elements of the "revisedtabitem" section/table (because it is not present in the shelve).
4
5NOTES
6-----
7July 27th: there is an unresolved problem about preserving uuids when updates are provided in source format .....
8"""
9import xlrd, xml, os, sys, string
10import utils_wb, uuid
11import xml.dom, xml.dom.minidom
12import collections, string, re
13from utils_wb import uniCleanFunc
14
15empty=re.compile('^$')
16
17def test( x,m):
18  if not x:
19    print m
20  return x
21
22class lcm(object):
23  def __init__(self,a,b):
24    self.a = {}
25    self.b = {}
26    for i in a:
27      self.a[string.lower(i)] = i
28    for i in b:
29      self.b[string.lower(i)] = i
30
31class main(object):
32
33  def __init__(self,src,rq,repl=False):
34    self.src=src
35    self.repl = collections.defaultdict( list )
36    self.err0010 = collections.defaultdict( int )
37    self.replItems = {}
38    self.remo = {}
39    self.upda = {}
40    self.insert = {}
41    if repl:
42      self.importRepl()
43      self.importRemove()
44      self.importUpdate()
45      self.importInsert()
46    self.e15_10 = 0
47   
48    fok = [test(os.path.isfile(src),'%s not found' % src), ]
49
50    assert all( fok), 'Required input file(s) missing'
51
52    for sh in [rq.refti, rq.revti, rq.vars, rq.grps, rq.rqvg, rq.rqli, rq.rqit, rq.rqsect]:
53       print sh['__info__']
54
55    doc = xml.dom.minidom.parse( src  )
56    main = doc.childNodes[0]
57    xsn = []
58    ff = {}
59    for c in main.childNodes:
60      tag = c.nodeName
61      if tag != '#text':
62        xsn.append(tag)
63        il = []
64        for i in c.childNodes:
65          if i.nodeName == 'item':
66            il.append(i)
67        xx = dict( il[0].attributes.items() )
68        ff[string.lower(tag)] = (c,xx)
69   
70    print xsn
71    print ff.keys()
72
73    addex = False
74    exrqvg = {}
75    if addex:
76      ###
77      extravg = [['OMIP', u'OMIP-Oyr', u'OMIP: OMIP-Oyr', 'CMIP5Rev', u'OMIP.Oyr'],
78               ['OMIP', u'OMIP-Omon', u'OMIP: OMIP-Omon', 'CMIP5Rev', u'OMIP.Omon'],
79               ['OMIP', u'OMIP-day', u'OMIP: OMIP-day', 'CMIP5Rev', u'OMIP.day'],
80               ['OMIP', u'OMIP-fx', u'OMIP: OMIP-fx', 'CMIP5Rev', u'OMIP.fx'] ]
81      for r in extravg:
82        thisuuid = str( uuid.uuid1() )
83        exrqvg[thisuuid] = [thisuuid ,] + r[:]
84   
85    self.eern = collections.defaultdict( list )
86    self.eern2 = {}
87    ixrn = 5
88    dups = []
89    ##for k in rq.rqvg.keys():
90      ##if k[0] != '_':
91    for i,k in [ (rq.rqvg[k],k) for k in  rq.rqvg.keys() if k[0] != '_'] + [(exrqvg[k],k) for k in exrqvg.keys()]:
92        kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'ref', 'refNote', 'refid']
93        kk = ['uuid', 'mip', 'label', 'title', 'ref', 'refNote']
94        ##i = rq.rqvg[k]
95       
96        self.eern[i[ixrn]].append( i[0] )
97        k2 = '%s__%s' % (i[ixrn-1],i[ixrn])
98        if self.eern2.has_key( k2 ):
99           dups.append( (k2,k,self.eern2[k2]) )
100        self.eern2[k2] = i[0]
101        assert i[0] == k, 'Bad key/uuid'
102
103    assert len( dups ) == 0, 'Duplicate refs: %s, %s' % (str(dups),str(map( lambda x: rq.rqvg[x[1]], dups )) )
104       
105    for k in [ 'var','ovar','groupitem', 'revisedtabitem', 'requestlink', 'requestitem','requestvargroup','tablesection' ]:
106    ##for k in [ 'var']:
107      thissh = {'var':rq.vars,'ovar':rq.refti, 'groupitem':rq.grps, \
108         'revisedtabitem':rq.revti, 'requestlink':rq.rqli, 'requestitem':rq.rqit, \
109         'requestvargroup':rq.rqvg, 'tablesection':rq.rqsect}[k]
110      lll = []
111      for i in thissh.keys():
112        if i[0] != '_':
113          lll.append(i)
114      idk = 0
115      if len(lll) > 0:
116        dil = ff[k][0].getElementsByTagName('item')
117        for d in dil:
118          ff[k][0].removeChild(d)
119        vare = {}
120        vare2 = {}
121        for i in lll:
122          ll = map( uniCleanFunc, thissh[i] )
123          assert len(ll) == len( thissh[i] ), 'Lost list elements after uniClean'
124          idk += 1
125#################################################################
126######### NEED TO CLEAN THIS IF ITEMS FROM OTHER SECTIONS ARE FILTERED
127#######################################################################
128          if k != 'var':
129            item = doc.createElement( 'item' )
130            item.setAttribute( 'id', 'tmpid.%4.4i' % idk )
131          dothis = True
132          if k == 'var':
133##- sn; units; description; procnote; procComment; prov
134##['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov']
135            thisl = string.strip(str( ll[0] ) )
136            thisuuid = str(i)
137            if not ( self.replItems.has_key( str(i) ) or self.remo.has_key(str(i)) ):
138              item = doc.createElement( 'item' )
139              item.setAttribute( 'id', 'tmpid.%4.4i' % idk )
140              item.setAttribute( 'uuid', str(i) )
141              item.setAttribute( 'title', str(ll[1]) )
142              item.setAttribute( 'sn', str(ll[2]) )
143              item.setAttribute( 'units', str(ll[3]) )
144              item.setAttribute( 'description', str(ll[4]) )
145              item.setAttribute( 'procnote', str(ll[5]) )
146              item.setAttribute( 'procComment', str(ll[6]) )
147              item.setAttribute( 'prov', str(ll[7]) )
148              vare[ll[3]] =  ll[1]
149              if self.upda.has_key( thisuuid ):
150                for tag in self.upda[thisuuid]['tags']:
151                  if tag == 'label':
152                    thisl = self.upda[thisuuid][tag]
153                  else:
154                    item.setAttribute( tag, self.upda[thisuuid][tag] )
155            else: 
156              print 'Omitting: ',ll
157              dothis = False
158          elif k == 'ovar':
159## 
160            tab2freq = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
161       u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
162       u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
163       u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
164       u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
165       u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
166       u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
167       u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'day', \
168       u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
169       u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
170       u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr'}
171            kk = ['uuid', 'comment', 'deflate_level', 'shuffle', 'ok_max_mean_abs', 'flag_meanings', 'type', 'ok_min_mean_abs', 'sn', 'deflate', 'title', 'valid_min', 'cell_methods', 'flag_values', 'cell_measures', 'out_name', 'modeling_realm', 'units', 'cell_methods_xx', 'valid_max', 'positive', 'var', 'mipTable', 'dimensions', 'vid', 'gpid','rowIndex']
172## uuid; comment; deflate_level; shuffle; ok_max_mean_abs; flag_meanings; type; ok_min_mean_abs; sn; deflate; valid_min; cell_methods; flag_values; cell_measures; out_name; modeling_realm; units; cell_methods_xx; valid_max; positive; var; mipTable; dimensions; vid
173
174            thisl = string.strip( str( ll[21] ) )
175            for j in range( min(len(kk),len(ll)) ):
176              if j != 21:
177                item.setAttribute( kk[j], str( ll[j] ) )
178            if len(ll) < len(kk):
179              print 'ERROR.015.0001: record length short %s (%s):: %s' % (len(ll),len(kk),ll)
180
181            if ll[22][-3:] in ['mon','day','3hr']:
182              fr = ll[22][-3:]
183            elif ll[22][-2:] in [ 'yr','fx']:
184              fr = ll[22][-2:]
185            else:
186              fr = tab2freq[ll[22]]
187   
188            item.setAttribute( 'frequency', fr )
189            thisuuid = ll[0]
190            if self.repl.has_key( thisuuid ):
191              for tag,old,new in self.repl[thisuuid]:
192                thisold = item.getAttribute( tag )
193                assert thisold == old, 'Attempt to replace value which is not present'
194                item.setAttribute( tag, new )
195          elif k == 'groupitem':
196            kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uuid', 'new', 'gpid', 'vkey', 'vid']
197            assert len(kk) == len(ll), 'length mismatch, %s  %s' % (len(kk),len(ll))
198# - group;  table; freq; descriptionEx; shape; levels; tstyle; mask; mip; mip2; uuid; new; vid
199            thisl = string.strip(str( ll[1] ) )
200            for j in range(len(kk)):
201              if j != 1:
202                ##item.setAttribute( kk[j], str( ll[j] ) )
203                if kk[j] == 'misc':
204                  item.setAttribute( 'priority', str( ll[j] ) )
205                else:
206                  item.setAttribute( kk[j], str( ll[j] ) )
207            item.setAttribute( 'title', thisl )
208            if string.find(thisl, ' ') != -1:
209              thisl = string.split(thisl)[0]
210            thisuuid = ll[11]
211            gpid = str(ll[-3])
212            if not rq.rqvg.has_key(gpid):
213              print 'ERROR.015.0010: gpid not found %s' % str(ll)
214              self.e15_10 += 1
215            if self.repl.has_key( thisuuid ):
216              for tag,old,new in self.repl[thisuuid]:
217                thisold = item.getAttribute( tag )
218                assert thisold == old, 'Attempt to replace value which is not present'
219                item.setAttribute( tag, new )
220##################################
221          elif k == 'revisedtabitem':
222#### need to fill gaps in variable groups --- or do better job upstream ##########  !!!!!!!!!!!!!!!!
223## - table; mip; uuid; priority
224##
225## variable group ids pulled through via mapping above .. very messy
226## still missing some OMIP matches .... OMIP revised tables are not explicitly requested anywhere.
227##
228            kk = ['var', 'table', 'mip', 'vid', 'priority']
229            kvg = 'CMIP5Rev__%s.%s' % ( ll[2],ll[1] )
230            kvg3 = 'rev__%s.%s' % ( ll[2],ll[1] )
231            if self.eern2.has_key(kvg):
232              vgid = self.eern2[kvg]
233            elif self.eern2.has_key(kvg3):
234              vgid = self.eern2[kvg3]
235            elif cmip5GrpLk[ll[1]].has_key(ll[0]):
236              g2 = cmip5GrpLk[ll[1]][ll[0]]
237              kvg2 = 'CMIP5Rev__%s.%s' % ( ll[2],g2 )
238              if self.eern2.has_key(kvg2):
239                vgid = self.eern2[kvg2]
240              else:
241                vgid = '__vg_not_found_1__'
242                self.err0010[kvg] += 1
243            else:
244              vgid = '__vg_not_found_2__'
245              self.err0010[kvg] += 1
246            thisuuid = str( uuid.uuid1() )
247            thisl = string.strip(str( ll[0] ) )
248            for j in range(len(kk)):
249              if j != 0:
250                item.setAttribute( kk[j], str( ll[j] ) )
251            item.setAttribute( 'title', thisl )
252            item.setAttribute( 'uuid', thisuuid )
253            item.setAttribute( 'vgid', vgid )
254            if self.insert.has_key(thisl):
255                thisold = item.getAttribute( 'vid' )
256                if thisold == '__new__':
257                  item.setAttribute( 'vid', self.insert[thisl] )
258
259##################################
260          elif k == 'requestlink':
261 ## - uuid; mip; tab; objective; grid; gridreq; comment
262            kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','ref', 'refNote', 'refid']
263            emap = {'uid':'uuid'}
264            thisl = string.strip(str( ll[2] ) )
265            for j in range(len(kk)):
266                thiskk = emap.get(  kk[j],  kk[j] )
267                try:
268                  item.setAttribute( thiskk, str( ll[j] ) )
269                except:
270                  print 'ERROR.099.0001: Failed to set attribute: %s [%s]' % (str(ll),j)
271                  item.setAttribute( thiskk, '__error_99_1__' )
272
273            item.setAttribute( 'title', thisl )
274##################################
275          elif k == 'requestitem':
276 ## - mip; tab; expt; rlid; ny
277            kk = ['mip', 'tab', 'expt', 'rlid', 'ny']
278            thisl = string.strip(str( '%s-%s-%s' % (ll[0],ll[1],ll[2]) ) )
279            for j in range(len(kk)):
280                if kk[j] == 'ny':
281                  thisv = str( int(ll[j]) )
282                else:
283                  thisv = str( ll[j] )
284                item.setAttribute( kk[j], thisv )
285            item.setAttribute( 'title', '%s, %s, %s' % (ll[0],ll[1],ll[2]) )
286            item.setAttribute( 'uuid', str(i) )
287##################################
288          elif k in ['requestvargroup','tablesection']:
289            if k == 'requestvargroup':
290              kk = ['uuid', 'mip', 'label', 'title', 'ref', 'refNote']
291            else:
292              kk = ['uuid', 'gpid', 'mip', 'label', 'title', 'ref', 'refNote']
293            thisl = string.replace( str( ll[2] ), '.', '-' )
294            for j in range(len(kk)):
295                item.setAttribute( kk[j], str( ll[j] ) )
296####
297          if dothis:
298            if string.find( thisl, '_' ) != -1:
299              #print 'WARNING: underscore in label', ll
300              thisl = string.replace( thisl, '_', '-' )
301            if string.find( thisl, '*' ) != -1:
302              #print 'WARNING: star in label', ll
303              thisl = string.replace( thisl, '*', '-' )
304            if string.find( thisl, '!' ) != -1:
305              #print 'WARNING: exclamation in label', ll
306              thisl = string.replace( thisl, '!', '-' )
307            if string.find( thisl, ' ' ) != -1:
308              #print 'WARNING: space in label', ll
309              thisl = string.replace( thisl, ' ', '-' )
310            if string.find( thisl, ':' ) != -1:
311              #print 'WARNING: colon in label', ll
312              thisl = string.replace( thisl, ':', '-' )
313            item.setAttribute( 'label', thisl )
314            if k == 'var':
315              vare2[item.getAttribute('units')] =  item.getAttribute('label')
316            ff[k][0].appendChild( item )
317        if k == 'var':
318            print '******************************************'
319            print vare.keys()
320            print vare2.keys()
321            print '******************************************'
322           
323    ##for k in rqvg_extra.keys():
324            ##item = doc.createElement( 'item' )
325            ##ff['...' ][0].appendChild( item )
326
327    this = doc.getElementsByTagName('remarks')[0]
328    dil = this.getElementsByTagName('item')
329    for d in dil:
330          this.removeChild(d)
331
332    txt = doc.toprettyxml(indent='\t', newl='\n', encoding=None)
333    oo = open( 'trial_20150831.xml', 'w' )
334    lines = string.split( txt, '\n' )
335    for line in lines:
336      l = utils_wb.uniCleanFunc( string.strip(line) )
337      if empty.match(l):
338        continue
339      else: 
340        oo.write(l + '\n')
341    oo.close()
342
343  def importRepl(self,rfile='uuidreplace.csv'):
344    for l in open(rfile).readlines():
345      bits = string.split( string.strip(l), '\t' )
346      assert len(bits) == 7, 'Could not parse item replacement file'
347      self.repl[ bits[3] ].append( (bits[2],bits[0],bits[1] ) )
348      self.replItems[bits[0]] = bits[1]
349
350  def importRemove(self,rfile='uuidremove.csv'):
351    for l in open(rfile).readlines():
352      self.remo[ string.strip(l) ] = 1
353
354  def importUpdate(self,rfile='uuidupdate.csv'):
355    for l in open(rfile).readlines():
356      bits = string.split( string.strip(l), '\t' )
357      tgs = string.strip( bits[2] )
358      if string.find( tgs, ' ' ) == -1:
359        tags = [tgs,]
360      else:
361        tags = string.split( tgs )
362      self.upda[ bits[0] ] =  {'comment':bits[1], 'tags':tags, 'label':bits[3], 'title':bits[4] }
363
364  def importInsert(self,rfile='uuidinsert.csv'):
365    for l in open(rfile).readlines():
366      bits = string.split( string.strip(l), '\t' )
367      if bits[0] == 'unique':
368         self.insert[bits[1]] = bits[3]
369
370sampleXml = '../framework/out/dreqSample.xml'
371cmip5GrpLk = collections.defaultdict( dict )
372from scansh import rq
373
374for k in rq.cmip5Grps.keys():
375  bits = string.split(k,'_')
376  tab = bits[0]
377  for v in rq.cmip5Grps[k]:
378    cmip5GrpLk[tab][v] = k
379m = main(sampleXml, rq)
380if len(m.err0010.keys()) > 0:
381  ks = m.err0010.keys()
382  ks.sort()
383  for k in ks:
384    print 'ERROR.001.0010: variable group not identified: %s [%s]' % (k,m.err0010[k])
Note: See TracBrowser for help on using the repository browser.