source: CMIP6dreqbuild/trunk/src/framework/makeSuppl.py @ 1348

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/framework/makeSuppl.py
Revision 1348, 6.5 KB checked in by mjuckes, 3 months ago (diff)

01.00.32beta

Line 
1import xml, collections, uuid, os, re
2import xml.dom.minidom
3import datetime, time
4
5import utils_wb
6import scanLims
7from dreqPy import dreq
8from ingest import cmip5so
9import cf
10
11empty=re.compile('^$')
12rmap = {'mn':'valid_min', 'mx':'valid_max', 'amn':'ok_min_mean_abs', 'amx':'ok_max_mean_abs', 
13        'smn':'valid_min_status', 'smx':'valid_max_status', 'samn':'ok_min_mean_abs_status', 'samx':'ok_max_mean_abs_status' } 
14
15class addUnits(object):
16  def __init__(self,dq,wbi='misc/units.xlsx'):
17    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')     ]
18    eqss = {'N m-1':'Newton per metre','Pa':'pressure','m-1':'wavelength','m':'distance or height','s':'time','1':'unitless','m s-2':'acceleration','m2':'area','m3':'volume' }
19    eqcf = {}
20    for k in eqss:
21      eqcf[ cf.units.Units( k ) ] = k
22
23    wb = utils_wb.workbook( wbi )
24    sh = wb.book.sheet_by_name('units')
25    self.repl = {}
26    self.uu = {}
27    for j in range(1,sh.nrows):
28      r = sh.row(j)
29      if len(r[0].value) > 1 and r[0].value[0] == '#':
30        pass
31      else:
32        if len(r) > 5 and r[5].value != u'':
33          self.repl[ r[0].value ] = r[5].value
34        else:
35          a = cf.units.Units( r[0].value )
36          if a.isvalid:
37            for k in eqcf:
38              if a.equivalent(k):
39                thisg = eqss[eqcf[k]]
40          else:
41            thisg = None
42          self.uu[r[0].value] = ([x.value for x in r],thisg)
43
44    for k in self.repl:
45      if self.repl[k] not in self.uu:
46        print( 'Bad replacement found: %s --> %s' % (k,self.repl[k]) )
47
48    for i in dq.coll['var'].items:
49      if i.units in self.repl:
50        u = self.repl[i.units]
51      else:
52        u = i.units
53      u = u.strip()
54      if str(u) == '1.0':
55        u = '1'
56      if u not in self.uu:
57        print( 'UNITS NOT FOUND: %s (%s)' % (u,i.label) )
58
59class makeSuppl(object):
60  def __init__(self,src='out/dreqSuppSample.xml' ):
61    assert os.path.isfile( src), '%s not found' % src
62    self.doc = xml.dom.minidom.parse( src  )
63    self.dq = dreq.loadDreq( dreqXML='out/annotated_20150731_chk.xml', configdoc='out/dreq2Defn.xml', manifest=None)
64    self.cc = collections.defaultdict( dict )
65    for i in self.dq.coll['CMORvar'].items:
66      self.cc[i.mipTable][i.label] = i.uid
67    self.header()
68    self.makeQcRanges()
69    self.makeUnits()
70    self.makeClean()
71    self.write()
72
73  def header(self):
74    t = time.gmtime()
75    d = datetime.date(t.tm_year, t.tm_mon, t.tm_mday)
76    thiss = self.doc.getElementsByTagName('prologue')[0]
77    date = thiss.getElementsByTagName('dc:date')[0]
78    date.firstChild.replaceWholeText(d.isoformat())
79    vers = thiss.getElementsByTagName('pav:version')[0]
80    vers.firstChild.replaceWholeText(self.dq.version)
81    ttl = thiss.getElementsByTagName('dc:title')[0]
82    ttl.firstChild.replaceWholeText( 'CMIP6 Data Request Supplement [%s]' % self.dq.version)
83
84  def makeClean(self):
85    thiss = self.doc.getElementsByTagName('places')[0]
86    for item in thiss.getElementsByTagName('item'):
87      thiss.removeChild( item )
88    thiss = self.doc.getElementsByTagName('transfers')[0]
89    for item in thiss.getElementsByTagName('item'):
90      thiss.removeChild( item )
91
92  def makeUnits(self):
93    a = addUnits(self.dq)
94    thiss = self.doc.getElementsByTagName('units')[0]
95    for item in thiss.getElementsByTagName('item'):
96      thiss.removeChild( item )
97    for k in a.uu.keys():
98        r,thisg = a.uu[k]
99        item = self.doc.createElement( 'item' )
100        item.setAttribute( 'uid', str(r[7]) )
101        item.setAttribute( 'label', str(r[1]) )
102        item.setAttribute( 'title', str(r[2]) )
103        if str( r[4] ) != '':
104          item.setAttribute( 'group', str(r[4]) )
105        item.setAttribute( 'text', str(r[0]) )
106        if thisg != None:
107          item.setAttribute( 'group', str(thisg) )
108        thiss.appendChild( item )
109
110  def makeQcRanges(self):
111    thiss = self.doc.getElementsByTagName('qcranges')[0]
112    for item in thiss.getElementsByTagName('item'):
113      thiss.removeChild( item )
114    self.qcset = set()
115    for t in scanLims.s.ccc:
116      for v in scanLims.s.ccc[t]:
117        if t in self.cc and v in self.cc[t]:
118          vid = self.cc[t][v]
119          self.qcset.add( (t,v) )
120          item = self.doc.createElement( 'item' )
121          item.setAttribute( 'vid', vid )
122          item.setAttribute( 'uid', str( uuid.uuid1() ) )
123          for k in scanLims.s.ccc[t][v]._asdict().keys():
124            if scanLims.s.ccc[t][v]._asdict()[k] != None:
125              k1 = rmap.get( k,k )
126              val = scanLims.s.ccc[t][v]._asdict()[k]
127              val = utils_wb.uniCleanFunc( val )
128              item.setAttribute( k1, str(val) )
129          thiss.appendChild( item )
130        else:
131          print( 'WARN.0001.00001: no variables found for %s, %s' % (t,v) )
132
133    for t in scanLims.s.cm5:
134      for v in scanLims.s.cm5[t]:
135        if t in self.cc and v in self.cc[t] and (t,v) not in self.qcset:
136          xx = scanLims.s.cm5[t][v][3:]
137          yy = scanLims.s.cm5[t][v][:3]
138          if not all( [x == 'None' for x in xx] ):
139            vid = self.cc[t][v]
140            self.qcset.add( (t,v) )
141            item = self.doc.createElement( 'item' )
142            item.setAttribute( 'vid', vid )
143            item.setAttribute( 'uid', str( uuid.uuid1() ) )
144            item.setAttribute( 'title', str( yy[0] ) )
145            item.setAttribute( 'label', '%s-%s' % (t,v) )
146            item.setAttribute( 'prov', 'CMIP5 standard output spreadsheet' )
147            if len(xx) != 4:
148              print( 'WARN.lenx: ',t,v,scanLims.s.cm5[t][v] )
149            else:
150             for x in range(4):
151               id = ['valid_min','valid_max','ok_min_mean_abs','ok_max_mean_abs'][x]
152               if id in ['ok_min_mean_abs','ok_max_mean_abs']:
153                  if xx[x] != 'None' and float(xx[x]) < 0.:
154                     print( 'WARN.meanabs.00001: skipping negative value: %s-%s: %s=%s' % (t,v,id,xx[x]) )
155                     xx[x] = 'None'
156               if xx[x] != 'None':
157                 item.setAttribute( id, xx[x] )
158                 item.setAttribute( id + '_status', 'suggested' )
159               else:
160                 item.setAttribute( id + '_status', '' )
161             thiss.appendChild( item )
162   
163
164  def write(self):
165    txt = self.doc.toprettyxml(indent='\t', newl='\n', encoding=None)
166    oo = open( 'out/supplement_20150731.xml', 'w' )
167    lines = txt.split( '\n' )
168    for line in lines:
169      l = utils_wb.uniCleanFunc( line.strip() )
170      if empty.match(l):
171        continue
172      else:
173        oo.write(l + '\n')
174    oo.close()
175   
176
177ms = makeSuppl()
Note: See TracBrowser for help on using the repository browser.