source: CMIP6dreqbuild/trunk/src/framework/ingest/dreq_consol_dreq2.py @ 861

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/framework/ingest/dreq_consol_dreq2.py@861
Revision 861, 14.7 KB checked in by mjuckes, 4 years ago (diff)

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