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

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

01.00.06

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