source: CMIP6dreqbuild/trunk/srcMisc/dreq_utils.py @ 926

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/srcMisc/dreq_utils.py@1157
Revision 926, 13.4 KB checked in by mjuckes, 3 years ago (diff)

stripped sx203.py from sx202.py

Line 
1
2import string, collections, shelve, uuid
3from sets import Set
4from utils_wb import uniCleanFunc
5
6def labcoerce(s,nodash=True):
7  s = string.replace(s, '.', '' )
8  s = string.replace(s, '+', '' )
9  s = string.replace(s, '/', ' ' )
10  s = string.replace(s, '--', '-' )
11  if nodash:
12    if string.find(s, '-' ) != -1:
13      s = string.replace(s, '-', ' ' )
14    if string.find(s, ' ' ) != -1:
15      s = string.replace( string.capwords( s ), ' ', '' )
16    return s
17  else:
18    return s
19
20class varKeys(object):
21  def __init__(self,file='dreq_consol_tables_shelve_v20160309' ):
22    sh = shelve.open( file, 'r' )
23    cc = collections.defaultdict( list )
24    self.keys = {}
25    for k in sh:
26      cc[ tuple( [sh[k][x] for x in [0,1,3,5,10]] ) ].append( k )
27    for t in cc.keys():
28      if len(cc[t]) == 1:
29        self.keys[t] = cc[t][0]
30      elif t[1] in ['','*'] or t[1][0] == '#':
31          print 'INFO.vark.0001: ignoring %s' % str(t)
32      elif all( [sh[kk][4] in ['Greenland','Antarctica'] for kk in cc[t]] ):
33        for kk in cc[t]:
34          t1 = tuple( list(t) + [sh[kk][4],] )
35          print 'INFO.vark.0004: Greenland/Antarctic pair',t1
36          self.keys[t1] = kk
37    sh.close()
38
39  def lookuprec(self,r ):
40    t = tuple( [r[x] for x in [0,1,3,5,10]] )
41    if r[4] in  ['Greenland','Antarctica']:
42      t1 = tuple( list(t) + [r[4],] )
43      if t1 in self.keys:
44        if t in self.keys:
45          print 'WARNING.vark.0002: duplicate key %s -- %s' % (str(t),str(t1))
46          return self.keys[t]
47        else:
48          return self.keys[t1]
49      else:
50        print 'WARNING.vark.0003: key not found: ',r,t1
51    if t in self.keys:
52       return self.keys[t]
53    print 'INFO.vark.0003: new key: %s' % str(t) 
54    return str( uuid.uuid1() )
55   
56class loadcsv(object):
57  def __init__(self,vdate):
58    self.eeoldl = collections.defaultdict( list )
59    self.ee_xref = {}
60    self.ee_mip = {}
61    self.cmv = collections.defaultdict( list )
62    for ee,fn,sep,xxx,nrmin in [(self.ee_xref,'vlsc5_xref_v%s.csv' % vdate,',',False,5),(self.ee_mip,'vlsc5_mip_v%s.csv' % vdate, '\t',False,24),(self.eeoldl,'vlsc5b_v%s.csv' % vdate, '\t',True,9)]:
63      for i in open(fn).readlines():
64        r = map( lambda x: string.strip(str(uniCleanFunc(x))), string.split( string.strip(i), sep ) )
65        while len(r) < nrmin:
66          r.append( '' )
67        if xxx:
68          ee[r[0]].append( r )
69        else:
70          ee[r[0]] = r
71
72    for k in self.ee_mip.keys():
73      r = self.ee_mip[k]
74      v = r[21]
75      if string.strip(v) == '':
76        v = r[15]
77      mtab = r[22]
78      kk = '%s.%s' % (mtab,v)
79      self.cmv[kk].append( k )
80
81
82class prconsolexpt(object):
83  def __init__(self):
84    self.records = []
85    self.edict = {}
86    self.info =['label','group','mip','description','modelClass','tier','nstart','starty','endy','yps','ensz','ntot','comment'] 
87
88  def parse(self,sh, extra=None):
89    for j in range(2,sh.nrows):
90        r = map( lambda x: x.value, sh.row(j) )
91        n = string.strip( str(r[0]) )
92        n2 = string.strip( str(r[4]) )
93        if (extra != None and n2 in extra) or n in ['0','0.0',0,0.0]:
94          print 'prconsolexpt: replace %s --> %s' % (n,n2)
95          n = n2
96        elif extra != None and n not in extra:
97          print 'WARN.expt.00010: unrecognised expt name: %s (%s) ' % (n,n2)
98
99        g = string.strip( r[1] )
100        mip = string.strip( r[3] )
101        desc = string.strip( r[7] )
102       
103        mcfg = string.strip( r[8] )
104        comment = ''
105        try:
106          if type(r[5]) == type(1.):
107            tier = int( r[5] )
108          else:
109            tier = [int( x) for x in string.split( r[5] )]
110        except:
111          print 'ERROR.001.0001: tier not integer: %s, %s' % (mip,r[5])
112          if r[5][:3] == 'Sub':
113            tier = 1
114            comment += 'Tiering of sub-components .....'
115          else:
116            raise
117        if extra != None and n in extra:
118          desc = extra[n]['experiment']
119          comment = extra[n]['description']
120
121        ll = []
122        for j in [6,11,12,13]:
123          try:
124            if type(r[j]) == type(1.):
125              v = int( r[j] )
126            else:
127              v = [int( x) for x in string.split( r[j] )]
128            ll.append( v )
129          except:
130            k = {6:'nstart', 11:'years per sim', 12:'ensemble size', 13:'total number of years'}[j]
131            try:
132              if string.find( r[j], '-' ) != -1:
133                ll.append( int( string.split( r[j], '-' )[0] ) )
134              else:
135                try:
136                  ll.append( int( string.split( r[j] )[0] ) )
137                except:
138                  print 'Failed to convert to integer ',r[j]
139                  print r
140                  raise
141              comment += ': %s abbreviated: %s' % (k,r[j])
142              print 'ERROR.001.0002: %s not integer: %s, %s' % (k,mip,r[j])
143            except:
144              raise
145        starty =  r[9] 
146        endy =  r[10] 
147        nstart, yps, ensz, ntot = ll
148        ##yps = int( r[11] )
149        ##ensz = int( r[12] )
150        ##ntot = int( r[13] )
151
152
153        self.edict[n] = (n,g,mip,desc,mcfg,tier,nstart,starty,endy,yps,ensz,ntot,comment)
154        self.records.append( [n,g,mip,desc,mcfg,tier,nstart,starty,endy,yps,ensz,ntot,comment] )
155
156class probj(object):
157  def __init__(self):
158    self.records = []
159
160  def parse(self,mip,sh):
161    st = False
162    r = None
163    for j in range(sh.nrows):
164      r = map( lambda x: x.value, sh.row(j) )
165      if st:
166        rr = [string.strip(x) for x in r]
167        if all( [rx == '' for rx in rr[:3]] ):
168          pass
169          ## omit of all blank
170        elif any( [rx == '' for rx in rr[:3]] ):
171          print 'Record with blank(s): %s: %s' % (mip,str(rr) )
172          self.records.append( (mip,rr[0],rr[1],rr[2]) )
173        else:
174          self.records.append( (mip,rr[0],rr[1],rr[2]) )
175      elif r[0] == 'Short name':
176        st = True
177
178class prcexr(object):
179  """Parse a row of the consolidated experiment sheet"""
180
181  def __init__(self,dd=None):
182    self.nt = collections.namedtuple( 'r4info', ['label','group','ix','mip','altLabel','tier','nstart','description','config','start','end','lsim','ensSize','ntot','startNote','tierNote'] )
183    if dd != None:
184      ks = sorted( dd.keys() )
185      for k in ks:
186        self.parse( k, dd[k] )
187
188  def parse(self,rv):
189    rr = rv[:14]
190    startNote = ''
191    tierNote = ''
192    try:
193     for j in [2,5,6,11,12,13]:
194       if j == 5 and type(rr[j]) == type(u'x') and rr[j][:4] == 'Sub-':
195         tierNote = rr[j]
196         rr[j] = -1
197       elif type(rr[j]) == type(u'x') and (string.find(rr[j], 'to') != -1 or string.find(rr[j], 'or') != -1):
198         rr[j] = int( string.split( rr[j] )[-1] )
199       elif type(rr[j]) == type(u'x') and (string.find(rr[j], '-') != -1):
200         rr[j] = int( string.split( rr[j], '-' )[-1] )
201       elif  j == 2 and rr[j] == '':
202         rr[j] = -1
203       else:
204         rr[j] = int( rr[j] )
205     for j in [9,10]:
206       if rr[j] == '':
207         rr[j] = 0
208       else:
209         try:
210           rr[j] = int( rr[j] )
211         except:
212           if j == 9:
213             startNote = rr[j]
214           else:
215             print startNote, rr
216             startNote += ( ' -- %s' % rr[j] )
217           rr[j] = -1
218    except:
219      print rr
220      raise
221    rr.append( startNote )
222    rr.append( tierNote )
223    self.row = self.nt._make( rr  )
224
225class pr4(object):
226  """Parse row 4 of the request scoping sheet"""
227
228  def __init__(self,dd=None):
229    self.nt = collections.namedtuple( 'r4info', ['ixcntl','ixh','ix0','ixm','ownix','ownhr','othix','othhr','mode','treset'] )
230
231    if dd != None:
232      ks = sorted( dd.keys() )
233      for k in ks:
234        self.parse( k, dd[k] )
235
236  def parse3(self,mip,r3):
237        if r3[6] == 'objectives served':
238          mode = 6
239        elif r3[7] == 'objectives served':
240          mode = 7
241        else:
242          raise 'Unable to parse heading'
243          mode = 999
244        self.r3info = mode
245       
246  def parse(self,mip,r4):
247    if r4[6][:17] == 'objectives served':
248          mode = 6
249    elif r4[7][:17] == 'objectives served':
250          mode = 7
251    else:
252          print 'Unable to parse heading %s' % str(r4)
253          print mip
254          print r4
255          raise
256          mode = 999
257    self.ixh = 0
258    self.ixh = 0
259    self.ix0 = 0
260    hhref = [u'control', u'AMIP', u'abrupt4xCO2', u'1pctCO2', u'CMIP6 historical']
261
262    try:
263      self.ixh = r4.index( u'CMIP6 historical' )
264      self.ixm = r4.index( u'MIP name:' )
265      self.ix0 = self.ixh + 2
266      if r4[self.ixh-8] == u'control':
267        self.iccntl = self.ixh-8
268        hh = []
269        for j in range(5):
270          hh.append( r4[self.iccntl + j*2] )
271          if hh[j] != hhref[j]:
272            print 'ERROR.001.002: mismatch in heading %s' %j, r4
273      else:
274        print 'ERROR.001.001: control expt. column not found', r4
275    except:
276      if mip == 'DCPP':
277       try:
278        self.ix0 = r4.index( u'DCPP-A' )
279        self.ixm = self.ix0+8
280        self.ixh = -1
281        self.iccntl = self.ix0
282        hh = []
283        for j in range(4):
284          hh.append( r4[self.iccntl + j*2] )
285       except:
286        print '!!!!!!!!!!!', r4
287        raise
288      else:
289        print 'Failed to parse Row 4'
290        print r4
291        raise
292
293    self.ownex = []
294    self.othex = []
295    self.othetrst = []
296    for j in range(self.ix0,self.ixm,2):
297      if string.strip(r4[j]) != '':
298        self.ownex.append(j)
299    for j in range(self.ixm,len(r4)-1,3):
300      if string.strip(r4[j+1]) != '':
301        self.othex.append(j)
302        if r4[j+2] != '':
303          self.othetrst.append(int(r4[j+2]))
304        else:
305          self.othetrst.append('')
306   
307    print mip, self.ixh, self.iccntl, self.ix0, self.ixm , self.ownex, self.othex
308    ownhr =  map(lambda x: r4[x], self.ownex)
309    othhr =  map(lambda x: r4[x+1], self.othex)
310    print 'pr4:INFO: ',ownhr, othhr
311    self.r4info = self.nt( self.iccntl, self.ixh, self.ix0, self.ixm, self.ownex, ownhr, self.othex, othhr,mode,self.othetrst )
312    ##( 'r4info', ['ixcntl','ixh','ix0','ixm','ownix','ownhr','othix','othhr','mode'] )
313
314class parseShb(object):
315  def __init__(self,vdate,sx,cmip5gplk):
316    """Parse **'dreq_consol_tables_reviewed_b_v%s' % vdate** from dreq_consol_tables.py"""
317    shb = shelve.open( 'dreq_consol_tables_reviewed_b_v%s' % vdate, 'r' )
318    revTabIds = Set( shb.keys()[:] )
319    revisedTabKeys = shb.keys()
320    revisedTabKeys.sort()
321    revisedTabKeysff = []
322    revisedTabKeysNM = {}
323    tabsects = collections.defaultdict( Set )
324    tabsectbyvar = collections.defaultdict( dict )
325    tabsectuuid = collections.defaultdict( dict )
326    tabuuid = {}
327    tabuuidrefs = collections.defaultdict( int )
328    sn = set()
329    for r in revisedTabKeys:
330      if not tabuuid.has_key( r ):
331        tabuuid[r] = str( uuid.uuid1() )
332##
333## need to get this information from requestLink_tmp -----
334##
335      preset = -3
336      if string.find( r, '.' ) != -1:
337        mip,tab = string.split(r, '.' )
338        assert sx.cmip5so.so.has_key(tab), 'FATAL.001.0001: revised table not found in original: %s' % tab
339        lnf = []
340        lpe = []
341        lmod = []
342        s1 = set()
343        for v in shb[r].keys():
344          v1 = string.strip(v)
345          s1.add(v1)
346          if not sx.cmip5so.so[tab].a.has_key(v1):
347            if mip != 'OMIP':
348              lnf.append(v)
349          else:
350            if shb[r][v][1] == sx.cmip5so.so[tab].a[v1][0]:
351              lpe.append(v)
352            else:
353              lmod.append(v)
354##
355## index sections of tables (for OMIP)
356##
357          tup = shb[r][v]
358      ### tup=(ix,p,sect,rowix)
359          if tup[2] != None:
360            tabsects[mip].add( (tab,tup[2]) )
361            tabsectbyvar[mip]['%s.%s' % (tab,v)] = tup
362            sk = '%s.%s' % (tab,tup[2])
363            if not tabsectuuid[mip].has_key( sk ):
364              tabsectuuid[mip][sk] = str( uuid.uuid1() )
365##
366## want to copy to Omon ... but involves change of frequency ... and dimensionality ....
367## so can only, here, reserve a uid for the tbd new cmor variable, a link of where it is coming from
368## and extend the OMIP.Omon table in tabsectbyvar
369##
370          if r == 'OMIP.Oyr':
371            if tup[2] == 'bgc' and tup[3] <= 65:
372              ##print 'INFO.ssss.00001: %s, %s' % (v,str(tup) )
373              ##tabsectbyvar[mip]['Omon.%s' % v] = (tup[0], 2, 'bgc.Oyr', tup[-1] )
374              pass
375              ##sn.add( tup[3] )
376
377        lnu = 0
378        for v in sx.cmip5so.so[tab].a.keys():
379          if (v not in s1) and (v not in shb[r]):
380            if tab == 'Omon' and v in sx.cmip5so.sop['Oyr_3dtr']:
381              pass
382            else:
383              lnu += 1 
384        if len(lnf) > 0:
385          print 'ERROR.008.0001: Revised variables not in original: %s %s' % (r,str(lnf) )
386        if len(lmod) == 0 and lnu == 0 and preset < 0:
387          print 'INFO.008.0001: No modfications in %s' % r
388#### save uuid of table ... for use in requestLinks
389          revisedTabKeysNM[r] = cmip5gplk[tab]
390        else:
391          print 'INFO.008.0002: modifications in %s: mods %s, unused %s, preset %s' % (r,len(lmod),lnu,preset)
392          revisedTabKeysff.append( r )
393
394    self.revGpIds = Set()
395    for t in revTabIds:
396      if t[-4:] == 'Omon':
397        self.revGpIds.add( t + '_oth' )
398        self.revGpIds.add( t + '_3d' )
399      elif t[-5:] == 'cfMon':
400        self.revGpIds.add( t + '_3dstd' )
401        self.revGpIds.add( t + '_3dmod' )
402        self.revGpIds.add( t + '_2dmod' )
403        self.revGpIds.add( t + '_sim' )
404
405    shb.close()
406    self.tabsectuuid = tabsectuuid
407    self.tabsectbyvar = tabsectbyvar
408    self.revisedTabKeysff = revisedTabKeysff
409    self.revisedTabKeysNM = revisedTabKeysNM
410    self.revisedTabKeys = revisedTabKeys
411    self.tabuuid = tabuuid
Note: See TracBrowser for help on using the repository browser.