source: CMIP6dreqbuild/trunk/src/workbook/importShDreq2.py @ 555

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/workbook/importShDreq2.py@555
Revision 555, 100.4 KB checked in by mjuckes, 5 years ago (diff)

cleaning CMOR tables

Line 
1"""Import data request from shelves and pu onto compliant XML document.
2------------------------------------------------------------------------
3A new uuid is generated for elements of the "revisedtabitem" section/table (because it is not present in the shelve).
4
5NOTES
6-----
7July 27th: there is an unresolved problem about preserving uuids when updates are provided in source format .....
8"""
9
10### Experiment group dictionary added, and experiment set of named tuples -- making it possible to identify experiments in each mip and group.
11### Should be able to use this in review to make reference groups ...
12
13###
14### Appear to be getting core variables into a clean format
15### Some filtering to avoit duplicates arising from two approaches to OMIP, flagged as ERROR.090 in standard output.
16### Corrected by omitting 2nd reference
17###
18
19import xlrd, xml, os, sys, string, shelve
20import utils_wb, uuid
21import xml.dom, xml.dom.minidom
22import collections, string, re
23import choiceCfg
24import importWbMods
25from utils_wb import uniCleanFunc
26import ivg
27reload(ivg)
28
29WbMods = importWbMods.run()
30
31nt__trace = collections.namedtuple( 'trace', ['GROUPITEM_ta','SPATIALSHAPE_01'] )
32trace = nt__trace( False, False )
33
34tableNameMap = {'CMIP5_3hr':'3hr', 'CMIP5_6hrLev':'6hrLev', 'CMIP5_6hrPlev':'6hrPlev', 'CMIP5_Amon':'Amon', 'CMIP5_LImon':'LImon', 'CMIP5_Lmon':'Lmon', 'CMIP5_OImon':'CMIP5_OImon', 'CMIP5_Oclim':'Oclim', 'CMIP5_Omon':'CMIP5_Omon', 'CMIP5_aero':'aero', 'CMIP5_cf3hr':'cf3hr', 'CMIP5_cfDay':'cfDay', 'CMIP5_cfMon':'cfMon', 'CMIP5_cfOff':'cfOff', 'CMIP5_cfSites':'cfsites', 'CMIP5_day':'day', 'CMIP5_fx':'fx', 'OMIP.Omon':'Omon', 'OMIP.Oyr':'Oyr', 'OMIP.day':'Oday', 'OMIP.fx':'Ofx' }
35
36reportedRedundantTables = set()
37redundantTables = ['CMIP5_Oyr','CMIP5_Omon','CMIP5_OImon','CORDEX_3h', 'CORDEX_6h', 'CORDEX_fx', 'CORDEX_mon', 'CORDEX_sem', 'PMIP3_Aclim', 'PMIP3_Amon', 'PMIP3_LIclim', 'PMIP3_LImon', 'PMIP3_Lclim', 'PMIP3_Lmon', 'PMIP3_OIclim', 'PMIP3_OImon', 'PMIP3_Oclim', 'PMIP3_Omon', 'PMIP3_day', 'PMIP3_fx', 'SPECS_6hr', 'SPECS_Lmon', 'SPECS_fx']
38
39## mapping of variable groups representing tables ....
40mappedTables =  {'Omon':'OMIP-Omon', 'OMIP-Oyr':'Oyr', 'OImon':'SIMIP-seaicemon' }
41mappedTables =  {'Omon':'OMIP-Omon', 'CMIP5-Oyr':'OMIP-Oyr', 'OImon':'SIMIP-seaicemon', 'CMIP5-Omon':'OMIP-Omon' }
42
43freqmap = {'daily':'day', 'Annual':'yr', 'Timestep':'subhr',  '1day':'day', '1mon':'mon', 'month':'mon', 'year':'yr', 'monthly':'mon', 'Day':'day', '6h':'6hr', '3 hourly':'3hr', '3 Hourly':'3hr'  }
44
45nt_expt = collections.namedtuple( 'expt', ['uid', 'label', 'mip', 'egid' ] )
46realmdef = { '__all__':['CFMIP [cfMonExtra]', 'PMIP [PMIP-Omon]', 'LS3MIP [LCmon]', 'C4MIP [C_Ocean_T2]', 'C4MIP [C_Ocean_T1]', 'LUMIP [Lyr_Lut]', 'PMIP [PMIP-LIclim]', 'HighResMIP [1hr_strat]', 'SIMIP [seaiceday]', 'C4MIP [C_LandT1]', 'CFMIP [cfDay_2d_new]', 'HighResMIP [6hrPlev_intense]', 'HighResMIP [Amon_diag]', 'DCPP [DCPP-mon]', 'HighResMIP [Amon_conv]', 'SIMIP [seaicemon]', 'DAMIP [new_monthly]', 'FAFMIP [fafOyrB]', 'HighResMIP [Amon_ext]', 'DynVar [DYVR_daily]', 'PMIP [PMIP-Aclim]', 'HighResMIP [3hr_extr]', 'C4MIP [C_Basic]', 'DCPP [DCPP-day]', 'CFMIP [cfMon_3dstd_new]', 'FAFMIP [fafOmon]', 'ISMIP6 [new_fx]', 'LS3MIP [LEday]', 'PMIP [PMIP-aeroclim]', 'PMIP [PMIP-aero]', 'DCPP [DCPP-6hr]', 'DynVar [DYVR_monthly]', 'ISMIP6 [icesheetmon]', 'CFMIP [aeroDay_2d]', 'ISMIP6 [new_LImon]', 'ISMIP6 [new_Omon]', 'CFMIP [cfDayExtra]', 'LS3MIP [LWday]', 'PMIP [PMIP-Oclim]', 'ISMIP6 [icesheetyear]', 'LUMIP [Lmon_Lut]', 'HighResMIP [1ts]', 'PMIP [PMIP-OIclim]', 'HighResMIP [6hrPlev_extr_dr]', 'VolMIP [VIRF]', 'C4MIP [C_LandT2]', 'C4MIP [C_Hist]', 'FAFMIP [fafOmonB]', 'RFMIP [aero_irf]', 'PMIP [PMIP-Lmon]', 'C4MIP [L_day]', 'PMIP [PMIP-Lclim]', 'PMIP [PMIP-Amon]', 'GeoMIP [aeroGeo]', 'HighResMIP [6hrPlev_extr]', 'PMIP [PMIP-day]', 'HighResMIP [Amon_sparc]', 'CFMIP [cfSites_new]', 'CFMIP [cf3hr_sim]'], 
47        'atmos':['CFMIP [cfMonExtra]', 'HighResMIP [1hr_strat]', 'CFMIP [cfDay_2d_new]', 'HighResMIP [6hrPlev_intense]', 'HighResMIP [Amon_diag]', 'DCPP [DCPP-mon]', 'HighResMIP [Amon_conv]', 'DAMIP [new_monthly]', 'HighResMIP [Amon_ext]', 'DynVar [DYVR_daily]', 'PMIP [PMIP-Aclim]', 'HighResMIP [3hr_extr]', 'DCPP [DCPP-day]', 'CFMIP [cfMon_3dstd_new]', 'PMIP [PMIP-aeroclim]', 'PMIP [PMIP-aero]', 'DCPP [DCPP-6hr]', 'DynVar [DYVR_monthly]', 'CFMIP [aeroDay_2d]', 'CFMIP [cfDayExtra]', 'HighResMIP [1ts]', 'HighResMIP [6hrPlev_extr_dr]', 'VolMIP [VIRF]', 'RFMIP [aero_irf]', 'PMIP [PMIP-Amon]', 'GeoMIP [aeroGeo]', 'HighResMIP [6hrPlev_extr]', 'PMIP [PMIP-day]', 'HighResMIP [Amon_sparc]', 'CFMIP [cfSites_new]', 'CFMIP [cf3hr_sim]'],
48        'ocean':['PMIP [PMIP-Omon]', 'C4MIP [C_Ocean_T1]', 'C4MIP [C_Ocean_T2]', 'FAFMIP [fafOyrB]', 'FAFMIP [fafOmon]', 'ISMIP6 [new_Omon]', 'PMIP [PMIP-OIclim]', 'FAFMIP [fafOmonB]', 'PMIP [PMIP-Oclim]'],
49        'land':['LS3MIP [LCmon]', 'C4MIP [C_Hist]', 'C4MIP [L_day]', 'PMIP [PMIP-Lclim]', 'C4MIP [C_Basic]', 'LUMIP [Lmon_Lut]', 'LUMIP [Lyr_Lut]', 'C4MIP [C_LandT1]', 'PMIP [PMIP-Lmon]', 'C4MIP [C_LandT2]'],
50        'seaIce':['SIMIP [seaicemon]', 'SIMIP [seaiceday]' ],
51        'landIce':['ISMIP6 [new_LImon]', 'PMIP [PMIP-LIclim]', 'ISMIP6 [icesheetyear]', 'ISMIP6 [new_fx]', 'ISMIP6 [icesheetmon]'],
52        '__unset__':['LS3MIP [LWday]', 'LS3MIP [LEday]'] }
53
54realmdefix = {}
55for k in realmdef.keys():
56  if k != '__all__':
57    for s in realmdef[k]:
58      assert not realmdefix.has_key(s), 'Duplicate targ value in realmdef: %s [%s]' % (s,k)
59      realmdefix[s] = k
60
61for k in realmdef['__all__']:
62  assert realmdefix.has_key(k), 'Key %s not found in realmdefix' % k
63
64class cls_s1(object):
65  def __init__(self):
66    self.a = collections.defaultdict( list )
67
68def mycc(s):
69      s = string.replace( s, '&', '' )
70      if len(s) > 0 and s[-1] == '+':
71        s = s[:-1] + 'ETC'
72## camelcase the input string
73      s1 = string.lower( string.replace(string.strip(str( s) ), '-', ' ') )
74      return string.replace( string.capwords( s1 ), ' ', '' )
75
76empty=re.compile('^$')
77
78def test( x,m):
79  if not x:
80    print m
81  return x
82
83class lcm(object):
84  def __init__(self,a,b):
85    self.a = {}
86    self.b = {}
87    for i in a:
88      self.a[string.lower(i)] = i
89    for i in b:
90      self.b[string.lower(i)] = i
91
92class main(object):
93
94  def __init__(self,src,rq,doRepl=False,run=False,schemaMode='dreq'):
95    self.schemaMode = schemaMode
96    self.requestlinkuid = set()
97    self.src=src
98    self.vgcheck = {}
99    self.rqlPreset = {}
100    fok = [test(os.path.isfile(src),'%s not found' % src), ]
101    assert all( fok), 'Required input file(s) missing'
102    self.fx = WbMods.fx
103    self.spsh = WbMods.ls
104    self.cmDims = WbMods.cm
105    self.importWbMods = WbMods
106
107    for sh in [rq.expt,rq.exgp,rq.objec,rq.refti, rq.revti, rq.vars, rq.grps, rq.rqvg, rq.rqli, rq.rqit, rq.rqsect]:
108       print sh['__info__']
109
110    self.repl = collections.defaultdict( list )
111    self.err0010 = collections.defaultdict( int )
112    self.replItems = {}
113    self.defaultP = {}
114    self.remo = {}
115    self.upda = {}
116    self.insert = {}
117    self.exptSet = set()
118    self.exptGrpDict = {}
119
120    self.objectives = collections.defaultdict( dict )
121    self.objectiveLinks = collections.defaultdict( cls_s1 )
122    self.experiments = {}
123    self.experimentGrp = {}
124    self.exptPntUid = {}
125    self.exptPnt = collections.defaultdict( list )
126    self.mips = set()
127    self.dsortdd = {}
128
129    if doRepl:
130      self.importRepl()
131      self.importRemove()
132      self.importUpdate()
133      self.importInsert()
134    self.e15_10 = 0
135    self.doc = xml.dom.minidom.parse( self.src  )
136    self.vocabs = xml.dom.minidom.parse( 'vocabs.xml' )
137    self.skey = {'experiment':rq.expt, 'exptgroup':rq.exgp, \
138         'objective':rq.objec, 'var':rq.vars,'ovar':rq.refti, 'groupitem':rq.grps, \
139         'revisedtabitem':rq.revti, 'requestlink':rq.rqli, 'requestitem':rq.rqit, \
140         'requestvargroup':rq.rqvg, 'tablesection':rq.rqsect, 'requestvar':rq.revti}
141
142    self.newImport = False
143    self.prepVar()
144    self.writeTimeSlice()
145    self.writeMip()
146    self.writeSn()
147    self.writeMcfg()
148    self.writeCmDim()
149    self.writeVar()
150    self.prep01()
151    self.prepRequestVarGroup()
152    self.prep(rq)
153    self.addAerChem()
154    self.prepRequestItem()
155    self.reviewExpt()
156    if run:
157      self.run(rq)
158      self.prepRequestLink()
159      self.finishRequestLink()
160      if self.schemaMode == 'dreq2':
161        self.write2()
162      self.finish()
163
164  def writeMcfg(self):
165    self.cfgUids = set()
166    xx = self.vocabs.getElementsByTagName( 'modelConfig' )
167    assert len(xx) == 1, 'Expecting one element named "modelConfig", found %s' % len(xx)
168    iDoc = xx[0]
169## <item id="tmpid.0003" label="C4MIP" status="" title="Coupled Climate Carbon Cycle Model Intercomparison Project" url="http://c4mip.lsce.ipsl.fr/"/>
170    thiss = self.doc.getElementsByTagName( 'modelConfig' )[0]
171    dil = thiss.getElementsByTagName('item')
172    for d in dil:
173      thiss.removeChild(d)
174    for i in iDoc.getElementsByTagName('item'):
175      item = self.doc.createElement( 'item' )
176      thisl = i.getAttribute( 'label' )
177      for k in ['title','MIPs','usage','range','type']:
178        item.setAttribute( k, i.getAttribute( k ) )
179      uid = str( thisl )
180      item.setAttribute( 'uid', uid )
181      item.setAttribute( 'label', uid )
182      self.cfgUids.add( uid )
183      thiss.appendChild( item )
184
185  def writeCmDim(self):
186    thiss = self.doc.getElementsByTagName( 'grids' )[0]
187    dil = thiss.getElementsByTagName('item')
188    for d in dil:
189      thiss.removeChild(d)
190    kk =  ['tables','label','altLabel','description','standardName','title','axis','units','isIndex','coords','bounds','direction','valid_min','valid_max','type','positive','value','boundsValues','requested','boundsRequested','tolRequested','isGrid' ]
191    for j in self.cmDims.ss.keys():
192      item = self.doc.createElement( 'item' )
193      for i in range(len(kk)):
194        if kk[i] in ['valid_min','valid_max']:
195          if str( self.cmDims.ss[j][i] ) != '':
196            item.setAttribute( kk[i], str( self.cmDims.ss[j][i] ) )
197        else:
198          item.setAttribute( kk[i], str( self.cmDims.ss[j][i] ) )
199      uid = 'dim:%s' % str( self.cmDims.ss[j][1] )
200      item.setAttribute( 'uid', uid )
201      thiss.appendChild( item )
202
203  def writeVar(self):
204    thiss = self.doc.getElementsByTagName( 'var' )[0]
205    dil = thiss.getElementsByTagName('item')
206    for d in dil:
207      thiss.removeChild(d)
208#<item description="dummyAt" id="001.001.001" label="example-01" procComment="dummyAt" procnote="dummyAt" prov="dummyAt" provmip="dummyAt" sn="dummyAt" title="dummy title string" uid="fa349c44-9ccb-11e5-8176-5404a60d96b5" units="dummyAt"/>
209    kk= ['label', 'title', 'description', 'procComment', 'procnote', 'prov', 'provmip', 'sn', 'units', 'uid','defaultp']
210    for uid in self.importWbMods.vars.d1:
211      item = self.doc.createElement( 'item' )
212      thisr = self.importWbMods.vars.d1[uid]
213      for i in range( len(kk) -1 ):
214           item.setAttribute( kk[i], thisr[i] )
215      if len( self.importWbMods.vars.c1[ thisr[0] ] ) == 1:
216         id = thisr[0]
217      else:
218         id = '%s.%s' % (thisr[0],self.importWbMods.vars.c1[ thisr[0] ].index( uid ) )
219         print 'INFO.090.00050: setting id for non-unique variable name: %s' % id
220      item.setAttribute( 'id', id )
221      thiss.appendChild( item )
222
223  def writeSn(self):
224    import loadcf
225    cf = loadcf.cf()
226    thiss = self.doc.getElementsByTagName( 'standardname' )[0]
227    dil = thiss.getElementsByTagName('item')
228    for d in dil:
229      thiss.removeChild(d)
230
231    for i in sorted( cf.names.keys() ):
232      item = self.doc.createElement( 'item' )
233      d,u = cf.names[i]
234      uid = str(i)
235      title = string.capwords( string.replace( uid, '_', ' ' ) )
236      label = string.replace( title, ' ', '' )
237      for w in ['Of','In','On','By']:
238        ww = ' %s ' % w
239        title = title.replace( ww, string.lower( ww ) )
240      item.setAttribute( 'uid', uid  )
241      item.setAttribute( 'label', label  )
242      item.setAttribute( 'title', title  )
243      item.setAttribute( 'units', str(u) )
244      item.setAttribute( 'description', str(d) )
245      thiss.appendChild( item )
246
247  def writeTimeSlice(self):
248    xx = self.vocabs.getElementsByTagName( 'timeSlice' )
249    assert len(xx) == 1, 'Expecting one element named "activity", found %s' % len(xx)
250    iDoc = xx[0]
251    thiss = self.doc.getElementsByTagName( 'timeSlice' )[0]
252    dil = thiss.getElementsByTagName('item')
253    for d in dil:
254      thiss.removeChild(d)
255
256    for i in iDoc.getElementsByTagName('item'):
257      item = self.doc.createElement( 'item' )
258      label = i.getAttribute( 'label' )
259      for k in ['label','title','type']:
260        item.setAttribute( k, i.getAttribute( k ) )
261      for k in ['start', 'end', 'step', 'sliceLen', 'nyears']:
262        if i.getAttribute( k ) != '':
263          v = str( int( float( i.getAttribute( k ) ) ) )
264          item.setAttribute( k, v )
265      item.setAttribute( 'uid', '_slice_%s' % label )
266      thiss.appendChild( item )
267
268  def writeMip(self):
269    self.mipUids = set()
270    xx = self.vocabs.getElementsByTagName( 'activity' )
271    assert len(xx) == 1, 'Expecting one element named "activity", found %s' % len(xx)
272    mipDoc = xx[0]
273## <item id="tmpid.0003" label="C4MIP" status="" title="Coupled Climate Carbon Cycle Model Intercomparison Project" url="http://c4mip.lsce.ipsl.fr/"/>
274    thiss = self.doc.getElementsByTagName( 'mip' )[0]
275    dil = thiss.getElementsByTagName('item')
276    for d in dil:
277      thiss.removeChild(d)
278    for i in mipDoc.getElementsByTagName('item'):
279      item = self.doc.createElement( 'item' )
280      mip = i.getAttribute( 'label' )
281      for k in ['title','url']:
282        item.setAttribute( k, i.getAttribute( k ) )
283      uid = string.replace( mip, ' ', '' )
284      item.setAttribute( 'uid', uid )
285      item.setAttribute( 'label', uid )
286      self.mipUids.add( uid )
287      thiss.appendChild( item )
288
289    if "DECK" not in self.mipUids:
290      item = self.doc.createElement( 'item' )
291      item.setAttribute( 'uid', 'DECK' )
292      item.setAttribute( 'url', '' )
293      item.setAttribute( 'label', 'DECK' )
294      item.setAttribute( 'title', 'DECK - set of standard CMIP runs' )
295      self.mipUids.add( "DECK" )
296      thiss.appendChild( item )
297
298  def prepRequestVarGroup(self):
299    self.varGroupByLabel = {}
300    self.varGroupUids = set()
301    nsev = 0
302    ss = set()
303    for k in ['requestvargroup','tablesection']:
304      if k == 'requestvargroup':
305              kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
306              il = 2
307      else:
308              kk = ['uid', 'gpid', 'mip', 'label', 'title', 'ref', 'refNote']
309              il = 3
310      thissh = self.skey[k]
311      for r in thissh:
312        if r[0] != '_':
313          thisl = str( thissh[r][il] )
314          if self.varGroupByLabel.has_key( thisl ):
315            print 'ERROR.090.00012: Duplicate label in variable groups: %s' % thisl
316            nsev += 1
317            ss.add( thisl )
318          self.varGroupByLabel[thisl] = r
319          self.varGroupUids.add( thissh[r][0] )
320
321    for k in self.prqv.exrqvg.keys():
322         ll = self.prqv.exrqvg[k]
323         thisl = string.replace( str( ll[2] ), '.', '-' )
324         if self.varGroupByLabel.has_key( thisl ):
325            print 'ERROR.090.00012: Duplicate label in variable groups: %s' % thisl
326            nsev += 1
327            ss.add( thisl )
328         self.varGroupByLabel[thisl] = k
329         self.varGroupUids.add( ll[0] )
330
331    self.rvgUidMapping = {}
332    for k in mappedTables.keys():
333      assert k not in ss and mappedTables[k] not in ss, 'Ambiguous table mapping because of duplicate variable group labels: %s' % k
334      ##assert self.varGroupByLabel.has_key( k ),'Table mapping key not found: %s' % k
335      assert self.varGroupByLabel.has_key( mappedTables[k] ),'Table mapping target not found: %s [%s]' % (mappedTables[k], str(self.varGroupByLabel.keys()) )
336      if k in mappedTables and k in self.varGroupByLabel:
337        self.rvgUidMapping[self.varGroupByLabel[k]] = self.varGroupByLabel[ mappedTables[k] ]
338        print 'INFO.090.00012: request variable mapping initialised: %s --> %s' % (k,mappedTables[k])
339      else:
340        print 'INFO.090.00011: request variable mapping NOT initialised: %s --> %s' % (k,mappedTables[k])
341     
342    assert nsev < 20, 'Multiple duplicate labels in variable groups: %s' % nsev
343
344  def prepVar(self):
345      thissh = self.skey['var']
346      self.varsxx = None
347      if self.newImport:
348#['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0', 'rlm0']
349        self.vars = collections.defaultdict( list )
350        self.vars1 = collections.defaultdict( list )
351        for k in thissh:
352          if k[0] != '_':
353            ll = thissh[k][:]
354            thisl = str( ll[2] )
355            self.vars[thisl].append( k )
356            self.vars1[str( ll[0] )].append( k )
357      else:
358        self.varsxx = collections.defaultdict( list )
359        for k in thissh:
360          if k[0] != '_':
361            ll = thissh[k][:]
362            thisl = str( ll[2] )
363            self.varsxx[str( ll[0] )].append( k )
364       
365
366  def prepRequestItem(self):
367      thissh = self.skey['requestitem']
368      for k in thissh:
369        if k[0] != '_':
370          ll = thissh[k][:]
371          ku = str(ll[2])
372##
373          self.exptPnt[ku].append( str(k) )
374
375
376      thissh = self.skey['experiment']
377      for k in thissh:
378        if k[0] != '_':
379          ll = thissh[k][:]
380          thisl = str( ll[2] )
381          self.mips.add( str( ll[4] ) )
382          self.experiments[thisl] = str( ll[0] )
383          self.exptSet.add( nt_expt._make( [str( ll[0] ), thisl, str( ll[4] ), str( ll[1] ) ] ) )
384          ##nt_expt = collections.namedtuple( 'expt', ['uid', 'label', 'mip', 'egid' ] )
385
386      thissh = self.skey['exptgroup']
387      for k in thissh:
388        if k[0] != '_':
389          ll = thissh[k][:]
390          thisl = str( ll[1] )
391          self.exptGrpDict[thisl] = str( ll[1] )
392          self.experimentGrp[thisl] = str( ll[0] )
393
394      mm = []
395      for m in self.mips:
396        if m not in self.mipUids:
397          mm.append(m)
398      assert len(mm) == 0, 'Not all mips found: %s: %s' % (str(mm),str(self.mipUids))
399
400  def prepRequestLink(self):
401      s0 = {' ta, ua, va, zg, hus', 'zg', 'utendogw, utendnogw, vtendogw,vtendnogw', 'tntogw,tntnogw', 'tasmax,tasmin,pr,prc,uas,vas', 'utendogw,utendnogw, and psistar, utendvstarad, utendwstarad', ' ta, ua, va, wap, zg, hus', 'vstar, wstar, fy, fz, utenddivf, utendogw, utendnogw, diabdrag[utenddiabdrag]', 'vmro3', 'tauu,tauv, tauu_pbl, tauv_pbl', 'tauu,tauv, tauu-pbl, tauv-pbl', ' tas, pr, psl', 'vstar, wstar, fy, fz, utenddivf', ' tas, pr, psl, uas', 'zmtnt, tntlw, tntsw', 'pr,prc',
402      'concdust,concaerh2o,reffclwc,emiso4,loadso4,concso2,emidust,emiss,conccmcn,emiso2,concnmcn,concss,reffclws,loadss,conccn',
403      'rsdsdiff,dryso4,wetso2,cldnci,od550lt1aer,reffclwtop,dryss,wetso4,sconcso4,cldncl,abs550aer,wetss,rsdscsdiff,wetdust,ec550aer,cldnvi,dryso2,drydust,od550aer,sconcss,sconcdust',
404      'thkcello,wmo,uo,hfnorth,tos,sos,soga,masscello,hfy,msftmrhoz,masso,pso,mlotst,zos,zostoga,rhopoto,hfydiff,hfbasin,ficeberg2d,thetao,so,zossga,dpco2,msftmyz,tauvo,sfdsi,msftyrhoz,spco2,fddtalk,hfxdiff,omlmax,htovovrt,sltovovrt,vmo,tauuo,volo,zsatarag,fgco2,zosga,wfo,vo,msftyyz,mfo,ficeberg,friver,msftbarot,umo,intpcalcite,intparag,fddtdic,hfx,agessc,hfbasindiff',
405      'difvmo,difvho,difvso' }
406      s1 = {'vstar, wstar, fy, fz, acceldivf[utenddivf], accelogw[utendogw], accelnogw[utendnogw], diabdrag[utenddiabdrag]'}
407      self.varGroupSs2 = collections.defaultdict( cls_s1 )
408      self.varGroupSubset = collections.defaultdict( dict )
409      kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','preset', 'ref', 'refNote', 'refid']
410##
411## preset is in the wrong place here ..... should be on the linked experiment group ...
412## probable better to edit the sheet and create a new group,  but in such a way that this class can generate the links and new variables....
413##
414# create lists of variables wanted from groups, indexed by uid of group and requestLink
415      thissh = self.skey['requestlink']
416      for k in thissh:
417        if k[0] != '_':
418          rr = thissh[k][:]
419          if rr[8] in s0:
420            vl0 = map( string.strip, string.split( rr[8], ',' ) )
421            print 'INFO.077.07060: rr[8] matched .... ', rr[8]
422          elif rr[7] in s0:
423            print 'INFO.077.07070: rr[7] matched .... ', rr[7]
424            vl0 = map( string.strip, string.split( rr[7], ',' ) )
425          elif rr[8] in s1:
426            print 'INFO.077.07071: rr[7] matched .... ', rr[8]
427            vl0 = map( string.strip, string.split( rr[8], ',' ) )
428            ##for i in range( len( vl0) ):
429              ##if string.find( vl0[i], '[' ) != -1:
430                ##a,b = string.split( vl0[i], '[' )
431                ##vl0[i] = (a,b[:-1])
432          else:
433            vl0 = None
434
435          if vl0 != None:
436            vl = set()
437            for v in vl0:
438              if string.find( v, '[' ) != -1:
439                bits = string.split( v, '[' )
440                vl.add( (bits[0],bits[1][:-1]) )
441              else:
442                vl.add(v)
443            m = str(rr[1])
444
445            self.varGroupSubset[str(rr[-1])][rr[0]] = vl
446            self.varGroupSs2[str(rr[-1])].a[(m,tuple(vl))].append(rr[0])
447            print 'INFO.077.07080: ',m,vl, rr[-1]
448
449##
450## not finding new variables .... may be better to redefine the groups ...
451##
452###
453### get full list of variables for each variable group
454###
455      thissh = self.skey['requestvar']
456      kk = ['label', 'table', 'mip', 'vid', 'priority','vgid','title','uid']
457      varGroupFull = collections.defaultdict( dict )
458      for k in thissh:
459        if k[0] != '_':
460          ll = thissh[k][:]
461          vgid = self.prqv.rqv_vg['%s.%s.%s' % (ll[2],ll[1],ll[0])]
462          ##if ll[1][:4] == 'DYVR':
463          print 'INFO.802.00001: ',ll, vgid in self.varGroupSubset.keys()
464          if vgid in self.varGroupSubset.keys():
465             varGroupFull[vgid][ll[0]] = k
466
467      for ll in self.rqv:
468          vgid = ll[  self.rqvinfo.index('gpid') ]
469          if vgid in self.varGroupSubset.keys():
470             varGroupFull[vgid][ll[1]] = ll[0]
471###
472### check that all variable groups covered
473###
474      nf = []
475      for k in self.varGroupSubset.keys():
476       if not (k in varGroupFull):
477         nf.append(k)
478
479      if len(nf) != 0:
480        for k in nf:
481          for k2 in self.varGroupSubset[k].keys():
482            print 'ERROR.080.06000: Variable group not found: ',k,k2,self.varGroupSubset[k][k2]
483##
484## some missing groups ...
485## appear to be missing MIP tables, e.g. CCMI_monthly
486## CCMI_monthly exists, but has no variables linking to it.
487##
488        print 'ERROR.080.06000:  %s %s' % (len(nf),len(varGroupFull.keys()))
489
490
491      shrvg = self.skey['requestvargroup']
492      for k in self.varGroupSs2:
493        if k not in varGroupFull:
494          print 'ERROR.080.06001: not in varGroupFull: %s [%s] %s' % (k,str(self.varGroupSs2[k].a.keys()), str( shrvg[k] ) )
495
496      self.rqvClone = collections.defaultdict( list )
497      self.rqvgrpExtra = []
498      self.rqlRedirect = {}
499      for k in varGroupFull:
500        for m,k2 in self.varGroupSs2[k].a:
501          ok1 = []
502          for i in k2:
503            i1 = i
504            if type(i) in [type(''),type(u'')]:
505              if string.find( i, 'and ' ) != -1:
506                i1 = string.split(i)[-1]
507                print 'INFO.099.09090: split i:',i,i1
508              ok1.append( varGroupFull[k].has_key(i1) )
509            elif type(i) == type( () ) and len(i) == 2:
510              ok1.append( varGroupFull[k].has_key(i[0]) or varGroupFull[k].has_key(i[1]) )
511            else:
512              print 'ERROR.080.06055: skipping unrecogised element: ',i
513              ok1.append( False )
514
515          ok = all( ok1 )
516          if not ok:
517            k2m = [  k2[i]  for i in range(len(k2)) if not ok1[i] ]
518            print 'ERROR.080.06060: not all vars found [%s] %s' % ( k, str(k2m) )
519          else:
520##
521## create new variable group and update link(s)
522##
523            gpid = str( uuid.uuid1() )
524            for rqlid in self.varGroupSs2[k].a[(m,k2)]:
525              self.rqlRedirect[rqlid] = gpid
526              ##kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
527## e.g. ['4db2f616-6d9e-11e5-b29a-ac72891c3257', 'DAMIP', u'DynVar-day', u'DAMIP: DynVar-day', 'new', u'DynVar.DYVR_daily']
528            ll =  rq.rqvg[k][:]
529            ll[0] = gpid
530            ll[2] += '-subset'
531            ll[-1] += ' (subset)'
532            self.rqvgrpExtra.append( ll )
533            print 'INFO.080.06060: subset validated, ', ll
534            for i in k2:
535##
536## set a marker to clone request variable record, with new group id
537##
538              i1 = i
539              if type(i) == type( () ) and len(i) == 2:
540                if varGroupFull[k].has_key(i[0]):
541                  i1 = i[0]
542                else:
543                  i1 = i[1]
544              elif string.find( i, 'and ' ) != -1:
545                i1 = string.split(i)[-1]
546              self.rqvClone[varGroupFull[k][i1]].append( gpid )
547
548  def finishRequestLink(self):
549    this = self.doc.getElementsByTagName('requestVarGroup')[0]
550## e.g. ['4db2f616-6d9e-11e5-b29a-ac72891c3257', 'DAMIP', u'DynVar-day', u'DAMIP: DynVar-day', 'new', u'DynVar.DYVR_daily']
551    kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
552    for ll in self.rqvgrpExtra:
553         item = self.doc.createElement( 'item' )
554         for j in range(len(kk)):
555              if kk[j] == 'refNote':
556                item.setAttribute( kk[j], str( ll[j] ) + '((isd.010))' )
557              else:
558                item.setAttribute( kk[j], str( ll[j] ) )
559         this.appendChild( item )
560##
561
562  def prep01(self):
563#### prepare some links for request variables
564    addex = True
565    self.prqv = ivg.prepRequestVar(addex)
566    self.prqv.run()
567
568  def prep(self,rq):
569## keys here match section element names in schema
570    #for k in [ 'var','ovar','groupitem', 'revisedtabitem']:
571## lists for 3 new sections
572### uuid, spid, tmid, cell_methods, cell_measures, description, procNote, prov
573    structure = [] 
574    self.structInfo = {}
575### uuid, label, dimensions, shape, levels, levelFlag
576    spatialshp = []
577### uuid, label, dimension, tstyle
578    temporalshp = []
579### cmor variables
580    self.cmv = []
581    self.cmvUidByFL = collections.defaultdict( cls_s1 )
582    self.cmvs = set()
583    self.cmvinfo = ('uid','stid','label','title','description','vid', \
584                    'deflate_level', 'shuffle', 'ok_max_mean_abs', 'flag_meanings', 'type', 'ok_min_mean_abs',  \
585                    'deflate', 'valid_min', 'flag_values', 'modeling_realm', 'valid_max', 'positive', 'mipTable', \
586                    'prov', 'provNote', 'frequency', 'rowIndex', 'coordinates','defaultPriority')
587    self.cmvinfo2 = ('uid','stid','label','title','description','vid', \
588                    'deflate_level', 'shuffle', 'ok_max_mean_abs', 'type', 'ok_min_mean_abs',  \
589                    'deflate', 'valid_min', 'modeling_realm', 'valid_max', 'positive', 'mipTable', \
590                    'prov', 'provNote', 'frequency', 'rowIndex', 'defaultPriority')
591    self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
592
593
594    thissh = self.skey['var']
595    self.varUidByName = self.importWbMods.vars.c1
596    ##self.varUidByName = collections.defaultdict( list )
597    if self.newImport:
598      oo = open('refDefaultP.txt', 'w' )
599      for k in thissh:
600         if k[0] != '_':
601##['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0']
602            thisuuid = str(k)
603            self.defaultP[thisuuid] = thissh[k][-1]
604            oo.write( '%s\t%s\t%s\t%s\n' % (k, thissh[k][0], thissh[k][2], thissh[k][-1] ) )
605            ##self.varUidByName[thissh[k][0]].append( thisuuid )
606      oo.close()
607    else:
608      ## ['label', 'title', 'description', 'procComment', 'procnote', 'prov', 'provmip', 'sn', 'units', 'uid','defaultp']
609      self.vars = collections.defaultdict( list )
610      self.vars1 = collections.defaultdict( list )
611      for uid in self.importWbMods.vars.d1:
612        self.defaultP[uid] = self.importWbMods.vars.d1[uid][-1]
613## collection indexed by short_name
614        self.vars1[self.importWbMods.vars.d1[uid][0]].append( uid )
615## collection indexed by standard_name
616        self.vars[self.importWbMods.vars.d1[uid][7]].append( uid )
617
618### request variables
619    self.rqv = []
620    self.realmByVar = collections.defaultdict( list )
621    for ksect in [ 'ovar','groupitem']:
622      thissh = self.skey[ksect]
623      if ksect == 'ovar':
624            setu1 = set()
625            tab2freq = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
626                  u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
627                  u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
628                  u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
629                  u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
630                  u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
631                  u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
632                  u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'day', \
633                  u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
634                  u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
635                  u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr'}
636            kk = ['uid', 'comment', 'deflate_level', 'shuffle', 'ok_max_mean_abs', 'flag_meanings', 'type', 'ok_min_mean_abs', 'sn', 'deflate', 'title', 'valid_min', 'cell_methods', 'flag_values', 'cell_measures', 'out_name', 'modeling_realm', 'units', 'cell_methods_xx', 'valid_max', 'positive', 'var', 'mipTable', 'dimensions', 'vid', 'gpid','rowIndex','ssect', 'priority']
637            id = kk.index('dimensions')
638            ivid = kk.index('vid')
639            thisnt = collections.namedtuple( 'ovar', kk )
640            ov = []
641            dset = set()
642            ds2 = set()
643            ovuu = {}
644            for k in thissh:
645              if k[0] != '_':
646                rr = thissh[k][:]
647                if rr[id] == 's|c|a|l|a|r':
648                  print 'ERROR.060.0001: bad dimension string detected and corrected: %s' % rr[id]
649                  rr[id] = 'scalar'
650                if string.find( rr[23], 'plevs' ) != -1:
651                   print 'INFO.qqqq01: ',rr[21:24]
652                rr[23] = string.replace(rr[23], 'plevs', 'plev17')
653                tt = thisnt._make( rr ) 
654                if tt.uid in setu1:
655                  print 'ERROR.099.0002: duplicate uuid: %s: %s' % (uuid,str(rr))
656                if str(tt.vid) == '__var_not_found_012__':
657                  print 'ERROR.099.00102: bad vid string: %s [%s]' % (tt.vid,tt.out_name)
658                       
659                if str(tt.vid) not in self.importWbMods.vars.d1:
660                  if tt.out_name in self.importWbMods.vars.c1:
661                    if len( self.importWbMods.vars.c1[ tt.out_name ] ) == 1:
662                      rr[ivid] = self.importWbMods.vars.c1[ tt.out_name ][0]
663                      tt = thisnt._make( rr ) 
664                      print 'INFO.099.00103: bad vid string replaced: %s [%s]' % (tt.vid,tt.out_name)
665                    else:
666                      print 'ERROR.099.00104: ambiguous bad vid string: %s [%s]' % (tt.vid,tt.out_name)
667                  else:
668                    print 'ERROR.099.00105: bad vid string: %s [%s]' % (tt.vid,tt.out_name)
669                setu1.add(tt.uid)
670                ov.append( tt )
671                dset.add( ov[-1].dimensions )
672                ds2.add( (tt.dimensions,tt.cell_methods,tt.cell_measures,tt.flag_values, tt.flag_meanings) )
673                ovuu[tt.uid] = tt
674                if rr[22][-3:] in ['mon','day','3hr']:
675                  fr = rr[22][-3:]
676                elif rr[22][-2:] in [ 'yr','fx']:
677                  fr = rr[22][-2:]
678                else:
679                  fr = tab2freq[rr[22]]
680   
681                prov = '%s ((isd.003))' % tt.mipTable
682                if tt.mipTable[:4] == 'OMIP':
683                  prov = 'CMIP6 [OMIP] ((isd.001))'
684                elif string.find( tt.mipTable, '_' ) != -1:
685                  prov = '%s [%s] ((isd.002))' % tuple( string.split( tt.mipTable, '_' ) )
686
687                if tt.var[:5] == 'xx..ccmi_':
688                  pass
689                else:
690                  lab = tt.var
691                  if lab in {'*','include Oyr 3D tracers'}:
692                    lab = '-copy-'
693##
694## insert conditional on redundant tables here ...
695##
696                  if tt.mipTable in redundantTables:
697                    if tt.mipTable not in reportedRedundantTables:
698                      print 'INFO.000.11111: redundant table spotted: ',tt.mipTable
699                      reportedRedundantTables.add( tt.mipTable )
700                  else:
701                    if tt.uid in self.cmvs:
702                       print 'ERROR.090.09010: duplicate cmv uid :',tt.__dict__
703                    self.cmvs.add( tt.uid )
704                    self.cmv.append( (tt.uid, (tt.dimensions,tt.cell_methods,tt.cell_measures,tt.flag_values,tt.flag_meanings), lab, tt.title, tt.comment, tt.vid, \
705                      tt.deflate_level, tt.shuffle, tt.ok_max_mean_abs, tt.flag_meanings, tt.type, tt.ok_min_mean_abs, \
706                      tt.deflate, tt.valid_min, tt.flag_values, tt.modeling_realm, tt.valid_max, tt.positive, tt.mipTable, \
707                      prov, tt.ssect, fr, tt.rowIndex, '',int(tt.priority)) )
708                    self.realmByVar[ lab ].append( tt.modeling_realm )
709                    if string.strip( tt.gpid ) == '':
710                       print 'ERROR.090.0990: blank gpid: ',lab,tt.mipTable
711                    vgid = tt.gpid
712                    if tt.mipTable[:4] == 'OMIP':
713                       m,t = string.split( tt.mipTable, '.' )
714                       vgid = self.prqv.getvgid( [None,t,m] )
715                       if vgid[0] != '_':
716                         if vgid != tt.gpid:
717                           print 'INFO.090.0990: link repare:',tt.gpid,lab,tt.mipTable,vgid
718                    self.rqv.append( (str( uuid.uuid1() ),lab, tt.uid, vgid, tt.priority,tt.mipTable,tt.mipTable) )
719                    if vgid not in self.varGroupUids:
720                      print 'ERROR.099.09901: bad vgid: ',self.rqv[-1]
721    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
722            self.dsort( dset )
723            print self.dsortdd[ksect][0].keys()
724
725      elif ksect == 'groupitem':
726            kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'priority', 'mip', 'uid', 'rowIndex', 'new', 'gpid', 'vkey', 'vid']
727            thisnt = collections.namedtuple( 'groupitem', kk + ['cmorv',] )
728            il = kk.index( 'levels' )
729            iu = kk.index( 'uid' )
730            idx = kk.index( 'descriptionEx' )
731            ixvid = kk.index( 'vid' )
732            ixvar = kk.index( 'var' )
733            ixp = kk.index( 'priority' )
734            dset = set()
735            dsgpi = set()
736            gi = []
737            s1 = set()
738            sm = set()
739            varsets = []
740            nov = 0
741            setu = set()
742            for k in thissh.keys():
743              if k[0] != '_':
744                rr = thissh[k][:]
745                if trace.GROUPITEM_ta and rr[ixvar] == 'ta':
746                  print 'INFO.045.00004: groupitem: ',rr
747
748##
749## convert floats back to integer
750##
751                if type(rr[ixp]) == type(1.):
752                  rr[ixp] = int(rr[ixp])
753##
754## split variable, create 2nd record at 23 levels.
755##
756                if rr[iu] in setu:
757                  print 'ERROR.099.0001: duplicate uuid in varGroups ... %s:: %s' % (uuid,str(rr))
758                if rr[iu] in setu1:
759                  print 'ERROR.099.0003: duplicate uuid in varGroups/ovar ... %s:: %s' % (uuid,str(rr))
760                setu.add(rr[iu])
761                if rr[il] in  {u'17 (or 23 )', u'17 (or 23)', u'17 (or23)', u'10/17/23'}:
762                  if rr[il] == u'10/17/23':
763                     lev0 = 10
764                     levsp = [17,23]
765                  else:
766                     lev0 = 17
767                     levsp = [23,]
768                  rr[ixp] = 1
769                  p = 1
770                  for lp in levsp:
771                    p += 1
772                    rr0 = rr + [rr[1] + str(lp),]
773                    rr0[ixp] = p
774                    rr0[il] = lp
775                    rr0[iu] = str( uuid.uuid1() )
776                    tt = thisnt._make( rr0 )
777                    if str(tt.vid) == '__var_not_found_012__':
778                      print 'ERROR.099.00104: bad vid string: %s [%s]' % (tt.vid,tt.var)
779                    gi.append( tt )
780                    varsets.append( (rr0[iu], 2, rr[iu], 1, 'variables at multiple vertical resolutions' ) )
781                  rr[il] = lev0
782                  tt = thisnt._make( rr + [rr[1] + str(lev0),] )
783                elif rr[il] in [u'Model levels or plev_27', u'Model levels or 27Plevs',u'27',27.]:
784                  rr0 = rr + [rr[1] + '27',]
785                  print 'INFO.0088.07007: ',rr0
786                  rr0[il] = 27
787                  rr0[iu] = str( uuid.uuid1() )
788                  if str(rr0[ixvid]) == '__var_not_found_012__':
789                    if str(rr0[ixvar]) in self.varUidByName:
790                      if len( self.varUidByName[rr0[ixvar]] ) == 1:
791                        rr0[ixvid] = self.varUidByName[rr0[ixvar]][0]
792                  tt = thisnt._make( rr0 )
793                  if str(tt.vid) == '__var_not_found_012__':
794                    print 'ERROR.099.00105: bad vid string: %s [%s]' % (tt.vid,tt.var)
795##
796## no longer requesting all option of "all or ..."
797##
798                  ##gi.append( tt )
799                  ##rr[il] = 'all'
800                  ##tt = thisnt._make( rr + [rr[1],] )
801                  varsets.append( (rr0[iu], 0, rr[iu], 0, 'Variables on model levels or 27 pressure levels' ) )
802                elif string.find( rr[idx], '850 hPa' ) != -1:
803                  print 'INFO.0099.0016: ', rr
804                  if rr[1][-3:] != '850':
805                    rr = rr + [rr[1] + '850',]
806                  else:
807                    rr = rr + [rr[1],]
808                  tt = thisnt._make( rr )
809                else:
810##
811## this point ... to mark HighResMIP 7 levels as distinct from CFMIP.
812## enough information in "mip" tag of tt record
813##
814                  if type( rr[il] ) == type(1.):
815                    if rr[il] == 7. and rr[10] == 'HighResMIP':
816                      print 'INFO.qqq03:',rr[il],rr
817                      rr[5] = rr[5] + '*'
818                  if str(rr[ixvid]) == '__var_not_found_012__':
819                    ok = False
820                    if str(rr[ixvar]) in self.varUidByName:
821                      if len( self.varUidByName[rr[ixvar]] ) == 1:
822                        rr[ixvid] = self.varUidByName[rr[ixvar]][0]
823                        print 'INFO.099.00106: correcting vid for %s' % rr[ixvar]
824                        ok = True
825                    if not ok:
826                        print 'WARN.099.00106: error in vid for %s not corrected' % rr[ixvar]
827                  tt = thisnt._make( rr + [rr[1],] )
828                  if str(tt.vid) == '__var_not_found_012__':
829                    print 'ERROR.099.00106: bad vid string: %s [%s]' % (tt.vid,tt.var)
830                 
831                if str(tt.mip) != 'OMIP':
832                  gi.append( tt )
833                  sm.add( tt.mask )
834
835            print '####### masks: ',sm
836            smdd = {}
837            dsn = {'floating ice shelf':u'floating ice sheet', u'ocean':u'sea' }
838            d1 = {u'land':(False,'area: mean where land'), \
839                  u'grounded ice sheet':(True,'area: mean where grounded_ice_sheet'), \
840                  u'ice sheet':(True,'area: mean where ice_sheet'), \
841                  u'floating ice sheet':(True,'area: mean where floating_ice_sheet'), \
842                  u'floating ice shelf':(True,'area: mean where floating_ice_sheet'),
843                  u'sea':(False,'area: mean where sea') }
844            for s in sm:
845              if s in  ['', u'none',u'Southern hemisphere', u'Northern hemisphere']:
846                smdd[s] = (False,'')
847              else:
848                smdd[s] = d1[ dsn.get( s,s ) ]
849
850            setu = set()
851
852            ccchk = ivg.checkCmv(gi)
853            nrep = 0
854
855            for tt in gi:
856                gr = 'a'
857                if tt.mip == 'OMIP' or any( [string.find(tt.table,i) != -1 for i in ['Omon','Oyr','Oclim','OImon','Ocean'] ] ):
858                  gr = 'o'
859                if self.varsxx != None:
860                  if tt.cmorv in self.varsxx:
861                    sss = set()
862                    for k in self.varsxx[tt.cmorv]:
863                      sss.add(self.skey['var'][k][-1] )
864                    sss = list(sss)
865                    if len(sss) == 1:
866                      if sss[0] == 'ocean':
867                        gr = 'o'
868                      elif sss[0] == 'atmos':
869                        gr = 'a'
870                    print 'INFO:lllw:', tt.cmorv, sss, gr
871                if tt.cmorv == 'sltbasin':
872                   print 'INFO.llll: ',tt,gr
873##
874## adding label for mip here messes up referencing later ...
875##
876                dset.add( (tt.shape,tt.levels,tt.tstyle,gr) )
877                dsgpi.add( (tt.shape,tt.levels,tt.tstyle,gr,smdd[tt.mask], 'None', 'None') )
878### need to check where variables are, perhaps, refering to "ovar"
879            ##kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'rowIndex', 'new', 'gpid', 'vkey', 'vid']
880                prov = '%s [%s]' % (tt.mip,tt.group)
881                provNote = ''
882                lab = tt.cmorv
883                if lab in {'*','include Oyr 3D tracers'}:
884                  lab = '-copy-'
885                elif lab == 'wap (omega)':
886                  lab = 'wap'
887                  provNote = 'wap (omega)'
888                lab = string.replace( string.strip(lab), '_', '-' )
889                if tt.uid in setu:
890                     print 'SEVERE[1]: duplicate uuid: ',tt.__dict__
891                setu.add( tt.uid )
892                fr = freqmap.get( tt.freq, tt.freq )
893                ntab = 'em%s' % string.capwords( fr )
894               
895                if ovuu.has_key(tt.vid):
896                  tt1 = ovuu[tt.vid]
897                  if tt1.modeling_realm == 'seaIce':
898                    ntab = 'OImon'
899                  if tt.priority in [1,2,3]:
900                    p = tt.priority
901                  else:
902                    p = int(tt1.priority)
903                  thisrealm = tt1.modeling_realm
904                  if gr == 'o' and thisrealm == 'atmos':
905                    thisrealm = 'ocean'
906                  thiscmv = (tt.uid, (tt.shape,tt.levels,tt.tstyle,gr,smdd[tt.mask],tt1.flag_values,tt1.flag_meanings), lab, '__from %s' % tt.table, tt.descriptionEx, tt1.vid, \
907                    tt1.deflate_level, tt1.shuffle, tt1.ok_max_mean_abs, tt1.flag_meanings, tt1.type, tt1.ok_min_mean_abs, \
908                    tt1.deflate, tt1.valid_min, tt1.flag_values, thisrealm, tt1.valid_max, tt1.positive, ntab, \
909                    prov, provNote, tt.freq, tt.rowIndex, '', int(p)) 
910                  self.realmByVar[ lab ].append( thisrealm )
911                  thisrqv = [str( uuid.uuid1() ),lab, tt.uid, tt.gpid, p, tt.mip, tt.group]
912                  nov += 1
913                else:
914                  thisrealm = ''
915                  if realmdefix.has_key( prov ):
916                    thisrealm = realmdefix[prov]
917                  else:
918                    print 'WARN:070.00001: realm not found for %s,%s' % (lab,prov)
919                  if gr == 'o' and thisrealm == 'atmos':
920                    thisrealm = 'ocean'
921
922                  if thisrealm == 'seaIce':
923                    ntab = 'OImon'
924
925                  if tt.priority in [1,2,3]:
926                    p = tt.priority
927                  elif  self.defaultP.get( tt.vid, 102) in [1,2,3]:
928                    p = self.defaultP.get( tt.vid, 102)
929                  else:
930                    p = 1
931                    print 'WARN:070.00002: priority defaulting to 1 for %s,%s' % (lab,prov)
932                  thiscmv = (tt.uid, (tt.shape,tt.levels,tt.tstyle,gr,smdd[tt.mask], 'None', 'None'), lab, '__from %s' % tt.table, tt.descriptionEx, tt.vid, \
933                    0, 0, 0, 0, '', 0, \
934                    0,0,0, thisrealm, 0, '', ntab, \
935                    prov, provNote, tt.freq, tt.rowIndex, '', str(p)) 
936                  self.realmByVar[ lab ].append( thisrealm )
937
938                  thisrqv = [str( uuid.uuid1() ),lab, tt.uid, tt.gpid, p, tt.mip, tt.group] 
939                if trace.GROUPITEM_ta and lab  == 'ta':
940                    print 'INFO.045.00005: groupitem: ',thisrqv
941
942
943                if ccchk.uidReplace.has_key(thiscmv[0]):
944                  nrep += 1
945                  thisrqv[2] = ccchk.uidReplace[thiscmv[0]]
946                else:
947                  self.cmv.append( thiscmv )
948                self.rqv.append( thisrqv )
949                if self.rqv[-1][3] not in self.varGroupUids:
950                      print 'ERROR.099.09902: bad vgid: ',self.rqv[-1]
951## Variables marked with shape '?' from PMIP are actually defined by OMIP ....
952                if tt.shape == '?':
953                  print 'ERROR.801.00001: shape not set: %s, %s, %s' % ( tt.shape,tt.mip,tt.var)
954
955            ##['', u'none', u'land', u'grounded ice sheet', u'floating ice sheet', u'floating ice shelf', u'ocean', u'ice sheet', u'sea', u'Southern hemisphere', u'Northern hemisphere']
956            self.dsort( dset,mode=ksect )
957            print 'INFO.088.00001: nrep=%s' % nrep
958            print 'INFO.088.00002: nov=%s [%s]' % (nov,len(gi))
959
960
961    for c in self.cmv:
962      u,v,f = (c[0],c[2],c[21])
963      self.cmvUidByFL[f].a[v].append( u ) 
964
965#######################################################################################
966#################
967    std = set()
968    ssd = set()
969    etd = {}
970    esd = {}
971    tshp = { 'time':['time-mean','Temporal mean'], 'time1':['time-point','Instantaneous value (i.e. synoptic or time-step value)'], \
972             'time2':['climatoglogy','Climatological mean'], \
973             '':['None','No temporal dimensions ... fixed field'], 'xxxx':['unknown','dimension not recognised'] }
974
975    for ksect in [ 'ovar','groupitem']:
976#### create structure list for spatial and temporal dimensions
977      for t in self.dsortdd[ksect][0].keys():
978        tdim, tt = self.dsort_u1( self.dsortdd[ksect][0][t], self.dsortdd[ksect][1] )
979
980        std.add( tdim )
981        ssd.add( tt )
982        ##ssd.add( (sdim,lfl,nl) )
983
984    for s in std:
985       label, description = tshp.get(s,tshp['xxxx'])
986       u = str( uuid.uuid1() )
987       etd[s] = (u,label,description,s)
988    kk = 0
989    for s in ssd:
990       d,lfl,nl = s
991       u = str( uuid.uuid1() )
992       kk+=1
993       lab = 'ssd-%3.3i' % kk
994       description = 'ssd.%3.3i' % kk
995       esd[s] = (u,lab,description,d,lfl,nl)
996
997    esd['Y-na'] = (str( uuid.uuid1() ),'extra','extra','latitude','false',1)
998    self.dimsTime = etd
999    self.dimsTimeInfo = ['uid','label','title','dimensions']
1000    self.dimsSpace = esd
1001    self.dimsSpaceInfo = ['uid','label','title','dimensions','levelFlag','levels']
1002       
1003    sshp = set()
1004    eshp = set()
1005    ll = []
1006    lls = ivg.structureList()
1007    nt_dims = collections.namedtuple( 'dims', ['uid','label','spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','description','procNote','prov'] )
1008    kk = 0
1009    strdd = {}
1010    ee3 = {}
1011    for dims,cmet,cmea,flgv, flgm in ds2:
1012        tdim, tt = self.dsort_u1( self.dsortdd['ovar'][0][dims], self.dsortdd['ovar'][1] )
1013        d1,odim,d2,crd = self.dsortdd['ovar'][0][dims]
1014        sdim,lfl,nl = tt
1015        u = str( uuid.uuid1() )
1016        spid = esd[tt][0]
1017        tmid = etd[tdim][0]
1018        kk += 1
1019        label = 'str-%3.3i' % kk
1020        proc = ''
1021        prov = 'CMIP5/OMIP'
1022        desc = ''
1023        print 'INFO.zzz01: ',dims
1024        t0 = (dims,cmet,cmea,flgv,flgm)
1025        if cmet == 'None':
1026          cmet = ''
1027        if cmea == 'None':
1028          cmea = ''
1029        if flgv == 'None':
1030          flgv = ''
1031        if flgm == 'None':
1032          flgm = ''
1033        t1 = (dims,cmet,cmea,flgv,flgm)
1034        u = lls.add( [u,label,spid,tmid, odim, crd, cmet, cmea, flgv, flgm, desc, proc, prov] )
1035        self.structInfo[u] = (label,cmet,spid)
1036        strdd[t0] = u
1037        strdd[t1] = u
1038         
1039        ##nt =  nt_dims._make( [u,label,spid,tmid, odim, crd, cmet, cmea, flgv, flgm, desc, proc, prov] )
1040        ##tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1041        ##if ee3.has_key( tt ):
1042            ##u = ee3[tt]
1043        ##else:
1044            ##ee3[tt] = u
1045            ##ll.append( nt )
1046        ##ll.append( nt_dims._make( [u,label,spid,tmid, odim, crd, cmet, cmea, flgv, flgm, desc, proc, prov] ) )
1047
1048    ttt = [ {u'Instantaneous (end of year)', 'instantaneous', 'point', 'Synoptic', u'synoptic', u'time: point'},
1049        {'Mean', u'time: mean', u'Time mean', u'daily mean', u'mean', u'time mean', u'time: day', u'time: mean', u'weighted time mean', 'Cumulative annual fraction'}, set(), {''}]
1050    cmetl = ['time: point', 'time: mean', 'time: mean within years time: mean over years ', '']
1051    ee1 = {}
1052    for shp,lvls,sty,gr,tmsk, flgv, flgm in dsgpi:
1053        t = (shp,lvls,sty,gr)
1054        tdim, tt = self.dsort_u1( self.dsortdd['groupitem'][0][t], self.dsortdd['groupitem'][1] )
1055        d1,odim,d2,crd = self.dsortdd['groupitem'][0][t]
1056        print 'INFO.099: ',d1,odim,d2,crd
1057        tflm, msk = tmsk
1058        sdim,lfl,nl = tt
1059        u = str( uuid.uuid1() )
1060        spid = esd[tt][0]
1061        tmid = etd[tdim][0]
1062        cmea = 'area: areacell%s' % gr
1063        cmet = ''
1064        for i in range(4):
1065          if sty in ttt[i]:
1066            cmet = cmetl[i]
1067        if cmet == '':
1068          cmet = msk
1069        elif msk != '':
1070          cmet += ' ' + msk
1071        kk += 1
1072        label = 'str-%3.3i' % kk
1073        proc = ''
1074        prov = 'CMIP5, endorsed MIPs'
1075        desc = ''
1076        dims = tt[0]
1077        if tdim != '':
1078          dims += '|' + tdim
1079        if strdd.has_key( (dims,cmet,cmea,'','') ):
1080          u = strdd[ (dims,cmet,cmea,'','') ]
1081          print 'INFO.zzz03: ',tt, tdim
1082        elif ee1.has_key( (tmid, spid, odim, cmet, cmea, crd) ):
1083          u = ee1[(tmid, spid, odim, cmet, cmea, crd)]
1084          print 'INFO.zzz04: ', tt, tdim
1085        else:
1086          print 'INFO.zzz02: ',tt, tdim
1087          u = lls.add( [u,label,spid,tmid, odim, crd, cmet, cmea, '', '', desc, proc, prov]  )
1088          ##nt =  nt_dims._make( [u,label,spid,tmid, odim, crd, cmet, cmea, '', '', desc, proc, prov] )
1089          ##tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1090          ##if ee3.has_key( tt ):
1091            ##u = ee3[tt]
1092          ##else:
1093            ##ee3[tt] = u
1094            ##ll.append( nt )
1095           
1096          ee1[(tmid, spid, odim, cmet, cmea, crd)] = u
1097        strdd[(shp,lvls,sty,gr,tmsk,flgv,flgm)] = u
1098        self.structInfo[u] = (label,cmet,spid)
1099
1100    ##nt_dims = collections.namedtuple( 'dims', ['uid','label','spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','description','procNote','prov'] )
1101    cc = collections.defaultdict( list )
1102    for nt in lls.ll:
1103      tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1104      cc[tt].append( nt.uid )
1105    ks = [k for k in cc.keys() if len( cc[k] ) > 1]
1106    if len( ks ) > 0:
1107      print 'DUPLICATE STRUCTURES'
1108      for k in ks:
1109        print 'DUPLICATE: ',k,len(cc[k])
1110     
1111    self.structList = lls.ll
1112    self.strdd = strdd
1113    oo = open( 'test.csv', 'w' )
1114    for l in ll:
1115      assert l.uid in self.structInfo, 'SEVERE: structure uid not in lookup ... %s' %  str( l.__dict__)
1116      oo.write( '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,\n' % l )
1117    oo.close()
1118
1119  def addAerChem(self):
1120    import importExtra
1121    lc = importExtra.loadAerChem()
1122    es = {}
1123    et = {}
1124    for l in self.dimsSpace.keys():
1125      print self.dimsSpace[l]
1126      assert self.dimsSpace[l][1] not in es, 'Duplicate spatial dimension label: %s' % self.dimsSpace[l][1]
1127      es[self.dimsSpace[l][1]] = l
1128    for l in self.dimsTime.keys():
1129      print self.dimsTime[l]
1130      assert self.dimsTime[l][1] not in et, 'Duplicate spatial dimension label: %s' % self.dimsTime[l][1]
1131      et[self.dimsTime[l][1]] = l
1132    nt_acv = collections.namedtuple( 'acv', ['sn','title','label', 'units', 'description', 'subsect', 'freq', 'splab', 'tm' ] )
1133    freq_map = {'hourly':'1hr', 'annual':'yr', 'daily':'day', 'fixed':'fx'} 
1134    for t in lc.cc2.keys():
1135      nn = 0
1136      for v in lc.cc2[t].a:
1137        v1 = v
1138        if v not in self.vars1:
1139          print 'INFO.kkkkk: AerChem Var missing: %s, %s' % (t,v)
1140          if string.replace( v, '_', '') in self.vars1:
1141            v1 = string.replace( v, '_', '')
1142            print 'INFO.kkkkk: AerChem %s found' % (v1)
1143        else:
1144          nn += 1
1145        tt = nt_acv._make( lc.cc2[t].a[v][0] )
1146        thisrealm = 'unset'
1147        freq = freq_map.get( tt.freq, tt.freq )
1148        ntab = 'aer%s' % freq
1149        thiscmv = (uuid.uuid1(), (tt.splab,tt.tm), tt.label, 'AerChemMIP', tt.description, self.vars1[v1][0], '','','','','float','','','','',"aero",'','',ntab,'AerChemMIP','',freq, 0, '', 1)
1150        self.cmv.append( thiscmv )
1151      print 'INFO.kkkkk: AerChem Vars found: %s: %s' % (t,nn)
1152                  ##thiscmv = (tt.uid, (tt.shape,tt.levels,tt.tstyle,gr,smdd[tt.mask],tt1.flag_values,tt1.flag_meanings), lab, '__from %s' % tt.table, tt.descriptionEx, tt1.vid, \
1153                    ##tt1.deflate_level, tt1.shuffle, tt1.ok_max_mean_abs, tt1.flag_meanings, tt1.type, tt1.ok_min_mean_abs, \
1154                    ##tt1.deflate, tt1.valid_min, tt1.flag_values, thisrealm, tt1.valid_max, tt1.positive, ntab, \
1155                    ##prov, provNote, tt.freq, tt.rowIndex, '', int(p))
1156
1157  def dsort_u1(self,eed,sde):
1158        tdim = eed[2]
1159        sdim = eed[0]
1160        nl = sde[sdim]
1161        lfl = 'true'
1162        if nl == -1:
1163          lfl = 'false'
1164          nl = 0
1165        elif nl == -2:
1166          nl = 1
1167          pass
1168        return (tdim, (sdim,lfl,nl) )
1169
1170
1171  def dsort( self, dset, mode='ovar' ):
1172      """Sort the dimensions string into spatial, temporal and other sections,
1173       returns a dictionary of tuples: spatial dimensions, other, temporal, coords and a 2nd, keyyed on spatial dimensions with a level count indicator.  """
1174      vdims = {'plev7':7, 'plev':4, 'plevs':17, 'plev3':3,'plev8':8,'alt40':40,'alev1':1, 'alevhalf':-1,'olevel':-1,'rho':-1,'sdepth':-1,'alevel':-1}
1175      odims = {'sza5','vegtype','scatratio','dbze','typepdec','vgidx','tau'}
1176      dl = sorted( list(dset) )
1177      if mode == 'ovar':
1178        eed = {}
1179        sss = [set(),set(),set(),set()]
1180        for s in dl:
1181          if s[:4] == 'time':
1182            bits = ['',s[4:]]
1183          else:
1184            bits = string.split(s, '|time', maxsplit=1 )
1185          if len(bits) == 1:
1186            ts = ''
1187          else:
1188            ts = 'time'
1189
1190          b0 = bits[0]
1191          b1 = ''
1192          bb = string.split(bits[0],'|')
1193          if bb[-1] in odims:
1194            if bb[-1] == 'tauxxx':
1195                b0 = bits[0][:-4]
1196                ts = 'tau|time'
1197            else:
1198              b0 = string.join( bb[:-1], '|' )
1199              b1 = bb[-1]
1200           
1201          if len(bits) == 1:
1202              tup = (b0,b1,'','')
1203          elif len(bits) == 2:
1204              b2 = string.split( bits[1], '|', maxsplit=1 )
1205              if len(b2) == 2:
1206                  tup = (b0,b1, ts + b2[0], b2[1])
1207              else:
1208                  tup = (b0,b1, ts + bits[1], '')
1209          eed[s] = tup
1210          for k in range(4):
1211            sss[k].add(tup[k])
1212
1213        lcount = {}
1214        for s in sss[0]:
1215          bits = string.split( s, '|' )
1216          nl = -2
1217          thisb = None
1218          for b in bits:
1219            if vdims.has_key(b):
1220              assert nl == -2, 'Duplicate vertical level count in %s' % s
1221              nl = vdims[b]
1222              thisb = b
1223          lcount[s] = nl
1224          if nl == -1 and s == 'latitude|basin':
1225            print 'SEVERE: error in level deduction'
1226            print s, bits, nl, thisb
1227            raise
1228      else:
1229        ## input is a set of tuples,  shape, levels, tstyle, o/a
1230        ## aim is to extract spatial, other, temporal dimensions + coords.
1231        sss = [set(),set(),set()]
1232        ttt = [ (u'Instantaneous (end of year)', 'instantaneous', 'point', 'Synoptic', u'synoptic', u'time: point'),
1233        ('Mean', u'time: mean', u'Time mean', u'daily mean', u'mean', u'time mean', u'time: day', u'time: mean', u'weighted time mean', 'Cumulative annual fraction'), (), ('',)]
1234        ttdd = {}
1235        kkk = ['time1','time','time2','']
1236        for i in range(4):
1237          for k in ttt[i]:
1238            ttdd[k] = kkk[i]
1239
1240        ##lll =  {[u'1.0', u'14.0', u'16.0',  u'17.0', u'27.0', u'3.0', u'36.0', u'4.0', u'40.0', u'7.0', ]:'flt', [u'17 (or 23 )', u'17 (or 23)', u'17 (or23)']:'obs', [u'Model levels or 27Plevs', u'all', u'all model levels', u'all model levels above 400hPa', u'all*', u'integrated over depth'], [u'single level',], [u'soil levels',], [u'surface',], [[u'100 m',] }
1241        dds = {'2D':'XYT', 'XY':'XYT', '':'?', '2D ':'XYT', 'XYZ':'XYZT', } 
1242## 'K'?? 'XYK'
1243        dd = {'XKT':('latitude|basin','','time','',False), \
1244             'XYZKT':('longitude|latitude|%s','effectRad','time','',True), \
1245             'XYZT':('longitude|latitude|%s','','time','',True), \
1246             'XYZT*':('longitude|latitude|%st','','time','',True), \
1247              'KZT':('alevel','spectband','time','',False), \
1248              'XYT':('longitude|latitude','','time','',False), \
1249              'XYKT':('longitude|latitude','angle','time','',False), \
1250              'YZT':('latitude|%s','','time','',True), \
1251              'XYK':('longitude|latitude','snowband','time','',False), \
1252              'K':('sistraits','','time','',False), \
1253              'scalar':('','','time','',False), \
1254              'ZST1':('alevel','site','time','',False), \
1255              'BasinYT':('latitude|basin','','time','',False), \
1256              '?':( '?', '?','?','?',False)
1257             }
1258             
1259        for d in dl:
1260          for k in range(3):
1261            sss[k].add( d[k] )
1262        ls0 = set()
1263        ls1 = set()
1264##
1265## sort shapes
1266##
1267        for s in sss[0]:
1268          if not dd.has_key( dds.get(s,s) ):
1269            print 'NO SOLUTION FOUND FOR SHAPE: "%s"' % s
1270          else:
1271            tt = dd[dds.get(s,s)]
1272            if tt[-1]:
1273              ls0.add( s )
1274##
1275## look at shapes which require additional information about vertical coord
1276##
1277        for d in dl:
1278          if d[0] in ls0:
1279             ls1.add( d[1] )
1280
1281        lset = {'soil levels':'sdepth', 'all model levels above 400hPa':'alevel'} 
1282        lsdd = {}
1283        for l in ls1:
1284          ii = 0
1285          if l in ['all','all*','all model levels']:
1286            ii = -1
1287            this = '%slevel' 
1288          elif lset.has_key(l):
1289            ii = -1
1290            this = lset[l]
1291          elif l == '':
1292            ii = -2
1293            this = l
1294          else:
1295            ii = int( float(l) )
1296            if ii in [40,16]:
1297              this = 'alt%s' % ii
1298            elif ii > 1.5:
1299              if ii > 35:
1300                ii = 39
1301##
1302## merge 14 and 17 level specifications to a 19 level coordinate
1303##
1304              if ii in [14,17]:
1305                ii = 19
1306              this = 'plev%s' % ii
1307            else:
1308              this = ''
1309          lsdd[l] = (ii,this)
1310##['', 1.0, u'all', 3.0, 4.0, u'soil levels', 7.0, 40.0, u'all model levels', u'17 (or 23)', u'all*', 14.0, u'Model levels or 27Plevs', 16.0, 17.0, u'all model levels above 400hPa', u'17 (or23)', 36.0, u'17 (or 23 )', 27.0]
1311             
1312        lcount = {}
1313        eed = {}
1314        for d in dl:
1315          s = d[0]
1316          if not dd.has_key( dds.get(s,s) ):
1317            print 'NO SOLUTION FOUND FOR SHAPE: "%s"' % s
1318          else:
1319            tt = dd[dds.get(s,s)]
1320            if tt[-1]:
1321              n,zz = lsdd[d[1]]
1322              if len(zz) > 0 and zz[0] == '%':
1323                zz = zz % d[3]
1324              sc = tt[0] % zz
1325              if sc[-1] == "|":
1326                print 'ERROR.080.05000: Bad dimension found %s [%s] %s %s' % (sc,str(tt), str((n,zz)), str(d)  )
1327            else:
1328              sc = tt[0]
1329              if (string.find( sc, 'alevel' ) != -1) or (string.find( sc, 'olevel' ) != -1):
1330                n = -1
1331              else:
1332                n = -2
1333
1334          lcount[sc] = n
1335          if n == -1 and sc == 'latitude|basin':
1336            print 'SEVERE [2]: error in level deduction'
1337            print sc, tt[0], tt[-1], n
1338            raise
1339          print 'INFO:qqq05: ',d, sc, tt, ttdd[d[2]]
1340          eed[d] = (sc,tt[1],ttdd[d[2]],tt[3])
1341      self.dsortdd[mode] = (eed,lcount)
1342
1343  def run(self,rq):
1344
1345    xx = self.doc.getElementsByTagName( 'main' )
1346    assert len(xx) == 1, 'Expecting one element named "main", found %s' % len(xx)
1347    main = xx[0]
1348    ## main = self.doc.childNodes[0]
1349    xsn = []
1350    ff = {}
1351    for c in main.childNodes:
1352      tag = c.nodeName
1353      if tag != '#text':
1354        xsn.append(tag)
1355        il = []
1356        for i in c.childNodes:
1357          if i.nodeName == 'item':
1358            il.append(i)
1359        xx = dict( il[0].attributes.items() )
1360        ff[string.lower(tag)] = (c,xx)
1361   
1362    print xsn
1363    print ff.keys()
1364    self.ff = ff
1365    ##        il.append(i,k in [ (rq.rqvg[k],k) for k in  rq.rqvg.keys() if k[0] != '_'] + [(exrqvg[k],k) for k in exrqvg.keys()]:
1366        ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'ref', 'refNote', 'refid']
1367        ##kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
1368        ##i = rq.rqvg[k]
1369       
1370        ##self.eern[i[ixrn]].append( i[0] )
1371        ##k2 = '%s__%s' % (i[ixrn-1],i[ixrn])
1372        ##if self.eern2.has_key( k2 ):
1373           ##dups.append( (k2,k,self.eern2[k2]) )
1374        ##self.eern2[k2] = i[0]
1375        ##assert i[0] == k, 'Bad key/uuid'
1376
1377    ##assert len( dups ) == 0, 'Duplicate refs: %s, %s' % (str(dups),str(map( lambda x: rq.rqvg[x[1]], dups )) )
1378       
1379## keys here match section element names in schema
1380    sectlist = [ 'experiment','exptgroup','objective','requestlink', 'requestitem','requestvargroup','tablesection' ]
1381    ## dec 2015 -- removing 'var' from this list
1382    if self.schemaMode != 'dreq2':
1383      sectlist = ['ovar','groupitem','revisedtabitem'] + sectlist
1384    else:
1385      sectlist.append( 'requestvar' )
1386
1387    for k in sectlist:
1388      thissh = self.skey[k]
1389## set labmod False for section in which label coercion is not wanted
1390      labmod = True
1391      lll = []
1392      for i in thissh.keys():
1393        if i[0] != '_':
1394          lll.append(i)
1395      idk = 0
1396      if len(lll) > 0:
1397##
1398## remove example items, xcept where this has been done in previous function
1399##
1400        if k not in ['xxxx']:
1401          dil = ff[k][0].getElementsByTagName('item')
1402          for d in dil:
1403            ff[k][0].removeChild(d)
1404
1405        vare = {}
1406        for i in lll:
1407          ll = map( uniCleanFunc, thissh[i] )
1408          assert len(ll) == len( thissh[i] ), 'Lost list elements after uniClean'
1409          idk += 1
1410#################################################################
1411######### NEED TO CLEAN THIS IF ITEMS FROM OTHER SECTIONS ARE FILTERED
1412#######################################################################
1413          dothis = True
1414          if k != 'var':
1415            item = self.doc.createElement( 'item' )
1416
1417          if k == 'objective':
1418 ## - mip; tab; expt; rlid; ny
1419            labmod = False
1420            kk = ['mip', 'label', 'title', 'description']
1421            ##thisl = string.replace(string.strip(str( ll[1] ) ), '-', ' ')
1422## camelcase this label.
1423            ##thisl = string.replace( string.capwords( thisl ), ' ', '' )
1424            thisl = mycc( ll[1] )
1425            mip = str( ll[0] )
1426            self.objectives[mip][thisl] = i
1427            for j in range(len(kk)):
1428                thisv = str( ll[j] )
1429                item.setAttribute( kk[j], thisv )
1430            item.setAttribute( 'uid', str(i) )
1431          elif k == 'experiment':
1432            labmod = False
1433            kk = ['uid','egid','label','description','mip','mcfg','tier','nstart','starty','endy','yps','ensz','ntot','comment']
1434            thisl = str( ll[2] )
1435            ## self.mips.add( str( ll[4] ) )
1436            for j in range(len(kk)):
1437                if kk[j] in ['tier','ensz']:
1438                  if type(ll[j]) == type( 1 ):
1439                    thisv = str( ll[j] )
1440                  else:
1441                    thisv = string.join( [str(x) for x in ll[j]] )
1442                else:
1443                  thisv = str( uniCleanFunc(ll[j]) )
1444                item.setAttribute( kk[j], thisv )
1445          elif k == 'exptgroup':
1446            labmod = False
1447            kk = ['uid','label','tierMin','ntot']
1448            thisl = str( ll[1] )
1449            ##self.exptGrpDict[thisl] = str( ll[1] )
1450            ##self.experimentGrp[thisl] = str( ll[0] )
1451            for j in range(len(kk)):
1452                thisv = str( ll[j] )
1453                item.setAttribute( kk[j], thisv )
1454          elif k == 'var':
1455##- sn; units; description; procnote; procComment; prov
1456##['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0']
1457            thisl = string.replace(string.strip(str( ll[0] ) ), '_', '-' )
1458            thisuuid = str(i)
1459            if not ( self.replItems.has_key( str(i) ) or self.remo.has_key(str(i)) ):
1460              item = self.doc.createElement( 'item' )
1461              item.setAttribute( 'id', 'tmpid.%4.4i' % idk )
1462              item.setAttribute( 'uid', str(i) )
1463              item.setAttribute( 'title', str(ll[1]) )
1464              item.setAttribute( 'sn', str(ll[2]) )
1465              item.setAttribute( 'units', str(ll[3]) )
1466              item.setAttribute( 'description', str(ll[4]) )
1467              item.setAttribute( 'procnote', str(ll[5]) )
1468              item.setAttribute( 'procComment', str(ll[6]) )
1469              item.setAttribute( 'prov', str(ll[7]) )
1470              vare[ll[3]] =  ll[1]
1471              if self.upda.has_key( thisuuid ):
1472                for tag in self.upda[thisuuid]['tags']:
1473                  if tag == 'label':
1474                    thisl = self.upda[thisuuid][tag]
1475                  else:
1476                    item.setAttribute( tag, self.upda[thisuuid][tag] )
1477              if thisl in self.fx.d1:
1478                thisr = self.fx.d1[thisl]
1479                if len(thisr) > 2 and thisr[2] != '':
1480                  item.setAttribute( 'title', str( thisr[2] ) )
1481                if len(thisr) > 3 and thisr[3] != '':
1482                  item.setAttribute( 'description', str( thisr[3] ) )
1483                if thisr[0] != thisl:
1484                  item.setAttribute( 'label', str( thisr[0] ) )
1485                  thisl = str( thisr[0] )
1486                if len(thisr) > 6 and thisr[6] != '':
1487                  item.setAttribute( 'units', str( thisr[6] ) )
1488                print 'INFO.qqq13: updating title and desc %s' % str( thisr )
1489            else: 
1490              print 'Omitting: ',ll
1491              dothis = False
1492          elif k == 'ovar':
1493## 
1494            tab2freq = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
1495       u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
1496       u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
1497       u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
1498       u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
1499       u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
1500       u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
1501       u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'day', \
1502       u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
1503       u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
1504       u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr'}
1505            kk = ['uid', 'comment', 'deflate_level', 'shuffle', 'ok_max_mean_abs', 'flag_meanings', 'type', 'ok_min_mean_abs', 'sn', 'deflate', 'title', 'valid_min', 'cell_methods', 'flag_values', 'cell_measures', 'out_name', 'modeling_realm', 'units', 'cell_methods_xx', 'valid_max', 'positive', 'var', 'mipTable', 'dimensions', 'vid', 'gpid','rowIndex','priority']
1506## uuid; comment; deflate_level; shuffle; ok_max_mean_abs; flag_meanings; type; ok_min_mean_abs; sn; deflate; valid_min; cell_methods; flag_values; cell_measures; out_name; modeling_realm; units; cell_methods_xx; valid_max; positive; var; mipTable; dimensions; vid
1507            ix_gpid = kk.index( 'gpid' )
1508
1509            thisl = string.strip( str( ll[21] ) )
1510            for j in range( min(len(kk),len(ll)) ):
1511              if kk[j] == 'priority':
1512                ll[j] = int(ll[j])
1513               
1514              if j != 21:
1515                item.setAttribute( kk[j], str( ll[j] ) )
1516
1517            if len(ll) < len(kk):
1518              print 'ERROR.015.0001: record length short %s (%s):: %s' % (len(ll),len(kk),ll)
1519
1520            if ll[22][-3:] in ['mon','day','3hr']:
1521              fr = ll[22][-3:]
1522            elif ll[22][-2:] in [ 'yr','fx']:
1523              fr = ll[22][-2:]
1524            else:
1525              fr = tab2freq[ll[22]]
1526   
1527            item.setAttribute( 'frequency', fr )
1528            thisuuid = ll[0]
1529            if self.repl.has_key( thisuuid ):
1530              for tag,old,new in self.repl[thisuuid]:
1531                thisold = item.getAttribute( tag )
1532                assert thisold == old, 'Attempt to replace value which is not present'
1533                item.setAttribute( tag, new )
1534          elif k == 'groupitem':
1535            kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'new', 'gpid', 'vkey', 'vid']
1536            assert len(kk) == len(ll), 'length mismatch, %s  %s' % (len(kk),len(ll))
1537# - group;  table; freq; descriptionEx; shape; levels; tstyle; mask; mip; mip2; uuid; new; vid
1538            ix_gpid = kk.index( 'gpid' )
1539            thisl = string.strip(str( ll[1] ) )
1540            for j in range(len(kk)):
1541              if j != 1:
1542                ##item.setAttribute( kk[j], str( ll[j] ) )
1543                if kk[j] == 'misc':
1544                  item.setAttribute( 'priority', str( ll[j] ) )
1545                else:
1546                  item.setAttribute( kk[j], str( ll[j] ) )
1547            item.setAttribute( 'title', thisl )
1548            if string.find(thisl, ' ') != -1:
1549              thisl = string.split(thisl)[0]
1550            thisuuid = ll[11]
1551
1552            gpid = str(ll[ix_gpid])
1553            if not rq.rqvg.has_key(gpid):
1554              print 'ERROR.015.0010: gpid not found %s' % str(ll)
1555              self.e15_10 += 1
1556            if self.repl.has_key( thisuuid ):
1557              for tag,old,new in self.repl[thisuuid]:
1558                thisold = item.getAttribute( tag )
1559                assert thisold == old, 'Attempt to replace value which is not present'
1560                item.setAttribute( tag, new )
1561##################################
1562          elif k in ['revisedtabitem','requestvar']:
1563#### need to fill gaps in variable groups --- or do better job upstream ##########  !!!!!!!!!!!!!!!!
1564## - table; mip; uuid; priority
1565##
1566## variable group ids pulled through via mapping above .. very messy
1567## still missing some OMIP matches .... OMIP revised tables are not explicitly requested anywhere.
1568##
1569            kk = ['var', 'table', 'mip', 'vid', 'priority']
1570    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
1571
1572            vgid = self.prqv.rqv_vg['%s.%s.%s' % (ll[2],ll[1],ll[0])]
1573            thisuuid = str( uuid.uuid1() )
1574            thisl = string.strip(str( ll[0] ) )
1575            for j in range(len(kk)):
1576              if j != 0 and kk[j] != 'table':
1577                item.setAttribute( kk[j], str( ll[j] ) )
1578            item.setAttribute( 'title', thisl + ' ((isd.005))' )
1579            item.setAttribute( 'uid', thisuuid )
1580            item.setAttribute( 'vgid', vgid )
1581            vid = str( ll[3] )
1582            if self.insert.has_key(thisl) and vid == '__new__':
1583                vid = self.insert[thisl]
1584                item.setAttribute( 'vid', self.insert[thisl] )
1585            if vid[0] == '_':
1586              f = {'6hrPlev':'6hr','Omon':'mon','Amon':'mon'}.get( ll[1], '__' )
1587              if f in self.cmvUidByFL and ll[0] in self.cmvUidByFL[f].a:
1588                if len( self.cmvUidByFL[f].a[ll[0]] ) == 1:
1589                  vid = self.cmvUidByFL[f].a[ll[0]][0]
1590                  item.setAttribute( 'vid', vid )
1591                  print 'INFO.090.08801: variable link corrected, %s' % len( self.cmvUidByFL[f].a[ll[0]] )
1592                else:
1593                  print 'WARN.090.08801: multiple options found, %s' % len( self.cmvUidByFL[f].a[ll[0]] )
1594            if vid[0] == '_':
1595              print 'ERROR.090.08801: bad variable ref [%s]' % vid,ll
1596
1597            if vid in self.fx.d2:
1598               if self.fx.d2[vid][3] == u'replace':
1599                 item.setAttribute( 'vid', str( self.fx.d2[vid][4] ) )
1600                 print 'INFO.qqq11: replacing link in requestVar  %s' % str(ll)
1601               else:
1602                 print 'INFO.qqq22: not replacing link in requestVar  %s' % str(ll)
1603            if vid in self.importWbMods.mmsi.ss:
1604              print 'INFO.046.0001: mip map found: ', self.importWbMods.mmsi.ss[vid]
1605              mm = self.importWbMods.mmsi.ss[vid]
1606              self._editRequestVar01( item, mm, ll )
1607               
1608            did = '%s__%s' % (vid,vgid)
1609            if self.vgcheck.has_key(did) and did[0] != '_':
1610              print 'ERROR.090.09001: Duplicate request ....: ',ll,self.vgcheck[did]
1611              dothis = False
1612            else:
1613              self.vgcheck[did] = ll
1614
1615##################################
1616          elif k == 'requestlink':
1617 ## - uuid; mip; tab; objective; grid; gridreq; comment
1618            kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt', 'opar', 'preset', 'ref', 'refNote', 'refid']
1619            ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','ref', 'refNote', 'refid']
1620            emap = {'uid':'uid'}
1621            mip = string.strip(str( ll[1] ) )
1622            obj = string.strip(str( ll[3] ) )
1623            if mip == "GMMIP":
1624              bits = [ mycc(x) for x in string.split( obj, ' ' ) ]
1625            else:
1626              bits = [ mycc(x) for x in string.split( obj, ',' ) ]
1627            for b in bits:
1628              self.objectiveLinks[mip].a[b].append( str( ll[0] ) )
1629            self.requestlinkuid.add( str(ll[0] ) )
1630            self.rqlPreset[str(ll[0])] = ll[9]
1631            dothis = False
1632       
1633 ##           thisl = string.strip(str( ll[2] ) )
1634##################################
1635          elif k == 'requestitem':
1636 ## - mip; tab; expt; rlid; ny
1637## defer so that cross-check of "expt" can be done .. or scan this earlier ....
1638              kk = ['mip', 'tab', 'expt', 'rlid', 'ny', 'nexmax', 'nenmax', 'nymax','treset']
1639              thisl = mycc( '%s %s' % (ll[0],ll[1]) )
1640              if str( ll[3] ) not in self.rqlPreset:
1641                 print 'ERROR.090.02000: requestlink not found .. ',ll
1642                 preset = '-99'
1643              else:
1644                 preset = str( self.rqlPreset[ str( ll[3] ) ] )
1645              if str( ll[3] ) not in self.requestlinkuid:
1646                print 'SEVERE.005.00005: rlid not found: %s' % str(ll)
1647              for j in range(len(kk)):
1648                if kk[j] == 'ny':
1649                  if ll[j] == '':
1650                    thisv = 0
1651                  else:
1652                    try:
1653                      thisv = str( int(ll[j]) )
1654                    except:
1655                      print 'SEVERE: failed to set "ny": %s' % str(ll)
1656                      thisv = 999
1657                else:
1658                  thisv = str( ll[j] )
1659                if not (kk[j] == 'treset' and thisv in ['None','']):
1660                  item.setAttribute( kk[j], thisv )
1661              item.setAttribute( 'title', '%s, %s, %s' % (ll[0],ll[1],ll[2]) )
1662              item.setAttribute( 'uid', str(i) )
1663              item.setAttribute( 'preset', preset )
1664              ku = str(ll[2])
1665              item.setAttribute( 'esid', self.exptPntUid[ku][0] )
1666              item.setAttribute( 'esidComment', str(self.exptPntUid[ku]) )
1667##################################
1668          elif k in ['requestvargroup','tablesection']:
1669            if k == 'requestvargroup':
1670              kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
1671            else:
1672              kk = ['uid', 'gpid', 'mip', 'label', 'title', 'ref', 'refNote']
1673            thisl = string.replace( str( ll[2] ), '.', '-' )
1674            if str(ll[0]) not in self.varGroupUids:
1675              print 'WARN.077.07707: uid not traced: ',ll
1676            else:
1677              print 'INFO.077.07707: uid traced: ',ll
1678            omitrvg = {'C4MIP-Omon','C4MIP-Oclim','HighResMIP-OImon','HighResMIP-Oclim'}
1679            if thisl in omitrvg:
1680              dothis = False
1681            else:
1682              for j in range(len(kk)):
1683                item.setAttribute( kk[j], str( ll[j] ) )
1684####
1685          if dothis:
1686            if labmod:
1687              if string.find( thisl, '_' ) != -1:
1688              #print 'WARNING: underscore in label', ll
1689                thisl = string.replace( thisl, '_', '-' )
1690              if string.find( thisl, '*' ) != -1:
1691                #print 'WARNING: star in label', ll
1692                thisl = string.replace( thisl, '*', '-' )
1693              if string.find( thisl, '!' ) != -1:
1694              #print 'WARNING: exclamation in label', ll
1695                thisl = string.replace( thisl, '!', '-' )
1696              if string.find( thisl, ' ' ) != -1:
1697              #print 'WARNING: space in label', ll
1698                thisl = string.replace( thisl, ' ', '-' )
1699              if string.find( thisl, ':' ) != -1:
1700              #print 'WARNING: colon in label', ll
1701                thisl = string.replace( thisl, ':', '-' )
1702            item.setAttribute( 'label', thisl )
1703            ff[k][0].appendChild( item )
1704           
1705  def write2(self):
1706    """write sections for cmor variable, request variable, structure, spatial and temporal dimensions"""
1707    spsResets = collections.defaultdict(list)
1708    self.spLab2Uid = {}
1709    for ksect in [ u'spatialshape', u'temporalshape', u'cmorvar', u'structure', u'requestvar', u'requestlink']:
1710    ##for ksect in [ u'cmorvar',  u'spatialshape', u'temporalshape', u'structure']:
1711        dil = self.ff[ksect][0].getElementsByTagName('item')
1712        if ksect != 'requestvar':
1713          for d in dil:
1714            self.ff[ksect][0].removeChild(d)
1715        if ksect == u'cmorvar':
1716          ktable = self.cmvinfo.index('mipTable')
1717          kfreq = self.cmvinfo.index('frequency')
1718          kstr = self.cmvinfo.index('stid')
1719            ##self.spatialDims[rr[0]] = rr[3]
1720          s1 = set()
1721          for r in self.cmv:
1722            if r[0] in s1:
1723              print 'ERROR.090.09005: duplicate key at ',r
1724            s1.add( r[0] )
1725            if len( r[1] ) == 2:
1726              spid = self.spLab2Uid[r[1][0]]
1727              print 'INFO.klklkl: AerChemMIP structure .... ',r[1]
1728            else:
1729              try:
1730                stid = self.strdd[r[1]]
1731              except:
1732                print 'ERROR.999.00099: strdd key not found: %s' % str(r[1])
1733                for k in self.strdd.keys():
1734                  if k[0] == r[1][0]:
1735                    print '*** ',k
1736                raise
1737             
1738            if r[0] in self.fx.d2:
1739              print 'INFO.qqq10: omitting record %s' % str( self.fx.d2[r[0]] )
1740            else:
1741              item = self.doc.createElement( 'item' )
1742              for k in range(len(self.cmvinfo)):
1743                n = self.cmvinfo[k]
1744                if n in self.cmvinfo2:
1745                  if n == 'mipTable' and str(r[k]) == 'CMIP5_Oyr':
1746                    print 'ERROR.047.0002: ',r
1747                  if n == "vid":
1748                    if str(r[k]) == '__var_not_found_012__':
1749                      print 'ERROR.099.00202: bad vid string: %s [%s]' % (r[k],str(r[:3]))
1750                    vid = str(r[k])
1751                  if n == "stid":
1752                    item.setAttribute( n, stid )
1753                  elif n == "label":
1754                    thisl = string.replace( r[k], '_', '' )
1755                    item.setAttribute( n, thisl )
1756                  elif n in ["valid_min","valid_max","ok_max_mean_abs","ok_min_mean_abs"]:
1757                    if str(r[k]) != "" and r[k] not in [None, 'None']:
1758                      if str(r[k]) == "None":
1759                        print 'ERROR.8888.00008: bad valid min/max: ',r[k]
1760                      item.setAttribute( n, str(r[k]) )
1761                  elif n == "frequency":
1762                    fr = freqmap.get( str(r[k]), str(r[k]) )
1763                    item.setAttribute( n, fr )
1764                  elif n == "mipTable":
1765                    tn = tableNameMap.get( str(r[k]), str(r[k]) )
1766                    item.setAttribute( n, tn )
1767                  else:
1768                    item.setAttribute( n, str(r[k]) )
1769
1770### reset table name for OImon ... correcting for frequency as well
1771###
1772              mtable = r[ktable]
1773              if r[ktable] == 'OImon':
1774                if r[kfreq] == 'mon':
1775                    mtable = 'SImon'
1776                    #item.setAttribute( 'mipTable', 'SImon' )
1777                else:
1778                    mtable = 'SIday'
1779                    #item.setAttribute( 'mipTable', 'SIday' )
1780              elif r[ktable] in ['em6hr','em3hr','emDay']:
1781                if stid in self.structInfo:
1782                  if string.find( self.structInfo[stid][1], 'time: point' ) != -1:
1783                    mtable += 'pt'
1784                  if string.find( self.spatialDims[ self.structInfo[stid][2] ], 'longitude' ) == -1:
1785                    mtable += 'Z'
1786                else:
1787                    print 'WARN.090.09999: structure uid not found',stid, r
1788              if mtable != r[ktable]:
1789                item.setAttribute( 'mipTable', mtable )
1790              if str(vid) not in self.importWbMods.vars.d1:
1791 
1792                  if thisl in self.importWbMods.vars.c1 or (thisl[-2:] in ['17','23'] and thisl[:-2] in self.importWbMods.vars.c1):
1793                    if thisl in self.importWbMods.vars.c1:
1794                      thisn = thisl
1795                    else:
1796                      thisn = thisl[:-2]
1797
1798                    if len( self.importWbMods.vars.c1[ thisn ] ) == 1:
1799                      newvid = self.importWbMods.vars.c1[ thisn ][0]
1800                      item.setAttribute( 'vid', newvid )
1801                      print 'INFO.099.00110: bad vid string replaced: %s [%s]' % (newvid,thisl)
1802                    else:
1803                      print 'ERROR.099.00111: ambiguous bad vid string: %s [%s]' % (vid,thisl)
1804                  else:
1805                    print 'ERROR.099.00112: bad vid string: %s [%s]' % (vid,thisl)
1806              thisuid = r[0]
1807              if self.repl.has_key( thisuid ):
1808                for tag,old,new in self.repl[thisuid]:
1809                  thisold = item.getAttribute( tag )
1810                  if thisold != old:
1811                     ##print 'WARN.yyy: Attempt to replace value which is not present'
1812                    print 'WARN.050.00051: Failed attempt to replace values in cmv: %s old:%s new:%s' % (tag,old,new)
1813                  else:
1814                    if tag == 'vid' and new not in self.importWbMods.vars.d1:
1815                        print 'ERROR.050.00052: Attempt to replave values in cmv with invalid vid: %s old:%s new:%s' % (tag,old,new)
1816                    else:
1817                      item.setAttribute( tag, new )
1818                      print 'INFO.050.00050: replacing values in cmv: %s old:%s new:%s' % (tag,old,new)
1819              self.ff[ksect][0].appendChild( item )
1820        elif ksect == u'structure':
1821          ers = {}
1822          for kk in spsResets:
1823            if len( spsResets[kk] ) > 0:
1824              utarg = spsResets[kk][0][0]
1825              for r in spsResets[kk][1:]:
1826                ers[r[0]] = utarg
1827          flds = self.structList[0]._fields
1828          for nt in self.structList:
1829            item = self.doc.createElement( 'item' )
1830            for f in flds:
1831              if f == 'spid' and nt.__dict__[f] in ers:
1832                item.setAttribute( f, ers[ nt.__dict__[f] ] )
1833                print 'INFO.801.00011: updating target spid .... '
1834              else:
1835                item.setAttribute( f, str( nt.__dict__[f] ) )
1836            self.ff[ksect][0].appendChild( item )
1837        elif ksect == u'spatialshape':
1838
1839     ##    self.dimsSpaceInfo = ['uid','label','title','dimensions','levelFlag','levels']
1840          self.spatialDims = {}
1841          for k in self.dimsSpace.keys():
1842            rr = self.dimsSpace[k]
1843            kk = rr[3]
1844            if kk == '':
1845              kk = 'scalar'
1846              rr = list(rr)
1847              rr[3] = 'scalar'
1848            elif kk == 'longitude|latitude|plev':
1849              kk = 'longitude|latitude|plev4'
1850              rr = list(rr)
1851              rr[3] = kk
1852            self.spatialDims[rr[0]] = rr[3]
1853            if kk not in spsResets:
1854              item = self.doc.createElement( 'item' )
1855              for i in range(len(self.dimsSpaceInfo)):
1856                item.setAttribute( self.dimsSpaceInfo[i], str( rr[i] ) )
1857              if rr[3] in self.spsh.ss:
1858                lab,ttl,lf,li = self.spsh.ss[rr[3]]
1859                if trace.SPATIALSHAPE_01:
1860                  print 'INFO.035.0001: new spatial shape label: %s, %s' % (lab, ttl)
1861                if ttl[:4] != 'ssd.':
1862                  item.setAttribute( 'title', ttl )
1863                if len(lab) < 4 or lab[:4] != 'ssd-':
1864                  item.setAttribute( 'label', lab )
1865                item.setAttribute( 'levels', li )
1866                item.setAttribute( 'levelFlag', string.lower(lf) )
1867              else:
1868                print 'ERROR.055.00001: spatial shape record not recognised: %s' % str(rr)
1869              print 'INFO.801.00120: new shape for %s' % str(rr)
1870              thisl = item.getAttribute( 'label' )
1871              assert thisl not in self.spLab2Uid.keys(), 'Duplicate spatial shape label: %s' % thisl
1872              self.spLab2Uid[thisl] = item.getAttribute( 'uid' )
1873              self.ff[ksect][0].appendChild( item )
1874            else:
1875              print 'INFO.801.00121: duplicate shape for %s' % str(rr)
1876            spsResets[kk].append( rr )
1877
1878        elif ksect == u'temporalshape':
1879          for k in self.dimsTime.keys():
1880            rr = self.dimsTime[k]
1881            item = self.doc.createElement( 'item' )
1882            for i in range(len(self.dimsTimeInfo)):
1883              item.setAttribute( self.dimsTimeInfo[i], str( rr[i] ) )
1884            self.ff[ksect][0].appendChild( item )
1885        elif ksect == u'requestvar':
1886          ##kk = ['var', 'table', 'mip', 'vid', 'priority']
1887          kk = ['label', 'table', 'mip', 'vid', 'priority','vgid','title','uid']
1888          kktr = {'vgid':'gpid', 'title':'label'}
1889    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
1890          kkf = 0
1891          for t in self.rqv:
1892            item = self.doc.createElement( 'item' )
1893            ###assert len(t) == len(kk), 'BAD request variable line: %s' % str(t)
1894            for i in range(len(kk)):
1895              k = kktr.get( kk[i], kk[i] )
1896              v = t[  self.rqvinfo.index(k) ]
1897              if k == 'priority':
1898                item.setAttribute( kk[i], str( int(v) ) )
1899              elif kk[i] == 'label':
1900                thisl = string.replace( v, '_', '' )
1901                item.setAttribute( kk[i], thisl )
1902              elif kk[i] == 'title':
1903                if str(v) == 'bsi':
1904                  print 'INFO.999.09900: ',t
1905                item.setAttribute( kk[i], str( v ) + ' ((isd.006))' )
1906              elif kk[i] == 'table':
1907                pass
1908              else:
1909                item.setAttribute( kk[i], str( v ) )
1910
1911            vid = str( t[2] )
1912            if vid in self.fx.d2:
1913               if self.fx.d2[vid][3] == u'replace':
1914                 item.setAttribute( 'vid', str( self.fx.d2[vid][4] ) )
1915                 print 'INFO.qqq12: replacing link in requestVar  %s' % str(t)
1916            if vid in self.importWbMods.mmsi.ss:
1917              print 'INFO.046.0002: mip map found: ', self.importWbMods.mmsi.ss[vid]
1918              mm = self.importWbMods.mmsi.ss[vid]
1919              self._editRequestVar01( item, mm, t )
1920              ##item.setAttribute( 'vid', mm[0].vid2 )
1921              ##if len( mm ) > 1:
1922                ##assert len( mm ) < 3, 'Unable to deal with triple clone'
1923                ##cln = item.cloneNode(True)
1924                ##cln.setAttribute( 'uid', str( uuid.uuid1() ) )
1925                ##cln.setAttribute( 'vid', mm[1].vid2 )
1926                ##self.ff[ksect][0].appendChild( cln )
1927                ##print 'INFO.046.0003: request variable split:', t[1]
1928             
1929            did = '%s__%s' % (t[2],t[3])
1930            if self.vgcheck.has_key(did):
1931              print 'ERROR.090.09002: Duplicate request ....: ',t,self.vgcheck[did]
1932            else:
1933              self.vgcheck[did] = t
1934              self.ff[ksect][0].appendChild( item )
1935              assert len( self.rqvClone.keys() ) > 5, 'rqvClone does not appear to be initialied: %s' % len( self.rqvClone.keys() )
1936              if self.rqvClone.has_key(t[0]):
1937                kkf += 1
1938                for id in self.rqvClone[t[0]]:
1939                  cln = item.cloneNode(True)
1940                  cln.setAttribute( 'vgid', id )
1941                  cln.setAttribute( 'uid', str( uuid.uuid1() ) )
1942                  self.ff[ksect][0].appendChild( cln )
1943                  print 'INFO.090.01010: request variable cloned:', t[1]
1944##
1945######################################################################################
1946##
1947        elif ksect == u'requestlink':
1948 ## - uuid; mip; tab; objective; grid; gridreq; comment
1949            kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt', 'opar', 'preset', 'ref', 'refNote', 'refid']
1950            ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','ref', 'refNote', 'refid']
1951       
1952            thissh = self.skey['requestlink']
1953            for k in thissh:
1954              if k[0] != '_':
1955                ll = thissh[k][:]
1956                thisl = string.strip(str( ll[2] ) )
1957                uid = string.strip(str( ll[0] ) )
1958                item = self.doc.createElement( 'item' )
1959                for j in range(len(kk)):
1960                  thiskk = kk[j]
1961## preset mover to request item .... so it can also be used on a per-experiment basis
1962                  if thiskk != 'preset':
1963                    try:
1964                      if kk[j] == 'comment':
1965                        v = utils_wb.uniCleanFunc( v )
1966                      else:
1967                        v = str( ll[j] )
1968                    except:
1969                      print thisl, kk[j]
1970                      print 'ERROR.099.0001: Failed to convert string '
1971                      print ll
1972                      v = '__error_99_1__'
1973
1974### redirect to new variable group if specified in mappings
1975##
1976                    if kk[j] == 'refid' and self.rvgUidMapping.has_key(v):
1977                        v = self.rvgUidMapping[v]
1978                        print 'INFO.090.00200: variable group reference reset in %s [%s]' % (thisl,uid)
1979
1980                    item.setAttribute( thiskk, v )
1981
1982                item.setAttribute( 'title', thisl )
1983                if self.rqlRedirect.has_key( ll[0] ):
1984                   print 'INFO.088.02020: redirect detected ',ll
1985                   item.setAttribute( 'refid', self.rqlRedirect[ ll[0] ] )
1986                self.ff[ksect][0].appendChild( item )
1987##################################
1988               
1989
1990  def _editRequestVar01( self, item, mm, t ):
1991              item.setAttribute( 'vid', mm[0].vid2 )
1992              item.setAttribute( 'label', mm[0].lab2 )
1993              if len( mm ) > 1:
1994                assert len( mm ) < 3, 'Unable to deal with triple clone'
1995                cln = item.cloneNode(True)
1996                cln.setAttribute( 'uid', str( uuid.uuid1() ) )
1997                cln.setAttribute( 'label', mm[1].lab2 )
1998                self.ff['requestvar'][0].appendChild( cln )
1999                print 'INFO.046.0003: request variable split:', t[1]
2000
2001  def finishExptGrp(self):
2002    """finish exptGroup section and create exptgrouplink section"""
2003    this = self.doc.getElementsByTagName('exptGroup')[0]
2004            ### kk = ['uid','label','tierMin','ntot']
2005    for k in self.exptPntUid.keys():
2006      u,typ = self.exptPntUid[k]
2007##      if not isg:
2008        ##item = self.doc.createElement( 'item' )
2009        ##item.setAttribute( uid, u )
2010    ##this = self.doc.getElementsByTagName('exptGroupLink')[0]
2011    ##dil = this.getElementsByTagName('item')
2012    ##for d in dil:
2013          ##this.removeChild(d)
2014    ##this.appendChild( item )
2015
2016  def reviewExpt(self):
2017    """Prepare cross-linking information to populate requestitem, exptgroup and exptgrouplink"""
2018    sh = shelve.open( '../framework/sh_links/exptMappings', 'r' )
2019    extraMappings={ 'LS3MIP-1, LS3MIP-2':['LmipH', 'LmipF'] }
2020    ks = sorted( self.exptPnt.keys() )
2021    self.exptPntMap = collections.defaultdict( list )
2022    self.exptPntUid = {}
2023    ner = 0
2024    ngr = 0
2025    nmr = 0
2026    nuns = 0
2027    nls = 0
2028    for k0 in ks:
2029      k = string.replace( string.replace( k0, '\n', ' ' ), '  ', ' ')
2030      thisl = None
2031      if sh.has_key(k):
2032        thisl = sh[k]
2033      elif extraMappings.has_key(k):
2034        thisl = extraMappings[k]
2035      else:
2036        print 'ERROR.080.00010: no mapping founds for experiment %s' % k
2037     
2038
2039      if thisl != None:
2040        thisu = None
2041        thisls = set( thisl )
2042        linkType = None
2043        for k2 in thisls:
2044          ok = True
2045          if self.experiments.has_key(k2):
2046            ner += 1
2047            linkType = 'expt'
2048            thisu = self.experiments[k2]
2049          elif self.experimentGrp.has_key(k2):
2050            ngr += 1
2051            thisu = self.experimentGrp[k2]
2052            linkType = 'grp'
2053          elif k2 in self.mips:
2054            nmr += 1
2055            thisu = k2
2056            linkType = 'mip'
2057          else:
2058            ok = False
2059            print 'ERROR.080.00999: target experiment not found: %s [%s]' % (k2,k)
2060          if not ok:
2061            self.exptPntMap[k].append( k2 )
2062##
2063## store uid of expt group to be pointed at.
2064##
2065        if len(thisls) == 1 and thisu != None:
2066          self.exptPntUid[k0] = (thisu, linkType, thisls)
2067        else:
2068          self.exptPntUid[k0] = (str( uuid.uuid1() ), 'list', thisls )
2069          nls += 1
2070      else:
2071          nuns += 1
2072          self.exptPntUid[k0] = (None,None)
2073     
2074    sh.close()
2075    print 'INFO.080.00010: Expt refs: %s, Expt group refs: %s, MIP expt set refs: %s, unset: %s, lists: %s' % (ner,ngr,nmr, nuns, nls)
2076
2077  def reviewObj(self):
2078## review objectives
2079##
2080    ol = []
2081    fnd1 = set()
2082    for m in self.objectives.keys():
2083      not_used = []
2084      used = set()
2085      not_found = []
2086      found = []
2087      alist = ['All','All?','all']
2088      aaa = [self.objectiveLinks[m].a.has_key(x) for x in ['All','All?','all'] ]
2089      us1 = set()
2090      for k in self.objectiveLinks[m].a:
2091        x = None
2092        if k == 'AllExceptPaleorcms':
2093          x = self.objectives[m].keys()
2094          x.pop( x.index( 'Paleorcms' ) )
2095        elif k == 'AllExceptNaturalVariability':
2096          x = self.objectives[m].keys()
2097          x.pop( x.index( 'NaturalVariability' ) )
2098
2099        if x != None:
2100          fnd1.add(k)
2101          for i in x:
2102            used.add(i)
2103            us1.add(i)
2104            for u in self.objectiveLinks[m].a[k]:
2105              ol.append( (m,self.objectives[m][i], u ) )
2106         
2107      allused = (m != 'GMMIP') and any( aaa )
2108      for o in self.objectives[m].keys():
2109        if allused or self.objectiveLinks[m].a.has_key(o):
2110          used.add(o)
2111          for u in self.objectiveLinks[m].a[o]:
2112            ol.append( (m,self.objectives[m][o], u ) )
2113          for k in alist:
2114            if self.objectiveLinks[m].a.has_key(k):
2115              for u in self.objectiveLinks[m].a[k]:
2116                ol.append( (m,self.objectives[m][o], u ) )
2117        elif o not in us1:
2118          not_used.append(o)
2119
2120      for o in self.objectiveLinks[m].a.keys():
2121        if (o in {'All','All?'} and len(self.objectives[m].keys()) > 0 ) or self.objectives[m].has_key(o) or o in fnd1:
2122          found.append(o)
2123        else:
2124          not_found.append(o)
2125      if len(not_used) > 0 or len(not_found) > 0:
2126        print 'WARN.080.00002: %s: OK %s: unused: %s: not found:%s' % (m,str(used),str(not_used),str(not_found))
2127      else:
2128        print 'INFO.080.00002: %s: all objectives matched' % m
2129    self.objList = ol
2130
2131
2132  def finish(self):
2133## varChoice section
2134    self.choices()
2135##
2136    self.reviewObj()
2137##
2138##
2139    if len( self.prqv.addExrqvg )  > 0:
2140      this = self.doc.getElementsByTagName('requestVarGroup')[0]
2141      kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
2142      for k in self.prqv.addExrqvg:
2143         item = self.doc.createElement( 'item' )
2144         ll = self.prqv.exrqvg[k]
2145         thisl = string.replace( str( ll[2] ), '.', '-' )
2146         for j in range(len(kk)):
2147              if kk[j] == 'refNote':
2148                item.setAttribute( kk[j], str( ll[j] ) + '((isd.004))' )
2149              else:
2150                item.setAttribute( kk[j], str( ll[j] ) )
2151         this.appendChild( item )
2152##
2153##  objectiveLink
2154##
2155    this = self.doc.getElementsByTagName('objectiveLink')[0]
2156    dil = this.getElementsByTagName('item')
2157    for d in dil:
2158          this.removeChild(d)
2159    for t in self.objList:
2160       item = self.doc.createElement( 'item' )
2161       item.setAttribute( 'label', t[0] )
2162       item.setAttribute( 'oid', t[1] )
2163       item.setAttribute( 'rid', t[2] )
2164       thisuuid = str( uuid.uuid1() )
2165       item.setAttribute( 'uid', thisuuid )
2166       this.appendChild( item )
2167##
2168## remarks
2169##
2170    this = self.doc.getElementsByTagName('remarks')[0]
2171    dil = this.getElementsByTagName('item')
2172    for d in dil:
2173          this.removeChild(d)
2174
2175    txt = self.doc.toprettyxml(indent='\t', newl='\n', encoding=None)
2176    if self.schemaMode == 'dreq2':
2177      ofn = 'trial2_20150831.xml'
2178    else:
2179      ofn = 'trial_20150831.xml'
2180    oo = open( ofn, 'w' )
2181    lines = string.split( txt, '\n' )
2182    for line in lines:
2183      l = utils_wb.uniCleanFunc( string.strip(line) )
2184      if empty.match(l):
2185        continue
2186      else: 
2187        oo.write(l + '\n')
2188    oo.close()
2189
2190  def choices(self):
2191    """Populate the 'varChoice' section, using the information in the 'choices' dictionary in 'choicecfg'"""
2192
2193    ccfg = choiceCfg.choices( self )
2194    self.ccfg = ccfg
2195##
2196##  choices
2197##
2198    this = self.doc.getElementsByTagName('varChoice')[0]
2199    dil = this.getElementsByTagName('item')
2200    for d in dil:
2201          this.removeChild(d)
2202    for k in ccfg.choices.keys():
2203       item = self.doc.createElement( 'item' )
2204       cc = ccfg.choices[k]
2205       for kk in cc.keys():
2206         item.setAttribute( kk, cc[kk] )
2207       this.appendChild( item )
2208       print 'INFO.zzz.00008: Appending ',cc[kk]
2209
2210    this = self.doc.getElementsByTagName('varChoiceLinkR')[0]
2211    dil = this.getElementsByTagName('item')
2212    for d in dil:
2213          this.removeChild(d)
2214    for cc in ccfg.varChoiceLnk:
2215       item = self.doc.createElement( 'item' )
2216       print 'INFO.zzz', cc
2217       for i in range( len( ccfg.varChoiceLnkInfo ) ):
2218         item.setAttribute( ccfg.varChoiceLnkInfo[i], cc[i] )
2219       this.appendChild( item )
2220
2221    this = self.doc.getElementsByTagName('varChoiceLinkC')[0]
2222    dil = this.getElementsByTagName('item')
2223    for d in dil:
2224          this.removeChild(d)
2225    for cc in ccfg.varChoiceLnkCfg:
2226       item = self.doc.createElement( 'item' )
2227       for i in range( len( ccfg.varChoiceLnkCfgInfo ) ):
2228         item.setAttribute( ccfg.varChoiceLnkCfgInfo[i], cc[i] )
2229       this.appendChild( item )
2230
2231    ##self.varChoiceLnkCfgInfo = [ 'uid', 'label', 'title', 'vid', 'cid', 'cfgid', 'cfg'
2232
2233  def importRepl(self,rfile='uuidreplace.csv'):
2234    for l in open(rfile).readlines():
2235      bits = string.split( string.strip(l), '\t' )
2236      assert len(bits) == 7, 'Could not parse item replacement file'
2237      self.repl[ bits[3] ].append( (bits[2],bits[0],bits[1] ) )
2238      self.replItems[bits[0]] = bits[1]
2239
2240  def importRemove(self,rfile='uuidremove.csv'):
2241    for l in open(rfile).readlines():
2242      self.remo[ string.strip(l) ] = 1
2243
2244  def importUpdate(self,rfile='uuidupdate.csv'):
2245    for l in open(rfile).readlines():
2246      bits = string.split( string.strip(l), '\t' )
2247      tgs = string.strip( bits[2] )
2248      if string.find( tgs, ' ' ) == -1:
2249        tags = [tgs,]
2250      else:
2251        tags = string.split( tgs )
2252      self.upda[ bits[0] ] =  {'comment':bits[1], 'tags':tags, 'label':bits[3], 'title':bits[4] }
2253
2254  def importInsert(self,rfile='uuidinsert.csv'):
2255    for l in open(rfile).readlines():
2256      bits = string.split( string.strip(l), '\t' )
2257      if bits[0] == 'unique':
2258         self.insert[bits[1]] = bits[3]
2259
2260mode = 'dreq2'
2261sampleXml = '../framework/out/%sSample.xml' % mode
2262from scansh import rq
2263
2264##cmip5GrpLk = collections.defaultdict( dict )
2265##for k in rq.cmip5Grps.keys():
2266  ##bits = string.split(k,'_')
2267  ##tab = bits[0]
2268  ##for v in rq.cmip5Grps[k]:
2269    ##cmip5GrpLk[tab][v] = k
2270
2271m = main(sampleXml, rq,run=True, schemaMode=mode, doRepl=True)
2272
2273ks = m.prqv.err0010.keys()
2274ks.sort()
2275for k in ks:
2276    print 'ERROR.001.0010: variable group not identified: %s [%s]' % (k,m.prqv.err0010[k])
2277ks = m.prqv.err0020.keys()
2278ks.sort()
2279for k in ks:
2280    print 'ERROR.001.0020: variable group not identified: %s [%s]' % (k,m.prqv.err0020[k])
Note: See TracBrowser for help on using the repository browser.