source: CMIP6dreqbuild/trunk/src/framework/ingest/util_anal.py @ 885

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

release candidate

Line 
1
2from xceptions import baseException
3import shelve, glob, os, uuid, collections, string
4from utils_wb import workbook, uniCleanFunc
5import util_varGroups
6import util_gen
7import loadcf
8
9varBlackList = ['tasAdjust','tsAdjust','pslAdjust','prAdjust']
10
11tab2freq = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
12                  u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
13                  u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
14                  u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
15                  u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
16                  u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
17                  u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
18                  u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'mon', \
19                  u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
20                  u'DCPP-day':'day',  \
21                  u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
22                  'OImon':'mon', 'Omon_oth':'mon', 'Omon':'mon',  'Oyr':'yr', 'Omon_3d':'mon', \
23                  u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr', \
24                   'Oclim':'monClim', \
25                   'cfMon':'mon', \
26                  u'cf3hr':'3hr', u'Amon':'mon', u'aero':'mon', u'aero_3d':'mon', u'6hrPlev':'6hr', u'aero_oth':'mon', \
27                  u'cf3hr_grid':'3hr', u'LImon':'mon', u'cfSites':'subhr', u'day_oth':'day', u'cfDay_2d':'day', u'day':'day' }
28
29##
30## want to match up with input/vars_... and  where is cmv uid fixed ????
31##
32##
33## need to migrate new vars into input/vars_ ... especially from LUMIP ...
34##
35## new variables which need to be added have been identified. No check for modifications (and no clear workflow here)...
36## ned to check .. a few appear spurious .. and then generate csv records ... for manual copy ...
37##
38##
39##
40## add AerChemMip and VIACS to stuff scanned and checked below .....
41
42def getSubGroup(s, var,dims,ttl,ix):
43        sg = None
44        if s == 'Oyr' and ix < 60:
45          sg = 'Oyr_3dtr'
46        elif s == 'Amon':
47          if string.find( dims, 'lev' ) == -1 and string.find( dims, 'longitude latitude') != -1:
48            sg = 'Amon_2d'
49          else:
50            sg  = 'Amon_oth'
51        elif s == 'Omon':
52          if string.find( dims, 'longitude latitude olevel' ) != -1:
53            sg = 'Omon_3d'
54          else:
55            sg = 'Omon_oth'
56        elif s == 'cfMon':
57          if ttl[:5] in ['ISCCP','PARAS','CALIP']:
58            sg = 'cfMon_sim'
59          elif var[-3:] == 'co2':
60            if string.find( dims, 'longitude latitude alev' ) != -1:
61              sg = 'cfMon_3dmod'
62            else:
63              sg = 'cfMon_2dmod'
64          else:
65            sg = 'cfMon_3dstd'
66        elif s == 'cfDay':
67          bits = '|'.split( dims )
68
69          if string.find( dims, 'longitude|latitude' ) != -1 and len(bits) > 2 and bits[2] in ['alev','alevel','alevhalf','alt40','plev7','alt40','plev7c']:
70              sg = 'cfDay_3d'
71          else:
72              sg = 'cfDay_2d'
73        elif s == 'cf3hr':
74          if  dims.find( 'longitude|latitude' ) != -1:
75              sg = 'cf3hr_grid'
76          else:
77              sg = 'cf3hr_sim'
78        elif s == 'aero':
79          if dims.find( 'longitude|latitude|alevel' ) != -1:
80              sg = 'aero_3d'
81          else:
82              sg = 'aero_oth'
83        elif s == 'day':
84          if ix < 28:
85              sg = 'day_ss'
86          else:
87              sg = 'day_oth'
88        return sg
89def getSubGroupO(sn, var,dims,ttl,ix):
90                 sg = None
91                 if sn == 'Oyr' and ix < 65:
92                   sg = 'Oyr_3dtr'
93                 elif sn == 'Omon':
94                   if string.find( dims, 'longitude latitude olevel' ) != -1:
95                     sg = 'Omon_3d'
96                   else:
97                     sg = 'Omon_oth'
98                 elif sn == 'cfMon':
99                   if ttl[:5] in ['ISCCP','PARAS','CALIP']:
100                     sg = 'cfMon_sim'
101                   elif var[-3:] == 'co2':
102                     if string.find( dims, 'longitude latitude alev' ) != -1:
103                       sg = 'cfMon_3dmod'
104                     else:
105                       sg = 'cfMon_2dmod'
106                   else:
107                     sg = 'cfMon_3dstd'
108                 elif sn == 'cfDay':
109                   bits = ' '.split( dims )
110                   if string.find( dims, 'longitude latitude' ) != -1 and len(bits) > 2 and bits[2] in ['alev','alevel','alevhalf','alt40','plev7','alt40']:
111                       sg = 'cfDay_3d'
112                   else:
113                       sg = 'cfDay_2d'
114                 elif sn == 'cf3hr':
115                   if dims.find( 'longitude latitude' ) != -1:
116                       sg = 'cf3hr_grid'
117                   else:
118                       sg = 'cf3hr_sim'
119                 return sg
120
121class ref(object):
122  def __init__(self,sdir='inSh'):
123    dir1 = '/data/tmp/svn3/exarch/CMIP6dreqbuild/trunk/src/workbook'
124    wb = workbook( '%s/%s' % (dir1,'inputs/vars_20160721.xls') )
125    self.vars = {}
126    s1 = wb.book.sheet_by_name(u'var')
127    su = set()
128    cf = loadcf.cf()
129    for i in range( s1.nrows ):
130      r = s1.row(i)
131      assert r[0] not in self.vars, 'DUPLICATE VARIABLE: %s' % str(r)
132      self.vars[r[0].value] = (r[9].value,r[10].value,r[7].value)
133    fl = sorted( glob.glob( '%s/sh__newVar_*' % sdir ) )
134    kml = []
135    for f in fl:
136      mip = f.split( '_' )[-1]
137      sh = shelve.open( f, 'r' )
138      ks = [k for k in sh.keys() if k[0] != '_']
139      for k in ks:
140        if k not in self.vars:
141          kml.append((mip,sh[k]))
142          print 'MISSING NEW: %s, %s, %s' % (k,f,str(sh[k]))
143        else:
144          sn0 = sh[k][1]
145          sn = self.vars[k][2]
146          if sn0 != sn:
147            a0 = sn0 in cf.names or sn0 in cf.alias
148            a = sn in cf.names or sn in cf.alias
149            if a and a0:
150              if sn in cf.names and sn0 in cf.names:
151                print 'WARN.standard_name.00001: template standard names different from ref: [%s] %s: %s -- %s' % (mip, k, sn0, sn)
152              elif sn in cf.alias and sn0 in cf.names:
153                print 'WARN.standard_name.00002: replace sn alias with new ....: [%s] %s: %s -- %s' % (mip, k, sn0, sn)
154              elif sn in cf.names and sn0 in cf.alias:
155                print 'WARN.standard_name.00003: attempt to replace sn new with alias ....: [%s] %s: %s -- %s' % (mip, k, sn0, sn)
156              elif sn in cf.alas and sn0 in cf.alias:
157                print 'WARN.standard_name.00004: two aliasses ...... : [%s] %s: %s -- %s' % (mip, k, sn0, sn)
158              else:
159                assert False, 'Should not be able to reach this code'
160            elif not a0:
161              print 'INFO.standard_name.000005: ignoring incorrect standard name in template: [%s] %s: %s -- %s' % (mip, k, sn0, sn)
162            elif not a:
163              print 'WARN.standard_name.00006: standard name needs updating: [%s] %s: %s -- %s' % (mip, k, sn0, sn)
164             
165
166    ixmip = 6
167    ixprov = 5
168    ixuid = 9
169    if len( kml) > 0:
170      oo = open( 'draft_newvars.csv', 'w' )
171      targ2src = ['Short name', 'Long Name', 'description/comments', None, None, None, None, 'CF standard_name', 'units', None, 'Priority']
172      srcHead = ['Short name', 'CF standard_name', 'standard name status', 'Native grid', 'units', 'Long Name', 'description/comments', 'Priority', 'associated observational dataset']
173      ixTarg2src = []
174      for i in range( len( targ2src ) ):
175        if targ2src[i] == None:
176           ixTarg2src.append( None )
177        else:
178           ixTarg2src.append( srcHead.index( targ2src[i] ) )
179##[u'fClAntLut ', '', u'new', u'atmos', u'kg C m-2 s-1', u'carbon from land clearing for land use tile that enters anthropogenic pools', u'If  a model has explicit anthropogenic pools, clearance should not include fire', 1.0, '']
180      for mip,irec in kml:
181        orec = []
182        for i in range( len( targ2src ) ):
183          if ixTarg2src[i] != None:
184            orec.append( uniCleanFunc(irec[ixTarg2src[i]], tostring=True) )
185          else:
186            orec.append( '' )
187        orec[ixmip] = mip
188        orec[ixprov] = 'CMIP6 [%s]' % mip
189        orec[ixuid] = str( uuid.uuid1() )
190        oo.write( '\t'.join( orec ) + '\n' )
191      oo.close()
192
193class cmvRef(object):
194  def __init__(self):
195    self.byUid = {}
196    self.byTab = collections.defaultdict( dict )
197    for l in open( 'ingest/cmvRef_01.beta.32.csv' ).readlines():
198      lab, tab, ttl, uid = l.strip().split( '\t' )
199      assert uid not in self.byUid, 'DUPLICATE UID: %s' % uid
200      self.byUid[uid] = (lab,tab,ttl)
201      if lab in self.byTab[tab]:
202        print 'ERROR.cmvRef.001: duplicate variable name in cmv table: %s,%s' % (tab,lab)
203      self.byTab[tab][lab] = uid
204
205class revTabChk(object):
206
207  def __init__(self,sdir='inSh'):
208    """Review and consolidate revised tables, as ingested into shelves, and annotate records"""
209    assert os.path.isdir( sdir ), 'Input directory not found: %s' % inSH
210    self.ref = refTabChk()
211    fl = sorted( glob.glob( '%s/sh__so_*' % sdir ) )
212    tref = util_varGroups.varGroupSs()
213    vref = util_varGroups.ref()
214    tref.loadGroups()
215    tprobs = set()
216    self.sh = shelve.open( '%s/sh__consol01_revTabs' % sdir, 'n' )
217    self.sh['__cols__'] = ['var', 'table', 'mip', 'vid', 'priority','vgid']
218    self.sh['__info__'] = {'label':'revTable', 'title':'Revised variable table records generated by ingest.util_anal.revTabChk'}
219    cc = collections.defaultdict( int )
220    vgmaps = {'Oyr':'OMIP-Oyr','OImon':'SIMIP-seaicemon'}
221    kkk = 0
222    for f in fl:
223#
224#  CMIP5 and OMIP tables go in as reference tables, and so should not be duplicated here.
225#
226      ss = set()
227      sso = set()
228      if f.find( 'CMIP5' ) == -1 and  f.find( 'OMIP' ) == -1:
229        sh = shelve.open( f, 'r' )
230        for k in sh.keys():
231          if k[0] != '_':
232            assert k not in self.sh, 'Duplicate key in revised table items: %s' % k
233
234            vgl = sh[k][1].replace( '_', '-' )
235            try:
236              vn = sh[k][0]
237            except:
238              print sh['__cols__']
239              print k
240              print sh[k]
241              raise
242            if vn not in vref.vars:
243              print 'WARN.cmv.99999: var name not found: %s:: %s' % (vn,str(sh[k]))
244            ss.add(vgl)
245            if vgl in ['cf3hr-grid', 'cfMon-3dmod', 'cfMon-2dmod']:
246              if vgl not in sso:
247                print 'Warning: skipping ',sh[k]
248                sso.add( vgl )
249              vgid = '__unset__01__'
250            else:
251              vgl1 = vgmaps.get( vgl, vgl )
252              if vgl1 not in tref.uidByLabel:
253                if 'CMIP5-%s' % vgl1 in tref.uidByLabel:
254                   vgl1 = 'CMIP5-%s' % vgl1
255
256              if vgl1 not in tref.uidByLabel:
257                print 'SEVERE.requestvar.00001: group not found: %s: %s, %s' % (vgl,f,str(sh[k]))
258                vgid = '__vgid_not_found__'
259              else:
260                vgid = tref.uidByLabel[vgl1]
261                cc[vgl1] += 1
262            vid = sh[k][3]
263            self.sh[k]  = sh[k][:] + [vgid,]
264            print 'INFO.revisedcmv.00001; ',self.sh[k]
265            if vid in self.ref.cmv:
266              sg = self.ref.cmv[vid][-1]
267              if sg not in [ '',None]:
268                sgs = sg.split('_')[-1]
269                vgl2 = '%s-%s' % (vgl1,sgs)
270                if vgl2 in tref.uidByLabel:
271                  vg2 = tref.uidByLabel[vgl2]
272                  rr = sh[k][:] + [vg2,]
273                  rr[1] = rr[1] + '_' + sgs
274                  k2 = str( uuid.uuid1() )
275                  self.sh[k2] = rr
276                else:
277                  print 'INFO.sg.00050: not found; ',vgl2, sg, sh[k]
278              else:
279                  print 'INFO.sg.00060: no subgroup; ',vgl, sg, sh[k]
280            else:
281                  print 'INFO.sg.00070: no cmv; ',sh[k],f
282            kkk += 1
283        sh.close()
284        print f, ss
285    self.sh.close()
286    for k in sorted( tref.uidByLabel.keys() ):
287      print k, cc[k]
288    for k in cc:
289      if k not in tref.uidByLabel:
290         print 'ERROR: ',k, cc[k]
291    print 'TOTAL VARS REQUESTED HERE: ',kkk
292
293class refTabChk(object):
294
295  def __init__(self,sdir='inSh'):
296    """Review reference tables, as ingested into shelves, and annotate records"""
297    assert os.path.isdir( sdir ), 'Input directory not found: %s' % inSH
298    fl = sorted( glob.glob( '%s/sh__refso_*' % sdir ) )
299    tprobs = set()
300    self.sh = shelve.open( '%s/sh__consol01_refTabs' % sdir, 'n' )
301    self.cmv = dict()
302    self.cmvtv = dict()
303    self.tabInfo = util_gen.tableInfo()
304    self.sh['__cols__'] = self.tabInfo.oh
305    self.sh['__info__'] = {'label':'refTable', 'title':'Reference variable table records generated by ingest.util_anal.refTabChk'}
306    itab = self.tabInfo.oh.index( 'mipTable' )
307    icmv = self.tabInfo.oh.index( 'var' )
308    iix = self.tabInfo.oh.index( 'rowIndex' )
309    iv = self.tabInfo.oh.index( 'out_name' )
310    ivid = self.tabInfo.oh.index( 'vid' )
311    idim = self.tabInfo.oh.index( 'dimensions' )
312    iln = self.tabInfo.oh.index( 'title' )
313    iss = self.tabInfo.oh.index( 'ssect' )
314    isn = self.tabInfo.oh.index( 'sn' )
315    igpid = self.tabInfo.oh.index( 'gpid' )
316    vref = util_varGroups.ref()
317    tref = util_varGroups.varGroupSs()
318    tref.loadGroups()
319    vmsgs = set()
320    dnrix = []
321    for x in ['var','title','comment',None,None,None,None,'sn','units',None,'priority']:
322      if x == None:
323        dnrix.append( None )
324      else:
325        dnrix.append( self.tabInfo.oh.index(x) )
326     
327    cf = loadcf.cf()
328    gtm = set()
329    sss = set()
330    oonv = None
331    vml = []
332    for f in fl:
333      self.actions = collections.defaultdict(int)
334      self.file = f
335      mip = f.split( '_' )[-1]
336      sh = shelve.open( f, 'r' )
337      ks = [k for k in sh if k[0] != '_']
338      for k in ks:
339       rr = sh[k][:]
340       uid = rr[0]
341       var = rr[iv]
342       if var.find( '_' ) != -1:
343         print 'ERROR.var.00001: underscore in variable: %s' % str(rr)
344         var = var.replace( '_', '' )
345         rr[iv] = var
346       if var not in varBlackList:
347        try:
348         tab = rr[itab]
349         tab = tref.mapGroupName(tab,'')
350         if var not in vref.vars:
351           if var not in vmsgs:
352              print 'SEVERE.vars.00010: var not found: %s [%s]' % (var,tab)
353              vmsgs.add( var )
354              if oonv == None:
355                oonv = open( 'draft_newvars02.csv', 'w' )
356              ov = []
357              for ix in dnrix:
358                if ix == None:
359                  ov.append( '' )
360                else:
361                  ov.append( str( rr[ix] ) )
362              ov[9] = uid
363              ov[6] = mip
364              ov[5] = 'CMIP6 Endorsement [%s]' % mip
365              oonv.write( '\t'.join( ov ) + '\n' )
366           vid = '-'
367         else:
368           sn0 = rr[isn]
369           sn = vref.vars[var][2]
370           if sn != sn0:
371            a0 = sn0 in cf.names or sn0 in cf.alias
372            a = sn in cf.names or sn in cf.alias
373            if a and a0:
374              if sn in cf.names and sn0 in cf.names:
375                print 'WARN.standard_name.10001: template standard names different from ref: [%s] %s: %s -- %s' % (mip, var, sn0, sn)
376                vml.append( (mip,var,'1',sn,sn0) )
377              elif sn in cf.alias and sn0 in cf.names:
378                print 'WARN.standard_name.10002: replace sn alias with new ....: [%s] %s: %s -- %s' % (mip, var, sn0, sn)
379                vml.append( (mip,var,'2',sn,sn0) )
380              elif sn in cf.names and sn0 in cf.alias:
381                print 'WARN.standard_name.10003: attempt to replace sn new with alias ....: [%s] %s: %s -- %s' % (mip, var, sn0, sn)
382              elif sn in cf.alas and sn0 in cf.alias:
383                print 'WARN.standard_name.10004: two aliasses ...... : [%s] %s: %s -- %s' % (mip, var, sn0, sn)
384              else:
385                assert False, 'Should not be able to reach this code'
386            elif not a0:
387              print 'INFO.standard_name.100005: ignoring incorrect standard name in template: [%s] %s: %s -- %s' % (mip, var, sn0, sn)
388            elif not a:
389              print 'WARN.standard_name.10006: standard name needs updating: [%s] %s: %s -- %s' % (mip, var, sn0, sn)
390              vml.append( (mip,var,'6',sn,sn0) )
391           
392           vid = vref.vars[var][0]
393
394         if tab not in tref.groupset:
395           print 'SEVERE.tables.00001: tab not found: %s' % tab
396           gpid = '-'
397         else:
398           gpid = tref.groupset[tab][0]
399           gtm.add( (tab,tref.groupset[tab]) )
400        except:
401         print k, sh[k]
402         print itab,iv
403         raise
404        if tab not in tab2freq:
405         tprobs.add(tab)
406        rr[igpid] = gpid
407        rr[ivid] = vid
408        rr[-1] = int( float(rr[-1]) )
409        sg = ''
410       ## check to see if this table has sections, and identify which section this variable is in if appropriate
411        print 'INFO.sg.01001: ',tab,tab in self.tabInfo.tabChildren
412        if rr[iss] != '':
413          sg = rr[iss]
414          sg1 = sg.replace( '_', '-' )
415          if sg1 in ['cf3hr-grid','Amon-oth']:
416             sgid = '_na_'
417          else:
418            assert sg1 in tref.groupset, 'Subgroup not found in groupset: %s,%s' % (tab,sg1)
419            sgid = tref.groupset[sg1][0]
420          rr[iss] = (sg,sgid)
421          print 'INFO.sg.00003: ',sg,sgid
422        elif tab in self.tabInfo.tabChildren:
423         if tab in ['Omon','Oyr']:
424           sg = getSubGroupO(tab, var,rr[idim],rr[iln],rr[iix])
425         else:
426           sg = getSubGroup(tab, var,rr[idim],rr[iln],rr[iix])
427         print 'INFO.sg.00001: ',tab,var,rr[idim],rr[iix], sg
428         if sg != None:
429           sg1 = sg.replace( '_', '-' )
430           if sg1 in ['Amon-oth']:
431             sgid = '_na_'
432           else:
433             assert sg1 in tref.groupset, 'Subgroup not found in groupset: %s, %s' % (tab,sg)
434             sgid = tref.groupset[sg1][0]
435           rr[iss] = (sg,sgid)
436           if (sg,sgid) not in sss:
437             sss.add( (sg,sgid) )
438             print 'INFO.sg.00002: ',sg,sgid
439         else:
440           assert rr[iss] == '', 'Corrupted subgroup element: %s,%s,%s' % (iss,rr[iss],str(rr))
441         
442        self.cmv[uid] = (tab, var, rr[idim], rr[iix], rr[iln],sg)
443        self.cmvtv[(tab,var)] = uid
444        if var == 'intppcalc':
445          print rr
446        if var in {'*','include Oyr 3D tracers'}:
447          print 'ERROR.copy.00890: ',f,rr
448        if k != uid:
449          print 'SEVERE.uid.00020: uid/k mismatch: ',k,rr
450
451        if var == 'msftmyz':
452           print 'INFO.msftmyz.00001: ',vid, rr
453        self.sh[k] = rr[:]
454    if oonv != None:
455      oonv.close()
456    print gtm
457    self.sh['__source__'] = fl
458    self.sh.close()
459    print 'UNMAPPED tabs (to freq): ',tprobs
460
461    if len( vml ) > 0:
462      oo = open( 'varStandardNameUpdates.csv', 'w' )
463      for vm in vml:
464        oo.write( '\t'.join( vm ) + '\n' )
465      oo.close()
466
467class dynGrps(object):
468  def __init__(self,rftc):
469    sdir = 'inSh'
470    sh = shelve.open( '%s/sh__requestScoping' % sdir )
471    sh0 = shelve.open( '%s/sh__requestScoping_0' % sdir, 'r' )
472    for k in sh0:
473      mip, rec = sh0[k]
474      print mip,rec
475
476class varGroupChk(object):
477  cmip5Tables = [u'3hr', u'6hrLev', u'6hrPlev', u'Amon', u'LImon', u'Lmon', u'OImon', u'Oclim', u'Omon', u'Oyr', u'aero', u'cf3hr', u'cfDay', u'cfMon', u'cfOff', u'cfSites', u'day', u'fx']
478  def __init__(self,sdir='inSh'):
479    """Review var groups, as ingested into shelves, and annotate records"""
480    assert os.path.isdir( sdir ), 'Input directory not found: %s' % inSH
481    self.ref = ref()
482    self.shl = {}
483    self.group2uid = {}
484    self.vgss = util_varGroups.varGroupSs()
485    self.vgss.loadGroups()
486    self.vgss.setUid()
487    self.vgss.checkMaps()
488    self.varsetoo = None
489    self.grps = set()
490    self.tbls = set()
491    self.frqs = set()
492    self.nnew = 0
493    self.nc5 = 0
494    self.noth = 0
495    self.ots = set()
496    isFirst = True
497    #self.sh = shelve.open( '%s/sh__consol01_grp' % sdir, 'n' )
498    self.sh = shelve.open( '%s/sh__consol01_groupItems' % sdir, 'n' )
499    self.shdvg = shelve.open( '%s/sh__consol01_dynVarGroup_requestVars' % sdir, 'n' )
500
501    self.shdvg['__info__'] = {'label':'dynVarGroup_requestVars', 'title':'Request variable records for dynamically generated variable groups (through variable names listed in request scoping). Generated by ingest.util_anal.varGroupChk'}
502    self.shdvg['__cols__'] = ['vid', 'title', 'label', 'priority', 'vgid', 'mip']
503
504    self.sh['__info__'] = {'label':'GroupItemsBeta', 'title':'Group Item records generated by ingest.util_anal.varGroupChk'}
505    self.sh['__cols__'] = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'oldv', 'rowIndex', 'var2', 'new', 'gpid', 'vkey', 'vid']
506    self.mg = dict()
507    self.checkRequestedGroups()
508
509    fl = sorted( glob.glob( '%s/sh__grp_*' % sdir ) )
510    for f in fl:
511      self.scanFile(f,isFirst)
512      isFirst = False
513
514    self.sh.close()
515    self.shdvg.close()
516    if self.varsetoo != None:
517      self.varsetoo.close()
518
519    sh = shelve.open( '%s/sh__requestScoping_1' % sdir,'n' )
520    for k in self.group2uid:
521       mip, uid, new = self.group2uid[k]
522       sh['%s__1' % str(k)] = (mip, uid )
523    sh.close()
524
525    for kkk in sorted(self.mg.keys()):
526      print 'WARNING: possible problem identifying group: ',self.mg[kkk]
527    print 'groups: ',self.grps
528    print 'tables: ',self.tbls
529    print 'frequencies: ',self.frqs
530    print 'nrefs to new: %s, cmip5: %s, other: %s' % (self.nnew, self.nc5, self.noth)
531    print 'other tables: ',self.ots
532    for k in self.shl:
533      self.shl[k].close()
534
535  def scanFile(self,f,isFirst):
536      self.actions = collections.defaultdict(int)
537      self.file = f
538      self.shl[f] = shelve.open( f, 'r' )
539      self.mip = self.shl[f]['__info__']['label']
540      if isFirst:
541        print self.shl[f]['__cols__']
542      ks = [k for k in self.shl[f].keys() if k[0] != '_']
543
544      for k in ks:
545        r = self.shl[f][k]
546        self.grps.add(r[0])
547        self.tbls.add(r[2])
548        self.frqs.add(r[3])
549        var = r[1].strip()
550        if var != r[1]:
551          print 'WARNING.blanks.0001: *%s* and *%s (%s,%s)' % (var,r[1],r[0],f)
552        extra = {}
553        if r[2] == 'new' or r[2][:2] == 'em':
554          extra['mode'] = 'new'
555          self.nnew +=1
556          if var not in self.ref.vars:
557            if var.find('_') != -1:
558              v2 = var.replace('_','')
559              if v2 in self.ref.vars:
560                print 'WARN: %s should be replaced with %s' % (var,v2)
561            print 'ERROR.missing.0001: variable not found: ',var,r[0],f
562          else:
563            if r[9] == '':
564              p1 = -1
565            else:
566              p1 = int( r[9] )
567            p2 = int( self.ref.vars[var][1] )
568            if p1 not in [1,2,3]:
569              if p2 in [1,2,3]:
570                extra['priority'] = p2
571              else:
572                print 'ERROR.priority.0001: %s (%s::%s), ref: %s, templ: %s' % (var,r[0],f,p2,p1)
573
574        elif r[2] in self.cmip5Tables or r[2][:5] == 'CMIP5' and r[2][6:] in self.cmip5Tables:
575          extra['mode'] = 'CMIP5'
576          self.nc5 += 1
577          if var not in self.ref.vars:
578            print 'ERROR.missing.0003: variable not found: ',var,r[0],f
579        else:
580          extra['mode'] = 'OTHER MIP'
581          self.noth += 1
582          self.ots.add( r[2] )
583          if var not in self.ref.vars:
584            print 'ERROR.missing.0002: variable not found: ',var,r[0],f
585##
586## but this is the MIP variable id ...... need the CMOR variable ID ?? ...
587##
588        vid = self.ref.vars.get(var,[None,])[0]
589        self.consol(k,r,vid,extra)
590      for k in sorted( self.actions.keys() ):
591           print 'ACTIONS: %s: %s -- %s' % (f,k,self.actions[k])
592
593
594  def varsets(self, thisuid, i1, refuid, i2, title ):
595    if self.varsetoo == None:
596      self.varsetoo = open('varsets.txt','w' )
597    self.varsetoo.write( '\t'.join(  [thisuid, str(i1), refuid, str(i2), title] ) + '\n' )
598 
599  def consol(self,rk,rr,vid,extra):
600##['Short name of group', 'Variable short name', 'Table', 'Frequency', 'Description extension (optional)', 'Shape', 'Levels', 'Time mean, point or climatology', 'Mask (optional)', 'Priority', 'MIP','uid','rowIndex', 'Prev. Var Name']
601##
602## following is provided by sx2.py:
603##['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'rowIndex', 'new', 'gpid', 'vkey', 'vid']
604## need to add vid (info found above), vgid, "new" flag, (also above), and "vkey".
605
606    rset = []
607    r = list(rr)
608    if 'priority' in extra:
609       r[9] = extra['priority']
610    elif r[9] == '':
611       r[9] = -1
612    else:
613       r[9] = int( r[9] )
614
615    if not self.vgss.matchGroup(r[0],self.mip):
616        print 'ERROR.group.00006: group not found: %s [%s]' % (r[0],self.mip)
617        self.mg[r[0]] = (self.mip,r)
618        gpid = '__noGroupFound__'
619        new = 0
620    else:
621        print 'INFO.group.00007: group found: %s (%s):: %s, %s' % (r[0],self.mip,self.vgss.groupName, self.vgss.groupMatch )
622        if r[0] in self.group2uid:
623          assert self.vgss.groupMatchRes == self.group2uid[r[0]], 'Mismatch in group lookup ..%s [%s,%s]' % (r[0], str(self.vgss.groupMatchRes), str(self.group2uid[r[0]]) )
624        else:
625          self.group2uid[r[0]] = self.vgss.groupMatchRes
626        gpid = str(self.vgss.groupMatchRes[1] )
627        isnew = self.vgss.groupMatchRes[2] == 'new'
628        if isnew:
629          new = 1
630        else:
631          new = -1
632
633    il = 6
634    idx = 4
635    ixp = 9
636    iu = 11
637    assert r[iu] == rk, 'CONFUSED ABOUT UIDs? %s, %s' % (rk,r[iu])
638    var2 = r[1]
639    if r[il] in  {u'17 (or 23 )', u'17 (or 23)', u'17 (or23)', u'10/17/23'}:
640       self.actions['Create 17/23 level pair'] += 1
641       if r[il] == u'10/17/23':
642                lev0 = 10
643                levsp = [19,23]
644       else:
645                lev0 = 19
646                levsp = [23,]
647       r[ixp] = 1
648       r[il] = lev0
649       var2 = var2 + str( lev0 )
650       p = 1
651       for lp in levsp:
652                 p += 1
653                 rr0 = r + [r[1] + str(lp),]
654                 rr0[ixp] = p
655                 rr0[il] = lp
656                 rr0[iu] = str( uuid.uuid1() )
657                 rr = rr0 + [new, gpid, 0, vid]
658                 if r[1] == 'hus':
659                    print 'INFO.hus.00202: ',rr
660                 rset.append( rr )
661                 self.varsets(rr0[iu], 2, rr[iu], 1, 'variables at multiple vertical resolutions' )
662
663    elif r[il] in [u'Model levels or plev_27', u'Model levels or 27Plevs',u'27',27.]:
664               self.actions['27 level variant of variable name created' ] += 1
665               var2 += '27'
666               r[il] = 27
667    elif r[idx].find( '850 hPa' ) != -1:
668               if r[1][-3:] != '850':
669                  self.actions['850mb variant of variable generated'] += 1
670                  var2 += '850'
671    elif type( r[il] ) == type(1.) and r[il] == 7. and r[10] == 'HighResMIP' and r[5] != 'XYZKT':
672                  self.actions['Shape modified to XYZKT*'] += 1
673                  r[5] = r[5] + '*'
674                  r[il] = '7h'
675    r += [var2,new, gpid, 0, vid]
676    rset.append( r )
677    if r[10] != 'OMIP':
678      for ri in rset:
679        self.consol_sub01( ri, extra )
680    else:
681      self.actions['OMIP records skipped'] += 1
682
683  def consol_sub01( self, r, extra ):
684    """Write our a requestItem record, which is split into a CMORvar and requestVar in isd3b.py"""
685    iu = 11
686    assert r[iu] not  in self.sh
687    assert len(r) == len( self.sh['__cols__'] ), 'Bad record length .. %s'  % str(r)
688    print 'INFO.requestitem.00001: ',r
689    self.sh[r[iu]] = r[:]
690
691  def checkRequestedGroups(self,sdir='inSh'):
692    sh = shelve.open( '%s/sh__requestScoping' % sdir, 'r' )
693    sh0 = shelve.open( '%s/sh__requestScoping_0' % sdir, 'n' )
694    cc = collections.defaultdict( int )
695    ff = set()
696    for mip in sorted( sh['__records__'].keys() ):
697      reqg = sh['__records__'][mip]
698      reqgd = dict()
699      self.mip = mip
700      for rec in reqg:
701        g = rec[0]
702        if g[:5] == 'CMIP5':
703         g = g[6:]
704        g0 = g
705        t = self.vgss.recChk(rec,mip)
706        dyngrp = t[0]
707        if dyngrp:
708          mtab, g = t[2]
709        if not self.vgss.matchGroup(g,self.mip) and not dyngrp:
710          print 'FAILED to match request group: ',self.mip,rec
711          ff.add( (self.mip,g) )
712        else:
713          print 'INFO.group.00008: group found: %s (%s):: %s, %s' % (g,self.mip,self.vgss.groupName, self.vgss.groupMatch )
714          assert self.vgss.groupMatchRes != None,  'Should have results from matchGroup here!!'
715          reqgd[g] = self.vgss.groupMatchRes
716          uid = str(self.vgss.groupMatchRes[1] )
717          rec[0] = self.vgss.groupName
718          kkk = '%s__%2.2i__%s' % (uid,cc[uid],0)
719          cc[uid] += 1
720          assert kkk not in sh0, 'Duplicate key for request link record: %s' % kkk
721          sh0[kkk] = [self.mip, rec ]
722          print 'INFO.vgrp.00001: ',kkk,self.mip,rec
723          if dyngrp:
724            self.saveDynGrp(g,mtab,uid)
725##
726## need to generate request variables for dynamic groups here (those detected via vgss )
727## would be nice to stage things ... create variable database and then add requests ....
728## "all at once" risks mis-alignments ...
729##
730## need to fill in details on dynamic groups after completion of scan of new groups.   
731##
732##
733    sh.close()
734    sh0.close()
735    if len(ff) > 0:
736      oo = open( 'varGroupSuggestions.csv', 'w' )
737      for t in sorted( list( ff ) ):
738        oo.write( '%s\t%s' % t )
739        oo.write( '\t%s\n' % str( uuid.uuid1() ) )
740      oo.close()
741
742  def saveDynGrp(self,glab,tab,rgid):
743    this = self.vgss.s2[glab]
744    print 'INFO.dyngrp.00001: ',rgid,this, glab
745    for k in this:
746      if k[0] != '_':
747        if this[k] == None:
748          print 'ERROR.dyngrp.00002: variable not found: ',rgid,k, glab
749        else:
750          vid, priority = this[k]
751          rec = [vid, '%s: %s' % (glab,k), k, priority, rgid, self.mip] 
752          uid = str(uuid.uuid1() )
753          self.shdvg[uid] = rec
754
Note: See TracBrowser for help on using the repository browser.