source: CMIP6dreqbuild/trunk/srcMisc/dreq_consol_dreq2.py @ 876

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/srcMisc/dreq_consol_dreq2.py@1157
Revision 876, 13.7 KB checked in by mjuckes, 4 years ago (diff)

release candidate

Line 
1import string, uuid, shelve
2from fcc_utils2 import snlist
3import xlrd, string, shelve, os, re, sys
4import collections
5from utils_wb import workbook
6####
7import dreq_cfg
8import dreq_utils
9import utils_wb
10
11nt__pr4info = collections.namedtuple( 'r4info', ['ixcntl','ixh','ix0','ixm','ownix','ownhr','othix','othhr','mode','treset'] )
12
13class localMaps(object):
14##
15## expand groups in request row ...
16##   .. duplicates all request items
17##
18    groupExpand = {'ISMIP6.icesheetmon':['LImonant','LImongre'],
19                   'ISMIP6.icesheetyear':['LIyrant','LIyrgre'],
20                   'ISMIP6.icesheetfx':['LIfxant','LIfxgre']}
21
22base = '/home/martin/2014/wip/dreq/'
23dir0 = '/home/martin/2014/wip/dreq/input/'
24
25class rqsummary(object):
26  __doc__ = """Create a request summary table, by MIP and variable table.
27Creates a list of default dictionaries, one for each table. An entry for each MIP in each dictionary.
28"""
29  def __init__(self,exptInfo=None):
30    self.tablist = []
31    self.tabindx = {}
32    self.mips = collections.defaultdict( int )
33    self.exptInfo = exptInfo
34    self.rowList = []
35    self.records = []
36    self.tsliceMap = {}
37    self.tsliceMap['DAMIP'] = {'18 (1850, 1860, ..,  2010, 2020)':'DAMIP18', 'all':None, \
38             '8\n(2030, 2040, .., 2090, 2100)':'DAMIP8', \
39             '61\n(1960-2020)':'DAMIP61', \
40             '60\n(1961-2020)':'DAMIP60', \
41             '40\n(2041-2060, 2081-2100)':'DAMIP40', \
42             '40\n(2026-2045, 2081-2100) xx':'DAMIP40x', '20\n(2081-2100)':'DAMIP20', '42\n(1979-2020)':'DAMIP42' }
43    self.tsliceMap['SIMIP'] = {'Last 100':'piControl100' }
44    self.tsliceMap['VolMIP'] = {'3 (start)':'volMIP3'}
45    self.tsliceMap['RFMIP'] = {'4 (RFMIP_slice1)':'RFMIP'}
46    self.tsliceMaps = set()
47    for k in self.tsliceMap:
48      for x in self.tsliceMap[k]:
49        self.tsliceMaps.add(x)
50
51  def add(self):
52    return rq(parent=self)
53
54  def addRow( self, mip, tab, obj, grid, gok, comment,opt='',opar='',uid=None, preset=-2, vgid=None ):
55    if uid == None:
56      k = str( uuid.uuid1() )
57    else:
58      k = uid
59    self.rowList.append( (k,mip,tab, obj, grid, gok, comment, opt, opar, preset, vgid) )
60    return k
61
62  def addItem( self, mip, tab, nn, nexmax, nenmax, nymax, expt=None, rid=None, treset=None, info=None ):
63    if not self.tabindx.has_key( tab ):
64      self.tabindx[tab] = len(self.tablist)
65      self.tablist.append( collections.defaultdict( int ) )
66    ix = self.tabindx[tab]
67    self.tablist[ix][mip] = nn
68    self.mips[mip] += 1
69    if type(info) in [type(''), type(u'')]:
70      if info in ['','all','ALL']:
71         info = 'all'
72      else:
73         if info not in self.tsliceMaps:
74           print 'ERROR.tslice.00001: map not found [%s]: %s' % (mip, info.replace( '\n', '\\n' ) )
75    self.records.append( (mip,tab,expt, rid,nn, nexmax, nenmax, nymax,treset,info) )
76
77  def show(self,oo):
78    mips = self.mips.keys()
79    mips.sort()
80    keys = self.tabindx.keys()
81    keys.sort()
82    oo.write( ',' + string.join(mips, ',') + ',\n' )
83    for k in keys:
84      r = []
85      ix = self.tabindx[k]
86      for m in mips:
87        r.append( self.tablist[ix][m] )
88      print k,r
89      if max(r) > 0:
90        rec = '%s,' % k
91        for i in r:
92          rec += '%s,' %  i
93        oo.write( rec + '\n' )
94
95  def loadGroups(self):
96    wb = workbook( '../src/framework/ingest/sortedVarGroups.xls' )
97    ## label, mip, -, -, -, title, refNote, uid, ref
98    sh = wb.book.sheet_by_name( 'Sheet1' )
99    self.groupset = {}
100    for i in range( sh.nrows ):
101      rr = [x.value.strip() for x in sh.row(i)]
102      label, mip, a1, a2, a3, title, refNote, uid, ref = rr[:9]
103      assert uid not in self.groupset, 'Duplicate uid: %s:: %s,%s' % (uid,str(self.groupset[uid]),str(rr))
104      self.groupset[uid] = (uid,mip,label,title,ref,refNote)
105
106class rq(object):
107
108  def __init__(self, parent=None, idir='../src/framework/inSh' ):
109    self.parent = parent
110    sh = shelve.open('%s/sh__requestScoping' % idir, 'r' )
111    sh0 = shelve.open('%s/sh__requestScoping_0' % idir, 'r' )
112    sh1 = shelve.open('%s/sh__requestScoping_1' % idir, 'r' )
113    cc = collections.defaultdict( list )
114    ee = dict()
115    ff = dict()
116    mips = set()
117    for k in sh0.keys():
118      if k[0] != '_' and k[-3:] == '__0':
119        k1 = k[:-1] + '1'
120        k1b = k[:36]
121        assert k1b in self.parent.groupset, 'Group uid not recognised: %s, %s' % (k,str(sh0[k]))
122        if k1 in sh1:
123           mip1, vgid = sh1[k1]
124           assert vgid == k1b, 'mismatch in vgid found ... %s, %s' % (vgid,k1b)
125       
126        uid = k[:-3]
127        mip, rec = sh0[k]
128        cc[mip].append( (uid,rec,k1b) )
129        r4il, r4 = sh['__headings__'][mip]
130        ee[mip] = nt__pr4info._make( r4il )
131        ff[mip] = r4
132        mips.add(mip)
133
134    sh.close()
135    sh0.close()
136    sh1.close()
137    print 'MIPS:: ',sorted( list( mips ) )
138    for mip in sorted( list( mips ) ):
139      self.mip = mip
140##
141## r4 is the headings row, r4i is the parsed information.
142##
143      self.parse02( cc[mip], ee[mip], ff[mip] )
144
145  def parse02(self,recl,r4i,r4):
146
147    self.mipl = None
148    self.nbl = None
149##
150    for uid,rv,vgid in recl:
151        tab = rv[0]
152        if '%s.%s' % (self.mip,tab) in localMaps.groupExpand:
153          tabl = localMaps.groupExpand[ '%s.%s' % (self.mip,tab) ]
154        elif not( len(tab) > 0 and tab[0] == '#'):
155          tabl = [tab,]
156        else:
157          tabl = []
158        for tab in tabl:
159          grid = rv[3]
160          gok = rv[r4i.mode-2]
161          comment = rv[r4i.mode-1]
162          obj0 = rv[r4i.mode]
163          bb = string.split(obj0, ':' )
164          if len(bb) > 1:
165            obj = bb[0]
166            preset = int( bb[1] )
167          else:
168            obj = obj0
169            preset = -1
170          opt = rv[1]
171          opar = rv[2]
172          nbl = False
173          if not tab in ['',u'']:
174            if self.mip != 'DCPP':
175              for je in range(5):
176                j1 = r4i.ixcntl + je*2
177                ok = self.readDeckColPair( rv[j1:j1+2], rv[0], j1, 160, expt=string.strip(r4[j1]), rid=uid )
178                if ok:
179                  nbl = True
180            for je in r4i.ownix:
181                ok = self.readDeckColPair( rv[je:je+2], rv[0], je, 100, expt=string.strip(r4[je]), rid=uid )
182                if ok:
183                  nbl = True
184            for jei in range( len(r4i.othix) ):
185                je = r4i.othix[jei]
186                tr = r4i.treset[jei]
187                ok = self.readDeckColPair( rv[je:je+3], rv[0], je, 100, expt=string.strip(r4[je+1]), rid=uid,mode=3,treset=tr )
188                if ok:
189                  nbl = True
190### add row if non-blank element found
191          if nbl:
192              if preset != -1:
193                print 'INFO.preset.00001: setting preset: ',rv
194              uid = self.parent.addRow( self.mip, tab, obj, grid, gok, comment, opt=opt, opar=opar, uid=uid, preset=preset, vgid=vgid )
195    return True
196
197  def readDeckColPair( self,data, tab, ix, nydef, expt=None, rid=None, mode=2, treset=None ):
198      assert mode in [2,3], 'Only modes 2,3 supported, not mode=%s' % mode
199      ##this = map( lambda x: x.value, self.wk1.currentSi.row(j)[ix:ix+mode] )
200      this = data
201##  if this element is empty, return .. nothing to do.
202      if all( [x in {u'','',0,0.0} for x in this] ):
203        return False
204
205      if mode == 2:
206        snens, sny = this
207        cmt = '2:%s:%s:' % (snens,sny)
208      else:
209        snex, snens, sny = this
210        cmt = '3:%s:%s:%s:' % (snex,snens,sny)
211
212      nex = 0
213      nexmax = -999
214      if mode == 3:
215        print '######### MODE = 3: %s' % str(this)
216        if type( snex ) in  {type(u' '),type(' ')}:
217          if snex[:3] in {u'all',u'ALL'}:
218            nex = 5
219            nexmax = -1
220          elif snex[:3] in {u'tbd',u'TBD','tbd','TBD'}:
221            print 'WARN:005.0001: tbd encountered in experiment number'
222            nex = 5
223            cmt += '*'
224          else:
225            print 'ERROR.001.0010: string in experiment number: %s' % snex
226            nex = 0
227            cmt += '*'
228        else:
229          print 'WARN:005.0002: experiment number .... need to check consistency etc: %s' % self.mip
230          nex = int(snex)
231          nexmax = nex
232        if type(nex) not in {type(1.), type(1)}:
233          print 'ERROR.099.0100: non integer nex: %s:: %s:: %s' % (str(this),snex, type(snex))
234          raise
235
236      try:
237        if snens in [ u'all', u'ALL']:
238          nens = 1
239          nenmax = -1
240        elif snens == '':
241          nens = 0
242          nenmax = -999
243        elif snens == 'O':
244          nens = 0
245          nenmax = -999
246          print 'WARNING: *O* (oh) entered for ensemble number: %s, %s' % (self.mip, tab)
247        else:
248          nens = int( snens )
249          nenmax = nens
250
251        if sny in [ u'all', u'ALL']:
252          ny = nydef
253          ony = 'all'
254          nymax = -1
255        elif sny == '':
256          ny = 0
257          ony = 0
258          nymax = -999
259        elif type(sny) in [type('x'),type(u'x')]:
260            s = sny
261            if string.find( s, '\n' ) != -1:
262              bits = string.split( s, '\n' )
263              ny = int( bits[0] )
264              nymax = ny
265              cmt += '*'
266              print 'WARN.001.0001: [%s] truncating time period option: %s' % (self.mip, str(s) )
267            else:
268              x = string.split( s )[0]
269              if string.find( x, '-' ) != -1:
270                bb = string.split(x, '-' )
271                ny = int(bb[1])-int(bb[0])
272                print 'WARN.001.0002: [%s] truncating time period option: %s' % (self.mip, str(s) )
273                nymax = ny
274              elif string.find( x, '/' ) != -1:
275                bb = string.split(x, '/' )
276                ny = int(bb[0])
277                print 'WARN.001.0003: [%s] truncating time period option: %s' % (self.mip, str(s) )
278                nymax = ny
279              elif x[:4] == 'Last':
280                x = string.split( s )[1]
281                print 'WARN.001.0005: [%s] time period option read as string: %s' % (self.mip, str(s) )
282                ny = int( x )
283                nymax = ny
284              else:
285                print 'WARN.001.0004: [%s] time period option read as string: %s' % (self.mip, str(s) )
286                ny = int( x )
287                nymax = ny
288        else:
289          ny = sny
290          nymax = ny
291
292        if type( ny ) in [type( 'x' ),type( u'x' )]:
293          bits = string.split(ny) 
294          if bits[1] == u'period':
295            bb = string.split( bits[0], '-' )
296            ny = int(bb[1]) - int(bb[0])
297            raise
298
299        try:
300          if mode == 2:
301            ntot = nens*ny
302          else:
303            ntot = nex*nens*ny
304          if type(ntot) not in {type(1.), type(1)}:
305            print 'ERROR.099.0101: non integer ntot: %s:: %s' % (str([mode,nex,nens,ny]),str(this))
306            raise
307        except:
308          print self.mip, tab, nens, ny
309          raise
310
311        self.parent.addItem( self.mip, tab, ntot, nexmax, nenmax, nymax, expt=expt, rid=rid, treset=treset, info=sny )
312        return True
313      except:
314        print 'ERROR.002.0001: Failed trying to scan deck column pair.'
315        print self.mip,expt
316        raise
317
318class main(object):
319  def __init__(self,rqs, odir='sh20150827'):
320    self.rqs = rqs
321    self.rqs.loadGroups()
322    self.rqs.add()
323
324    oo = open( 'request02.csv', 'w' )
325    self.rqs.show( oo )
326    oo.close()
327
328    self.odir = odir
329
330  def rvg(self):
331### requestVarGroup = mip, label, title, uuid
332### requestLinks = vgid, objective, grid, gridreq, comment, uuid -- inherits label and title
333    sh = shelve.open( '%s/requestVarGroup02' % self.odir, 'n' )
334    sh['__info__'] = { 'label':'requestVarGroup', 'title':'Identify variable groups' }
335    sh['__cols__'] = [ 'uuid', 'mip', 'label','title','ref','refNote']
336## rows from "request scoping" analysed in *ingest* package of dreqPy
337    for u in self.rqs.groupset:
338        sh[str(u)] = self.rqs.groupset[u]
339    sh.close()
340
341  def rql(self):
342    s1 = set()
343    sh = shelve.open( '%s/requestLinks02' % self.odir, 'n' )
344    sh['__info__'] = { 'label':'requestLinks', 'title':'Links from variable groups to a request id' }
345    sh['__cols__'] = [ 'uid', 'mip', 'tab','objective','grid','gridreq','comment','opt','opar', 'preset', 'vgid']
346    for i in self.rqs.rowList:
347      assert i[-1] in self.rqs.groupset, 'vgid not found for %s' % str(i)
348      assert i[0] not in sh, 'duplicate uid found in requestlinks'
349      sh[i[0]] = i[:]
350      if i[3] in {'',u''}:
351        print 'ERROR.099.0060: Blank objective: %s' % str(i)
352      s1.add( i[0] )
353    sh.close()
354    sh = shelve.open( '%s/requestItems02' % self.odir, 'n' )
355    sh['__info__'] = { 'label':'requestItems', 'title':'Specification for a single experiment' , \
356         'comment':'Currently only has number of years -- need to include more details' }
357    sh['__cols__'] = [ 'mip', 'tab', 'expt','rlid','ny', 'nexmax', 'nenmax', 'nymax','treset','info']
358    ##('AerChemMIP', u'Omon_3d', u'CMIP6 historical', 'ad74be9a-26ef-11e5-8d9b-ac72891c3257', 0.0)
359    for i in self.rqs.records:
360      if type(i[4]) not in ( type(0), type(1.) ):
361          print 'ERROR.099.0001: non-integer ny: %s' % str(i)
362      expt = i[2]
363      if string.find( expt, '(' ) != -1:
364        expt = string.strip( expt[:string.find( expt, '(' )] )
365      if i[3] not in s1:
366        print 'SEVERE.005.00009: bad link ',i
367      if string.find( expt, ',' ) != -1 or (string.find( expt, ' ' ) != -1 and expt != "CMIP6 historical"):
368        bits = map( lambda x: string.strip(x), string.split( expt, ',' ) )
369        print 'INFO.expt.00006: ',i[:3], bits
370        for b in bits:
371          il = list(i)
372          il[2] = b
373          bb = dreq_utils.labcoerce(b)
374          k = str( uuid.uuid1() )
375          sh[k] =  il[:] 
376      else:
377        k = str( uuid.uuid1() )
378        if expt != i[2]:
379          il = list(i)
380          il[2] = expt
381          sh[k] =  il[:] 
382        else:
383          sh[k] =  i[:] 
384    sh.close()
385
386if __name__ == '__main__':
387  rqs= rqsummary()
388  m = main( rqs)
389  m.rvg()
390  m.rql()
Note: See TracBrowser for help on using the repository browser.