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

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

updates

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      s1 = {'vstar, wstar, fy, fz, acceldivf[utenddivf], accelogw[utendogw], accelnogw[utendnogw], diabdrag[utenddiabdrag]'}
403      self.varGroupSs2 = collections.defaultdict( cls_s1 )
404      self.varGroupSubset = collections.defaultdict( dict )
405      kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','preset', 'ref', 'refNote', 'refid']
406##
407## preset is in the wrong place here ..... should be on the linked experiment group ...
408## 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....
409##
410# create lists of variables wanted from groups, indexed by uid of group and requestLink
411      thissh = self.skey['requestlink']
412      for k in thissh:
413        if k[0] != '_':
414          rr = thissh[k][:]
415          if rr[8] in s0:
416            vl0 = map( string.strip, string.split( rr[8], ',' ) )
417            print 'INFO.077.07060: rr[8] matched .... ', rr[8]
418          elif rr[7] in s0:
419            print 'INFO.077.07070: rr[7] matched .... ', rr[7]
420            vl0 = map( string.strip, string.split( rr[7], ',' ) )
421          elif rr[8] in s1:
422            print 'INFO.077.07071: rr[7] matched .... ', rr[8]
423            vl0 = map( string.strip, string.split( rr[8], ',' ) )
424            ##for i in range( len( vl0) ):
425              ##if string.find( vl0[i], '[' ) != -1:
426                ##a,b = string.split( vl0[i], '[' )
427                ##vl0[i] = (a,b[:-1])
428          else:
429            vl0 = None
430
431          if vl0 != None:
432            vl = set()
433            for v in vl0:
434              if string.find( v, '[' ) != -1:
435                bits = string.split( v, '[' )
436                vl.add( (bits[0],bits[1][:-1]) )
437              else:
438                vl.add(v)
439            m = str(rr[1])
440
441            self.varGroupSubset[str(rr[-1])][rr[0]] = vl
442            self.varGroupSs2[str(rr[-1])].a[(m,tuple(vl))].append(rr[0])
443            print 'INFO.077.07080: ',m,vl, rr[-1]
444###
445### get full list of variables for each variable group
446###
447      thissh = self.skey['requestvar']
448      kk = ['label', 'table', 'mip', 'vid', 'priority','vgid','title','uid']
449      varGroupFull = collections.defaultdict( dict )
450      for k in thissh:
451        if k[0] != '_':
452          ll = thissh[k][:]
453          vgid = self.prqv.rqv_vg['%s.%s.%s' % (ll[2],ll[1],ll[0])]
454          if ll[1][:5] == 'CFMIP':
455             print 'INFO.802.00001: ',ll, vgid in self.varGroupSubset.keys()
456          if vgid in self.varGroupSubset.keys():
457             varGroupFull[vgid][ll[0]] = k
458
459      for ll in self.rqv:
460          vgid = ll[  self.rqvinfo.index('gpid') ]
461          if vgid in self.varGroupSubset.keys():
462             varGroupFull[vgid][ll[1]] = ll[0]
463###
464### check that all variable groups covered
465###
466      nf = []
467      for k in self.varGroupSubset.keys():
468       if not (k in varGroupFull):
469         nf.append(k)
470      if len(nf) != 0:
471        for k in nf:
472          for k2 in self.varGroupSubset[k].keys():
473            print 'ERROR.080.06000: Variable group not found: ',k,k2,self.varGroupSubset[k][k2]
474##
475## some missing groups ...
476## appear to be missing MIP tables, e.g. CCMI_monthly
477## CCMI_monthly exists, but has no variables linking to it.
478##
479        print 'ERROR.080.06000:  %s %s' % (len(nf),len(varGroupFull.keys()))
480
481
482      shrvg = self.skey['requestvargroup']
483      for k in self.varGroupSs2:
484        if k not in varGroupFull:
485          print 'ERROR.080.06001: not in varGroupFull: %s [%s] %s' % (k,str(self.varGroupSs2[k].a.keys()), str( shrvg[k] ) )
486
487      self.rqvClone = collections.defaultdict( list )
488      self.rqvgrpExtra = []
489      self.rqlRedirect = {}
490      for k in varGroupFull:
491        for m,k2 in self.varGroupSs2[k].a:
492          ok1 = []
493          for i in k2:
494            i1 = i
495            if type(i) in [type(''),type(u'')]:
496              if string.find( i, 'and ' ) != -1:
497                i1 = string.split(i)[-1]
498                print 'INFO.099.09090: split i:',i,i1
499              ok1.append( varGroupFull[k].has_key(i1) )
500            elif type(i) == type( () ) and len(i) == 2:
501              ok1.append( varGroupFull[k].has_key(i[0]) or varGroupFull[k].has_key(i[1]) )
502            else:
503              print 'ERROR.080.06055: skipping unrecogised element: ',i
504              ok1.append( False )
505
506          ok = all( ok1 )
507          if not ok:
508            k2m = [  k2[i]  for i in range(len(k2)) if not ok1[i] ]
509            print 'ERROR.080.06060: not all vars found [%s] %s' % ( k, str(k2m) )
510          else:
511##
512## create new variable group and update link(s)
513##
514            gpid = str( uuid.uuid1() )
515            for rqlid in self.varGroupSs2[k].a[(m,k2)]:
516              self.rqlRedirect[rqlid] = gpid
517              ##kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
518## e.g. ['4db2f616-6d9e-11e5-b29a-ac72891c3257', 'DAMIP', u'DynVar-day', u'DAMIP: DynVar-day', 'new', u'DynVar.DYVR_daily']
519            ll =  rq.rqvg[k][:]
520            ll[0] = gpid
521            ll[2] += '-subset'
522            ll[-1] += ' (subset)'
523            self.rqvgrpExtra.append( ll )
524            print 'INFO.080.06060: subset validated, ', ll
525            for i in k2:
526##
527## set a marker to clone request variable record, with new group id
528##
529              i1 = i
530              if type(i) == type( () ) and len(i) == 2:
531                if varGroupFull[k].has_key(i[0]):
532                  i1 = i[0]
533                else:
534                  i1 = i[1]
535              elif string.find( i, 'and ' ) != -1:
536                i1 = string.split(i)[-1]
537              self.rqvClone[varGroupFull[k][i1]].append( gpid )
538
539  def finishRequestLink(self):
540    this = self.doc.getElementsByTagName('requestVarGroup')[0]
541## e.g. ['4db2f616-6d9e-11e5-b29a-ac72891c3257', 'DAMIP', u'DynVar-day', u'DAMIP: DynVar-day', 'new', u'DynVar.DYVR_daily']
542    kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
543    for ll in self.rqvgrpExtra:
544         item = self.doc.createElement( 'item' )
545         for j in range(len(kk)):
546              if kk[j] == 'refNote':
547                item.setAttribute( kk[j], str( ll[j] ) + '((isd.010))' )
548              else:
549                item.setAttribute( kk[j], str( ll[j] ) )
550         this.appendChild( item )
551##
552
553  def prep01(self):
554#### prepare some links for request variables
555    addex = True
556    self.prqv = ivg.prepRequestVar(addex)
557    self.prqv.run()
558
559  def prep(self,rq):
560## keys here match section element names in schema
561    #for k in [ 'var','ovar','groupitem', 'revisedtabitem']:
562## lists for 3 new sections
563### uuid, spid, tmid, cell_methods, cell_measures, description, procNote, prov
564    structure = [] 
565    self.structInfo = {}
566### uuid, label, dimensions, shape, levels, levelFlag
567    spatialshp = []
568### uuid, label, dimension, tstyle
569    temporalshp = []
570### cmor variables
571    self.cmv = []
572    self.cmvUidByFL = collections.defaultdict( cls_s1 )
573    self.cmvs = set()
574    self.cmvinfo = ('uid','stid','label','title','description','vid', \
575                    'deflate_level', 'shuffle', 'ok_max_mean_abs', 'flag_meanings', 'type', 'ok_min_mean_abs',  \
576                    'deflate', 'valid_min', 'flag_values', 'modeling_realm', 'valid_max', 'positive', 'mipTable', \
577                    'prov', 'provNote', 'frequency', 'rowIndex', 'coordinates','defaultPriority')
578    self.cmvinfo2 = ('uid','stid','label','title','description','vid', \
579                    'deflate_level', 'shuffle', 'ok_max_mean_abs', 'type', 'ok_min_mean_abs',  \
580                    'deflate', 'valid_min', 'modeling_realm', 'valid_max', 'positive', 'mipTable', \
581                    'prov', 'provNote', 'frequency', 'rowIndex', 'defaultPriority')
582    self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
583
584
585    thissh = self.skey['var']
586    self.varUidByName = self.importWbMods.vars.c1
587    ##self.varUidByName = collections.defaultdict( list )
588    if self.newImport:
589      oo = open('refDefaultP.txt', 'w' )
590      for k in thissh:
591         if k[0] != '_':
592##['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0']
593            thisuuid = str(k)
594            self.defaultP[thisuuid] = thissh[k][-1]
595            oo.write( '%s\t%s\t%s\t%s\n' % (k, thissh[k][0], thissh[k][2], thissh[k][-1] ) )
596            ##self.varUidByName[thissh[k][0]].append( thisuuid )
597      oo.close()
598    else:
599      ## ['label', 'title', 'description', 'procComment', 'procnote', 'prov', 'provmip', 'sn', 'units', 'uid','defaultp']
600      self.vars = collections.defaultdict( list )
601      self.vars1 = collections.defaultdict( list )
602      for uid in self.importWbMods.vars.d1:
603        self.defaultP[uid] = self.importWbMods.vars.d1[uid][-1]
604## collection indexed by short_name
605        self.vars1[self.importWbMods.vars.d1[uid][0]].append( uid )
606## collection indexed by standard_name
607        self.vars[self.importWbMods.vars.d1[uid][7]].append( uid )
608
609### request variables
610    self.rqv = []
611    self.realmByVar = collections.defaultdict( list )
612    for ksect in [ 'ovar','groupitem']:
613      thissh = self.skey[ksect]
614      if ksect == 'ovar':
615            setu1 = set()
616            tab2freq = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
617                  u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
618                  u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
619                  u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
620                  u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
621                  u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
622                  u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
623                  u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'day', \
624                  u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
625                  u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
626                  u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr'}
627            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']
628            id = kk.index('dimensions')
629            ivid = kk.index('vid')
630            thisnt = collections.namedtuple( 'ovar', kk )
631            ov = []
632            dset = set()
633            ds2 = set()
634            ovuu = {}
635            for k in thissh:
636              if k[0] != '_':
637                rr = thissh[k][:]
638                if rr[id] == 's|c|a|l|a|r':
639                  print 'ERROR.060.0001: bad dimension string detected and corrected: %s' % rr[id]
640                  rr[id] = 'scalar'
641                if string.find( rr[23], 'plevs' ) != -1:
642                   print 'INFO.qqqq01: ',rr[21:24]
643                rr[23] = string.replace(rr[23], 'plevs', 'plev17')
644                tt = thisnt._make( rr ) 
645                if tt.uid in setu1:
646                  print 'ERROR.099.0002: duplicate uuid: %s: %s' % (uuid,str(rr))
647                if str(tt.vid) == '__var_not_found_012__':
648                  print 'ERROR.099.00102: bad vid string: %s [%s]' % (tt.vid,tt.out_name)
649                       
650                if str(tt.vid) not in self.importWbMods.vars.d1:
651                  if tt.out_name in self.importWbMods.vars.c1:
652                    if len( self.importWbMods.vars.c1[ tt.out_name ] ) == 1:
653                      rr[ivid] = self.importWbMods.vars.c1[ tt.out_name ][0]
654                      tt = thisnt._make( rr ) 
655                      print 'INFO.099.00103: bad vid string replaced: %s [%s]' % (tt.vid,tt.out_name)
656                    else:
657                      print 'ERROR.099.00104: ambiguous bad vid string: %s [%s]' % (tt.vid,tt.out_name)
658                  else:
659                    print 'ERROR.099.00105: bad vid string: %s [%s]' % (tt.vid,tt.out_name)
660                setu1.add(tt.uid)
661                ov.append( tt )
662                dset.add( ov[-1].dimensions )
663                ds2.add( (tt.dimensions,tt.cell_methods,tt.cell_measures,tt.flag_values, tt.flag_meanings) )
664                ovuu[tt.uid] = tt
665                if rr[22][-3:] in ['mon','day','3hr']:
666                  fr = rr[22][-3:]
667                elif rr[22][-2:] in [ 'yr','fx']:
668                  fr = rr[22][-2:]
669                else:
670                  fr = tab2freq[rr[22]]
671   
672                prov = '%s ((isd.003))' % tt.mipTable
673                if tt.mipTable[:4] == 'OMIP':
674                  prov = 'CMIP6 [OMIP] ((isd.001))'
675                elif string.find( tt.mipTable, '_' ) != -1:
676                  prov = '%s [%s] ((isd.002))' % tuple( string.split( tt.mipTable, '_' ) )
677
678                if tt.var[:5] == 'xx..ccmi_':
679                  pass
680                else:
681                  lab = tt.var
682                  if lab in {'*','include Oyr 3D tracers'}:
683                    lab = '-copy-'
684##
685## insert conditional on redundant tables here ...
686##
687                  if tt.mipTable in redundantTables:
688                    if tt.mipTable not in reportedRedundantTables:
689                      print 'INFO.000.11111: redundant table spotted: ',tt.mipTable
690                      reportedRedundantTables.add( tt.mipTable )
691                  else:
692                    if tt.uid in self.cmvs:
693                       print 'ERROR.090.09010: duplicate cmv uid :',tt.__dict__
694                    self.cmvs.add( tt.uid )
695                    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, \
696                      tt.deflate_level, tt.shuffle, tt.ok_max_mean_abs, tt.flag_meanings, tt.type, tt.ok_min_mean_abs, \
697                      tt.deflate, tt.valid_min, tt.flag_values, tt.modeling_realm, tt.valid_max, tt.positive, tt.mipTable, \
698                      prov, tt.ssect, fr, tt.rowIndex, '',int(tt.priority)) )
699                    self.realmByVar[ lab ].append( tt.modeling_realm )
700                    if string.strip( tt.gpid ) == '':
701                       print 'ERROR.090.0990: blank gpid: ',lab,tt.mipTable
702                    vgid = tt.gpid
703                    if tt.mipTable[:4] == 'OMIP':
704                       m,t = string.split( tt.mipTable, '.' )
705                       vgid = self.prqv.getvgid( [None,t,m] )
706                       if vgid[0] != '_':
707                         if vgid != tt.gpid:
708                           print 'INFO.090.0990: link repare:',tt.gpid,lab,tt.mipTable,vgid
709                    self.rqv.append( (str( uuid.uuid1() ),lab, tt.uid, vgid, tt.priority,tt.mipTable,tt.mipTable) )
710                    if vgid not in self.varGroupUids:
711                      print 'ERROR.099.09901: bad vgid: ',self.rqv[-1]
712    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
713            self.dsort( dset )
714            print self.dsortdd[ksect][0].keys()
715
716      elif ksect == 'groupitem':
717            kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'priority', 'mip', 'uid', 'rowIndex', 'new', 'gpid', 'vkey', 'vid']
718            thisnt = collections.namedtuple( 'groupitem', kk + ['cmorv',] )
719            il = kk.index( 'levels' )
720            iu = kk.index( 'uid' )
721            ixvid = kk.index( 'vid' )
722            ixvar = kk.index( 'var' )
723            ixp = kk.index( 'priority' )
724            dset = set()
725            dsgpi = set()
726            gi = []
727            s1 = set()
728            sm = set()
729            varsets = []
730            nov = 0
731            setu = set()
732            for k in thissh.keys():
733              if k[0] != '_':
734                rr = thissh[k][:]
735                if trace.GROUPITEM_ta and rr[ixvar] == 'ta':
736                  print 'INFO.045.00004: groupitem: ',rr
737
738##
739## convert floats back to integer
740##
741                if type(rr[ixp]) == type(1.):
742                  rr[ixp] = int(rr[ixp])
743##
744## split variable, create 2nd record at 23 levels.
745##
746                if rr[iu] in setu:
747                  print 'ERROR.099.0001: duplicate uuid in varGroups ... %s:: %s' % (uuid,str(rr))
748                if rr[iu] in setu1:
749                  print 'ERROR.099.0003: duplicate uuid in varGroups/ovar ... %s:: %s' % (uuid,str(rr))
750                setu.add(rr[iu])
751                if rr[il] in  {u'17 (or 23 )', u'17 (or 23)', u'17 (or23)', u'10/17/23'}:
752                  if rr[il] == u'10/17/23':
753                     lev0 = 10
754                     levsp = [17,23]
755                  else:
756                     lev0 = 17
757                     levsp = [23,]
758                  rr[ixp] = 1
759                  p = 1
760                  for lp in levsp:
761                    p += 1
762                    rr0 = rr + [rr[1] + str(lp),]
763                    rr0[ixp] = p
764                    rr0[il] = lp
765                    rr0[iu] = str( uuid.uuid1() )
766                    tt = thisnt._make( rr0 )
767                    if str(tt.vid) == '__var_not_found_012__':
768                      print 'ERROR.099.00104: bad vid string: %s [%s]' % (tt.vid,tt.var)
769                    gi.append( tt )
770                    varsets.append( (rr0[iu], 2, rr[iu], 1, 'variables at multiple vertical resolutions' ) )
771                  rr[il] = lev0
772                  tt = thisnt._make( rr + [rr[1] + str(lev0),] )
773                elif rr[il] == u'Model levels or 27Plevs':
774                  rr0 = rr + [rr[1] + '27',]
775                  rr0[il] = 27
776                  rr0[iu] = str( uuid.uuid1() )
777                  if str(rr0[ixvid]) == '__var_not_found_012__':
778                    if str(rr0[ixvar]) in self.varUidByName:
779                      if len( self.varUidByName[rr0[ixvar]] ) == 1:
780                        rr0[ixvid] = self.varUidByName[rr0[ixvar]][0]
781                  tt = thisnt._make( rr0 )
782                  if str(tt.vid) == '__var_not_found_012__':
783                    print 'ERROR.099.00105: bad vid string: %s [%s]' % (tt.vid,tt.var)
784                  gi.append( tt )
785                  rr[il] = 'all'
786                  tt = thisnt._make( rr + [rr[1],] )
787                  varsets.append( (rr0[iu], 0, rr[iu], 0, 'Variables on model levels or 27 pressure levels' ) )
788                else:
789##
790## this point ... to mark HighResMIP 7 levels as distinct from CFMIP.
791## enough information in "mip" tag of tt record
792##
793                  if type( rr[il] ) == type(1.):
794                    if rr[il] == 7. and rr[10] == 'HighResMIP':
795                      print 'INFO.qqq03:',rr[il],rr
796                      rr[5] = rr[5] + '*'
797                  if str(rr[ixvid]) == '__var_not_found_012__':
798                    ok = False
799                    if str(rr[ixvar]) in self.varUidByName:
800                      if len( self.varUidByName[rr[ixvar]] ) == 1:
801                        rr[ixvid] = self.varUidByName[rr[ixvar]][0]
802                        print 'INFO.099.00106: correcting vid for %s' % rr[ixvar]
803                        ok = True
804                    if not ok:
805                        print 'WARN.099.00106: error in vid for %s not corrected' % rr[ixvar]
806                  tt = thisnt._make( rr + [rr[1],] )
807                  if str(tt.vid) == '__var_not_found_012__':
808                    print 'ERROR.099.00106: bad vid string: %s [%s]' % (tt.vid,tt.var)
809                 
810                if str(tt.mip) != 'OMIP':
811                  gi.append( tt )
812                  sm.add( tt.mask )
813
814            print '####### masks: ',sm
815            smdd = {}
816            dsn = {'floating ice shelf':u'floating ice sheet', u'ocean':u'sea' }
817            d1 = {u'land':(False,'area: mean where land'), \
818                  u'grounded ice sheet':(True,'area: mean where grounded_ice_sheet'), \
819                  u'ice sheet':(True,'area: mean where ice_sheet'), \
820                  u'floating ice sheet':(True,'area: mean where floating_ice_sheet'), \
821                  u'floating ice shelf':(True,'area: mean where floating_ice_sheet'),
822                  u'sea':(False,'area: mean where sea') }
823            for s in sm:
824              if s in  ['', u'none',u'Southern hemisphere', u'Northern hemisphere']:
825                smdd[s] = (False,'')
826              else:
827                smdd[s] = d1[ dsn.get( s,s ) ]
828
829            setu = set()
830
831            ccchk = ivg.checkCmv(gi)
832            nrep = 0
833
834            for tt in gi:
835                gr = 'a'
836                if tt.mip == 'OMIP' or any( [string.find(tt.table,i) != -1 for i in ['Omon','Oyr','Oclim','OImon','Ocean'] ] ):
837                  gr = 'o'
838                if self.varsxx != None:
839                  if tt.cmorv in self.varsxx:
840                    sss = set()
841                    for k in self.varsxx[tt.cmorv]:
842                      sss.add(self.skey['var'][k][-1] )
843                    sss = list(sss)
844                    if len(sss) == 1:
845                      if sss[0] == 'ocean':
846                        gr = 'o'
847                      elif sss[0] == 'atmos':
848                        gr = 'a'
849                    print 'INFO:lllw:', tt.cmorv, sss, gr
850                if tt.cmorv == 'sltbasin':
851                   print 'INFO.llll: ',tt,gr
852##
853## adding label for mip here messes up referencing later ...
854##
855                dset.add( (tt.shape,tt.levels,tt.tstyle,gr) )
856                dsgpi.add( (tt.shape,tt.levels,tt.tstyle,gr,smdd[tt.mask], 'None', 'None') )
857### need to check where variables are, perhaps, refering to "ovar"
858            ##kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'rowIndex', 'new', 'gpid', 'vkey', 'vid']
859                prov = '%s [%s]' % (tt.mip,tt.group)
860                provNote = ''
861                lab = tt.cmorv
862                if lab in {'*','include Oyr 3D tracers'}:
863                  lab = '-copy-'
864                elif lab == 'wap (omega)':
865                  lab = 'wap'
866                  provNote = 'wap (omega)'
867                lab = string.replace( string.strip(lab), '_', '-' )
868                if tt.uid in setu:
869                     print 'SEVERE[1]: duplicate uuid: ',tt.__dict__
870                setu.add( tt.uid )
871                fr = freqmap.get( tt.freq, tt.freq )
872                ntab = 'em%s' % string.capwords( fr )
873               
874                if ovuu.has_key(tt.vid):
875                  tt1 = ovuu[tt.vid]
876                  if tt1.modeling_realm == 'seaIce':
877                    ntab = 'OImon'
878                  if tt.priority in [1,2,3]:
879                    p = tt.priority
880                  else:
881                    p = int(tt1.priority)
882                  thisrealm = tt1.modeling_realm
883                  if gr == 'o' and thisrealm == 'atmos':
884                    thisrealm = 'ocean'
885                  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, \
886                    tt1.deflate_level, tt1.shuffle, tt1.ok_max_mean_abs, tt1.flag_meanings, tt1.type, tt1.ok_min_mean_abs, \
887                    tt1.deflate, tt1.valid_min, tt1.flag_values, thisrealm, tt1.valid_max, tt1.positive, ntab, \
888                    prov, provNote, tt.freq, tt.rowIndex, '', int(p)) 
889                  self.realmByVar[ lab ].append( thisrealm )
890                  thisrqv = [str( uuid.uuid1() ),lab, tt.uid, tt.gpid, p, tt.mip, tt.group]
891                  nov += 1
892                else:
893                  thisrealm = ''
894                  if realmdefix.has_key( prov ):
895                    thisrealm = realmdefix[prov]
896                  else:
897                    print 'WARN:070.00001: realm not found for %s,%s' % (lab,prov)
898                  if gr == 'o' and thisrealm == 'atmos':
899                    thisrealm = 'ocean'
900
901                  if thisrealm == 'seaIce':
902                    ntab = 'OImon'
903
904                  if tt.priority in [1,2,3]:
905                    p = tt.priority
906                  elif  self.defaultP.get( tt.vid, 102) in [1,2,3]:
907                    p = self.defaultP.get( tt.vid, 102)
908                  else:
909                    p = 1
910                    print 'WARN:070.00002: priority defaulting to 1 for %s,%s' % (lab,prov)
911                  thiscmv = (tt.uid, (tt.shape,tt.levels,tt.tstyle,gr,smdd[tt.mask], 'None', 'None'), lab, '__from %s' % tt.table, tt.descriptionEx, tt.vid, \
912                    0, 0, 0, 0, '', 0, \
913                    0,0,0, thisrealm, 0, '', ntab, \
914                    prov, provNote, tt.freq, tt.rowIndex, '', str(p)) 
915                  self.realmByVar[ lab ].append( thisrealm )
916
917                  thisrqv = [str( uuid.uuid1() ),lab, tt.uid, tt.gpid, p, tt.mip, tt.group] 
918                if trace.GROUPITEM_ta and lab  == 'ta':
919                    print 'INFO.045.00005: groupitem: ',thisrqv
920
921
922                if ccchk.uidReplace.has_key(thiscmv[0]):
923                  nrep += 1
924                  thisrqv[2] = ccchk.uidReplace[thiscmv[0]]
925                else:
926                  self.cmv.append( thiscmv )
927                self.rqv.append( thisrqv )
928                if self.rqv[-1][3] not in self.varGroupUids:
929                      print 'ERROR.099.09902: bad vgid: ',self.rqv[-1]
930## Variables marked with shape '?' from PMIP are actually defined by OMIP ....
931                if tt.shape == '?':
932                  print 'ERROR.801.00001: shape not set: %s, %s, %s' % ( tt.shape,tt.mip,tt.var)
933
934            ##['', 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']
935            self.dsort( dset,mode=ksect )
936            print 'INFO.088.00001: nrep=%s' % nrep
937            print 'INFO.088.00002: nov=%s [%s]' % (nov,len(gi))
938
939
940    for c in self.cmv:
941      u,v,f = (c[0],c[2],c[21])
942      self.cmvUidByFL[f].a[v].append( u ) 
943
944#######################################################################################
945#################
946    std = set()
947    ssd = set()
948    etd = {}
949    esd = {}
950    tshp = { 'time':['time-mean','Temporal mean'], 'time1':['time-point','Instantaneous value (i.e. synoptic or time-step value)'], \
951             'time2':['climatoglogy','Climatological mean'], \
952             '':['None','No temporal dimensions ... fixed field'], 'xxxx':['unknown','dimension not recognised'] }
953
954    for ksect in [ 'ovar','groupitem']:
955#### create structure list for spatial and temporal dimensions
956      for t in self.dsortdd[ksect][0].keys():
957        tdim, tt = self.dsort_u1( self.dsortdd[ksect][0][t], self.dsortdd[ksect][1] )
958
959        std.add( tdim )
960        ssd.add( tt )
961        ##ssd.add( (sdim,lfl,nl) )
962
963    for s in std:
964       label, description = tshp.get(s,tshp['xxxx'])
965       u = str( uuid.uuid1() )
966       etd[s] = (u,label,description,s)
967    kk = 0
968    for s in ssd:
969       d,lfl,nl = s
970       u = str( uuid.uuid1() )
971       kk+=1
972       lab = 'ssd-%3.3i' % kk
973       description = 'ssd.%3.3i' % kk
974       esd[s] = (u,lab,description,d,lfl,nl)
975
976    esd['Y-na'] = (str( uuid.uuid1() ),'extra','extra','latitude','false',1)
977    self.dimsTime = etd
978    self.dimsTimeInfo = ['uid','label','title','dimensions']
979    self.dimsSpace = esd
980    self.dimsSpaceInfo = ['uid','label','title','dimensions','levelFlag','levels']
981       
982    sshp = set()
983    eshp = set()
984    ll = []
985    lls = ivg.structureList()
986    nt_dims = collections.namedtuple( 'dims', ['uid','label','spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','description','procNote','prov'] )
987    kk = 0
988    strdd = {}
989    ee3 = {}
990    for dims,cmet,cmea,flgv, flgm in ds2:
991        tdim, tt = self.dsort_u1( self.dsortdd['ovar'][0][dims], self.dsortdd['ovar'][1] )
992        d1,odim,d2,crd = self.dsortdd['ovar'][0][dims]
993        sdim,lfl,nl = tt
994        u = str( uuid.uuid1() )
995        spid = esd[tt][0]
996        tmid = etd[tdim][0]
997        kk += 1
998        label = 'str-%3.3i' % kk
999        proc = ''
1000        prov = 'CMIP5/OMIP'
1001        desc = ''
1002        print 'INFO.zzz01: ',dims
1003        t0 = (dims,cmet,cmea,flgv,flgm)
1004        if cmet == 'None':
1005          cmet = ''
1006        if cmea == 'None':
1007          cmea = ''
1008        if flgv == 'None':
1009          flgv = ''
1010        if flgm == 'None':
1011          flgm = ''
1012        t1 = (dims,cmet,cmea,flgv,flgm)
1013        u = lls.add( [u,label,spid,tmid, odim, crd, cmet, cmea, flgv, flgm, desc, proc, prov] )
1014        self.structInfo[u] = (label,cmet)
1015        strdd[t0] = u
1016        strdd[t1] = u
1017         
1018        ##nt =  nt_dims._make( [u,label,spid,tmid, odim, crd, cmet, cmea, flgv, flgm, desc, proc, prov] )
1019        ##tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1020        ##if ee3.has_key( tt ):
1021            ##u = ee3[tt]
1022        ##else:
1023            ##ee3[tt] = u
1024            ##ll.append( nt )
1025        ##ll.append( nt_dims._make( [u,label,spid,tmid, odim, crd, cmet, cmea, flgv, flgm, desc, proc, prov] ) )
1026
1027    ttt = [ {u'Instantaneous (end of year)', 'instantaneous', 'point', 'Synoptic', u'synoptic', u'time: point'},
1028        {'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(), {''}]
1029    cmetl = ['time: point', 'time: mean', 'time: mean within years time: mean over years ', '']
1030    ee1 = {}
1031    for shp,lvls,sty,gr,tmsk, flgv, flgm in dsgpi:
1032        t = (shp,lvls,sty,gr)
1033        tdim, tt = self.dsort_u1( self.dsortdd['groupitem'][0][t], self.dsortdd['groupitem'][1] )
1034        d1,odim,d2,crd = self.dsortdd['groupitem'][0][t]
1035        print 'INFO.099: ',d1,odim,d2,crd
1036        tflm, msk = tmsk
1037        sdim,lfl,nl = tt
1038        u = str( uuid.uuid1() )
1039        spid = esd[tt][0]
1040        tmid = etd[tdim][0]
1041        cmea = 'area: areacell%s' % gr
1042        cmet = ''
1043        for i in range(4):
1044          if sty in ttt[i]:
1045            cmet = cmetl[i]
1046        if cmet == '':
1047          cmet = msk
1048        elif msk != '':
1049          cmet += ' ' + msk
1050        kk += 1
1051        label = 'str-%3.3i' % kk
1052        proc = ''
1053        prov = 'CMIP5, endorsed MIPs'
1054        desc = ''
1055        dims = tt[0]
1056        if tdim != '':
1057          dims += '|' + tdim
1058        if strdd.has_key( (dims,cmet,cmea,'','') ):
1059          u = strdd[ (dims,cmet,cmea,'','') ]
1060          print 'INFO.zzz03: ',tt, tdim
1061        elif ee1.has_key( (tmid, spid, odim, cmet, cmea, crd) ):
1062          u = ee1[(tmid, spid, odim, cmet, cmea, crd)]
1063          print 'INFO.zzz04: ', tt, tdim
1064        else:
1065          print 'INFO.zzz02: ',tt, tdim
1066          u = lls.add( [u,label,spid,tmid, odim, crd, cmet, cmea, '', '', desc, proc, prov]  )
1067          ##nt =  nt_dims._make( [u,label,spid,tmid, odim, crd, cmet, cmea, '', '', desc, proc, prov] )
1068          ##tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1069          ##if ee3.has_key( tt ):
1070            ##u = ee3[tt]
1071          ##else:
1072            ##ee3[tt] = u
1073            ##ll.append( nt )
1074           
1075          ee1[(tmid, spid, odim, cmet, cmea, crd)] = u
1076        strdd[(shp,lvls,sty,gr,tmsk,flgv,flgm)] = u
1077        self.structInfo[u] = (label,cmet)
1078
1079    ##nt_dims = collections.namedtuple( 'dims', ['uid','label','spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','description','procNote','prov'] )
1080    cc = collections.defaultdict( list )
1081    for nt in lls.ll:
1082      tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1083      cc[tt].append( nt.uid )
1084    ks = [k for k in cc.keys() if len( cc[k] ) > 1]
1085    if len( ks ) > 0:
1086      print 'DUPLICATE STRUCTURES'
1087      for k in ks:
1088        print 'DUPLICATE: ',k,len(cc[k])
1089     
1090    self.structList = lls.ll
1091    self.strdd = strdd
1092    oo = open( 'test.csv', 'w' )
1093    for l in ll:
1094      assert l.uid in self.structInfo, 'SEVERE: structure uid not in lookup ... %s' %  str( l.__dict__)
1095      oo.write( '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,\n' % l )
1096    oo.close()
1097
1098  def addAerChem(self):
1099    import importExtra
1100    lc = importExtra.loadAerChem()
1101    es = {}
1102    et = {}
1103    for l in self.dimsSpace.keys():
1104      print self.dimsSpace[l]
1105      assert self.dimsSpace[l][1] not in es, 'Duplicate spatial dimension label: %s' % self.dimsSpace[l][1]
1106      es[self.dimsSpace[l][1]] = l
1107    for l in self.dimsTime.keys():
1108      print self.dimsTime[l]
1109      assert self.dimsTime[l][1] not in et, 'Duplicate spatial dimension label: %s' % self.dimsTime[l][1]
1110      et[self.dimsTime[l][1]] = l
1111    nt_acv = collections.namedtuple( 'acv', ['sn','title','label', 'units', 'description', 'subsect', 'freq', 'splab', 'tm' ] )
1112    for t in lc.cc2.keys():
1113      nn = 0
1114      for v in lc.cc2[t].a:
1115        v1 = v
1116        if v not in self.vars1:
1117          print 'INFO.kkkkk: AerChem Var missing: %s, %s' % (t,v)
1118          if string.replace( v, '_', '') in self.vars1:
1119            v1 = string.replace( v, '_', '')
1120            print 'INFO.kkkkk: AerChem %s found' % (v1)
1121        else:
1122          nn += 1
1123        tt = nt_acv._make( lc.cc2[t].a[v][0] )
1124        thisrealm = 'unset'
1125        thiscmv = (uuid.uuid1(), (tt.splab,tt.tm), tt.label, 'AerChemMIP', tt.description, self.vars1[v1][0], '','','','','float','','','','',"aero",'','','','AerChemMIP','',tt.freq, 0, '', 1)
1126        self.cmv.append( thiscmv )
1127      print 'INFO.kkkkk: AerChem Vars found: %s: %s' % (t,nn)
1128                  ##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, \
1129                    ##tt1.deflate_level, tt1.shuffle, tt1.ok_max_mean_abs, tt1.flag_meanings, tt1.type, tt1.ok_min_mean_abs, \
1130                    ##tt1.deflate, tt1.valid_min, tt1.flag_values, thisrealm, tt1.valid_max, tt1.positive, ntab, \
1131                    ##prov, provNote, tt.freq, tt.rowIndex, '', int(p))
1132
1133  def dsort_u1(self,eed,sde):
1134        tdim = eed[2]
1135        sdim = eed[0]
1136        nl = sde[sdim]
1137        lfl = 'true'
1138        if nl == -1:
1139          lfl = 'false'
1140          nl = 0
1141        elif nl == -2:
1142          nl = 1
1143          pass
1144        return (tdim, (sdim,lfl,nl) )
1145
1146
1147  def dsort( self, dset, mode='ovar' ):
1148      """Sort the dimensions string into spatial, temporal and other sections,
1149       returns a dictionary of tuples: spatial dimensions, other, temporal, coords and a 2nd, keyyed on spatial dimensions with a level count indicator.  """
1150      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}
1151      odims = {'sza5','vegtype','scatratio','dbze','typepdec','vgidx','tau'}
1152      dl = sorted( list(dset) )
1153      if mode == 'ovar':
1154        eed = {}
1155        sss = [set(),set(),set(),set()]
1156        for s in dl:
1157          if s[:4] == 'time':
1158            bits = ['',s[4:]]
1159          else:
1160            bits = string.split(s, '|time', maxsplit=1 )
1161          if len(bits) == 1:
1162            ts = ''
1163          else:
1164            ts = 'time'
1165
1166          b0 = bits[0]
1167          b1 = ''
1168          bb = string.split(bits[0],'|')
1169          if bb[-1] in odims:
1170            if bb[-1] == 'tauxxx':
1171                b0 = bits[0][:-4]
1172                ts = 'tau|time'
1173            else:
1174              b0 = string.join( bb[:-1], '|' )
1175              b1 = bb[-1]
1176           
1177          if len(bits) == 1:
1178              tup = (b0,b1,'','')
1179          elif len(bits) == 2:
1180              b2 = string.split( bits[1], '|', maxsplit=1 )
1181              if len(b2) == 2:
1182                  tup = (b0,b1, ts + b2[0], b2[1])
1183              else:
1184                  tup = (b0,b1, ts + bits[1], '')
1185          eed[s] = tup
1186          for k in range(4):
1187            sss[k].add(tup[k])
1188
1189        lcount = {}
1190        for s in sss[0]:
1191          bits = string.split( s, '|' )
1192          nl = -2
1193          thisb = None
1194          for b in bits:
1195            if vdims.has_key(b):
1196              assert nl == -2, 'Duplicate vertical level count in %s' % s
1197              nl = vdims[b]
1198              thisb = b
1199          lcount[s] = nl
1200          if nl == -1 and s == 'latitude|basin':
1201            print 'SEVERE: error in level deduction'
1202            print s, bits, nl, thisb
1203            raise
1204      else:
1205        ## input is a set of tuples,  shape, levels, tstyle, o/a
1206        ## aim is to extract spatial, other, temporal dimensions + coords.
1207        sss = [set(),set(),set()]
1208        ttt = [ (u'Instantaneous (end of year)', 'instantaneous', 'point', 'Synoptic', u'synoptic', u'time: point'),
1209        ('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'), (), ('',)]
1210        ttdd = {}
1211        kkk = ['time1','time','time2','']
1212        for i in range(4):
1213          for k in ttt[i]:
1214            ttdd[k] = kkk[i]
1215
1216        ##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',] }
1217        dds = {'2D':'XYT', 'XY':'XYT', '':'?', '2D ':'XYT', 'XYZ':'XYZT', } 
1218## 'K'?? 'XYK'
1219        dd = {'XKT':('latitude|basin','','time','',False), \
1220             'XYZKT':('longitude|latitude|%s','effectRad','time','',True), \
1221             'XYZT':('longitude|latitude|%s','','time','',True), \
1222             'XYZT*':('longitude|latitude|%st','','time','',True), \
1223              'KZT':('alevel','spectband','time','',False), \
1224              'XYT':('longitude|latitude','','time','',False), \
1225              'XYKT':('longitude|latitude','angle','time','',False), \
1226              'YZT':('latitude|%s','','time','',True), \
1227              'XYK':('longitude|latitude','snowband','time','',False), \
1228              'K':('sistraits','','time','',False), \
1229              'scalar':('','','time','',False), \
1230              'ZST1':('alevel','site','time','',False), \
1231              'BasinYT':('latitude|basin','','time','',False), \
1232              '?':( '?', '?','?','?',False)
1233             }
1234             
1235        for d in dl:
1236          for k in range(3):
1237            sss[k].add( d[k] )
1238        ls0 = set()
1239        ls1 = set()
1240##
1241## sort shapes
1242##
1243        for s in sss[0]:
1244          if not dd.has_key( dds.get(s,s) ):
1245            print 'NO SOLUTION FOUND FOR SHAPE: "%s"' % s
1246          else:
1247            tt = dd[dds.get(s,s)]
1248            if tt[-1]:
1249              ls0.add( s )
1250##
1251## look at shapes which require additional information about vertical coord
1252##
1253        for d in dl:
1254          if d[0] in ls0:
1255             ls1.add( d[1] )
1256
1257        lset = {'soil levels':'sdepth', 'all model levels above 400hPa':'alevel'} 
1258        lsdd = {}
1259        for l in ls1:
1260          ii = 0
1261          if l in ['all','all*','all model levels']:
1262            ii = -1
1263            this = '%slevel' 
1264          elif lset.has_key(l):
1265            ii = -1
1266            this = lset[l]
1267          elif l == '':
1268            ii = -2
1269            this = l
1270          else:
1271            ii = int( float(l) )
1272            if ii in [40,16]:
1273              this = 'alt%s' % ii
1274            elif ii > 1.5:
1275              if ii > 35:
1276                ii = 39
1277              this = 'plev%s' % ii
1278            else:
1279              this = ''
1280          lsdd[l] = (ii,this)
1281##['', 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]
1282             
1283        lcount = {}
1284        eed = {}
1285        for d in dl:
1286          s = d[0]
1287          if not dd.has_key( dds.get(s,s) ):
1288            print 'NO SOLUTION FOUND FOR SHAPE: "%s"' % s
1289          else:
1290            tt = dd[dds.get(s,s)]
1291            if tt[-1]:
1292              n,zz = lsdd[d[1]]
1293              if len(zz) > 0 and zz[0] == '%':
1294                zz = zz % d[3]
1295              sc = tt[0] % zz
1296              if sc[-1] == "|":
1297                print 'ERROR.080.05000: Bad dimension found %s [%s] %s %s' % (sc,str(tt), str((n,zz)), str(d)  )
1298            else:
1299              sc = tt[0]
1300              if (string.find( sc, 'alevel' ) != -1) or (string.find( sc, 'olevel' ) != -1):
1301                n = -1
1302              else:
1303                n = -2
1304
1305          lcount[sc] = n
1306          if n == -1 and sc == 'latitude|basin':
1307            print 'SEVERE [2]: error in level deduction'
1308            print sc, tt[0], tt[-1], n
1309            raise
1310          print 'INFO:qqq05: ',d, sc, tt, ttdd[d[2]]
1311          eed[d] = (sc,tt[1],ttdd[d[2]],tt[3])
1312      self.dsortdd[mode] = (eed,lcount)
1313
1314  def run(self,rq):
1315
1316    xx = self.doc.getElementsByTagName( 'main' )
1317    assert len(xx) == 1, 'Expecting one element named "main", found %s' % len(xx)
1318    main = xx[0]
1319    ## main = self.doc.childNodes[0]
1320    xsn = []
1321    ff = {}
1322    for c in main.childNodes:
1323      tag = c.nodeName
1324      if tag != '#text':
1325        xsn.append(tag)
1326        il = []
1327        for i in c.childNodes:
1328          if i.nodeName == 'item':
1329            il.append(i)
1330        xx = dict( il[0].attributes.items() )
1331        ff[string.lower(tag)] = (c,xx)
1332   
1333    print xsn
1334    print ff.keys()
1335    self.ff = ff
1336    ##        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()]:
1337        ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'ref', 'refNote', 'refid']
1338        ##kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
1339        ##i = rq.rqvg[k]
1340       
1341        ##self.eern[i[ixrn]].append( i[0] )
1342        ##k2 = '%s__%s' % (i[ixrn-1],i[ixrn])
1343        ##if self.eern2.has_key( k2 ):
1344           ##dups.append( (k2,k,self.eern2[k2]) )
1345        ##self.eern2[k2] = i[0]
1346        ##assert i[0] == k, 'Bad key/uuid'
1347
1348    ##assert len( dups ) == 0, 'Duplicate refs: %s, %s' % (str(dups),str(map( lambda x: rq.rqvg[x[1]], dups )) )
1349       
1350## keys here match section element names in schema
1351    sectlist = [ 'experiment','exptgroup','objective','requestlink', 'requestitem','requestvargroup','tablesection' ]
1352    ## dec 2015 -- removing 'var' from this list
1353    if self.schemaMode != 'dreq2':
1354      sectlist = ['ovar','groupitem','revisedtabitem'] + sectlist
1355    else:
1356      sectlist.append( 'requestvar' )
1357
1358    for k in sectlist:
1359      thissh = self.skey[k]
1360## set labmod False for section in which label coercion is not wanted
1361      labmod = True
1362      lll = []
1363      for i in thissh.keys():
1364        if i[0] != '_':
1365          lll.append(i)
1366      idk = 0
1367      if len(lll) > 0:
1368##
1369## remove example items, xcept where this has been done in previous function
1370##
1371        if k not in ['xxxx']:
1372          dil = ff[k][0].getElementsByTagName('item')
1373          for d in dil:
1374            ff[k][0].removeChild(d)
1375
1376        vare = {}
1377        for i in lll:
1378          ll = map( uniCleanFunc, thissh[i] )
1379          assert len(ll) == len( thissh[i] ), 'Lost list elements after uniClean'
1380          idk += 1
1381#################################################################
1382######### NEED TO CLEAN THIS IF ITEMS FROM OTHER SECTIONS ARE FILTERED
1383#######################################################################
1384          dothis = True
1385          if k != 'var':
1386            item = self.doc.createElement( 'item' )
1387
1388          if k == 'objective':
1389 ## - mip; tab; expt; rlid; ny
1390            labmod = False
1391            kk = ['mip', 'label', 'title', 'description']
1392            ##thisl = string.replace(string.strip(str( ll[1] ) ), '-', ' ')
1393## camelcase this label.
1394            ##thisl = string.replace( string.capwords( thisl ), ' ', '' )
1395            thisl = mycc( ll[1] )
1396            mip = str( ll[0] )
1397            self.objectives[mip][thisl] = i
1398            for j in range(len(kk)):
1399                thisv = str( ll[j] )
1400                item.setAttribute( kk[j], thisv )
1401            item.setAttribute( 'uid', str(i) )
1402          elif k == 'experiment':
1403            labmod = False
1404            kk = ['uid','egid','label','description','mip','mcfg','tier','nstart','starty','endy','yps','ensz','ntot','comment']
1405            thisl = str( ll[2] )
1406            ## self.mips.add( str( ll[4] ) )
1407            for j in range(len(kk)):
1408                if kk[j] in ['tier','ensz']:
1409                  if type(ll[j]) == type( 1 ):
1410                    thisv = str( ll[j] )
1411                  else:
1412                    thisv = string.join( [str(x) for x in ll[j]] )
1413                else:
1414                  thisv = str( uniCleanFunc(ll[j]) )
1415                item.setAttribute( kk[j], thisv )
1416          elif k == 'exptgroup':
1417            labmod = False
1418            kk = ['uid','label','tierMin','ntot']
1419            thisl = str( ll[1] )
1420            ##self.exptGrpDict[thisl] = str( ll[1] )
1421            ##self.experimentGrp[thisl] = str( ll[0] )
1422            for j in range(len(kk)):
1423                thisv = str( ll[j] )
1424                item.setAttribute( kk[j], thisv )
1425          elif k == 'var':
1426##- sn; units; description; procnote; procComment; prov
1427##['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0']
1428            thisl = string.replace(string.strip(str( ll[0] ) ), '_', '-' )
1429            thisuuid = str(i)
1430            if not ( self.replItems.has_key( str(i) ) or self.remo.has_key(str(i)) ):
1431              item = self.doc.createElement( 'item' )
1432              item.setAttribute( 'id', 'tmpid.%4.4i' % idk )
1433              item.setAttribute( 'uid', str(i) )
1434              item.setAttribute( 'title', str(ll[1]) )
1435              item.setAttribute( 'sn', str(ll[2]) )
1436              item.setAttribute( 'units', str(ll[3]) )
1437              item.setAttribute( 'description', str(ll[4]) )
1438              item.setAttribute( 'procnote', str(ll[5]) )
1439              item.setAttribute( 'procComment', str(ll[6]) )
1440              item.setAttribute( 'prov', str(ll[7]) )
1441              vare[ll[3]] =  ll[1]
1442              if self.upda.has_key( thisuuid ):
1443                for tag in self.upda[thisuuid]['tags']:
1444                  if tag == 'label':
1445                    thisl = self.upda[thisuuid][tag]
1446                  else:
1447                    item.setAttribute( tag, self.upda[thisuuid][tag] )
1448              if thisl in self.fx.d1:
1449                thisr = self.fx.d1[thisl]
1450                if len(thisr) > 2 and thisr[2] != '':
1451                  item.setAttribute( 'title', str( thisr[2] ) )
1452                if len(thisr) > 3 and thisr[3] != '':
1453                  item.setAttribute( 'description', str( thisr[3] ) )
1454                if thisr[0] != thisl:
1455                  item.setAttribute( 'label', str( thisr[0] ) )
1456                  thisl = str( thisr[0] )
1457                if len(thisr) > 6 and thisr[6] != '':
1458                  item.setAttribute( 'units', str( thisr[6] ) )
1459                print 'INFO.qqq13: updating title and desc %s' % str( thisr )
1460            else: 
1461              print 'Omitting: ',ll
1462              dothis = False
1463          elif k == 'ovar':
1464## 
1465            tab2freq = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
1466       u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
1467       u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
1468       u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
1469       u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
1470       u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
1471       u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
1472       u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'day', \
1473       u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
1474       u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
1475       u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr'}
1476            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']
1477## 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
1478            ix_gpid = kk.index( 'gpid' )
1479
1480            thisl = string.strip( str( ll[21] ) )
1481            for j in range( min(len(kk),len(ll)) ):
1482              if kk[j] == 'priority':
1483                ll[j] = int(ll[j])
1484               
1485              if j != 21:
1486                item.setAttribute( kk[j], str( ll[j] ) )
1487
1488            if len(ll) < len(kk):
1489              print 'ERROR.015.0001: record length short %s (%s):: %s' % (len(ll),len(kk),ll)
1490
1491            if ll[22][-3:] in ['mon','day','3hr']:
1492              fr = ll[22][-3:]
1493            elif ll[22][-2:] in [ 'yr','fx']:
1494              fr = ll[22][-2:]
1495            else:
1496              fr = tab2freq[ll[22]]
1497   
1498            item.setAttribute( 'frequency', fr )
1499            thisuuid = ll[0]
1500            if self.repl.has_key( thisuuid ):
1501              for tag,old,new in self.repl[thisuuid]:
1502                thisold = item.getAttribute( tag )
1503                assert thisold == old, 'Attempt to replace value which is not present'
1504                item.setAttribute( tag, new )
1505          elif k == 'groupitem':
1506            kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'new', 'gpid', 'vkey', 'vid']
1507            assert len(kk) == len(ll), 'length mismatch, %s  %s' % (len(kk),len(ll))
1508# - group;  table; freq; descriptionEx; shape; levels; tstyle; mask; mip; mip2; uuid; new; vid
1509            ix_gpid = kk.index( 'gpid' )
1510            thisl = string.strip(str( ll[1] ) )
1511            for j in range(len(kk)):
1512              if j != 1:
1513                ##item.setAttribute( kk[j], str( ll[j] ) )
1514                if kk[j] == 'misc':
1515                  item.setAttribute( 'priority', str( ll[j] ) )
1516                else:
1517                  item.setAttribute( kk[j], str( ll[j] ) )
1518            item.setAttribute( 'title', thisl )
1519            if string.find(thisl, ' ') != -1:
1520              thisl = string.split(thisl)[0]
1521            thisuuid = ll[11]
1522
1523            gpid = str(ll[ix_gpid])
1524            if not rq.rqvg.has_key(gpid):
1525              print 'ERROR.015.0010: gpid not found %s' % str(ll)
1526              self.e15_10 += 1
1527            if self.repl.has_key( thisuuid ):
1528              for tag,old,new in self.repl[thisuuid]:
1529                thisold = item.getAttribute( tag )
1530                assert thisold == old, 'Attempt to replace value which is not present'
1531                item.setAttribute( tag, new )
1532##################################
1533          elif k in ['revisedtabitem','requestvar']:
1534#### need to fill gaps in variable groups --- or do better job upstream ##########  !!!!!!!!!!!!!!!!
1535## - table; mip; uuid; priority
1536##
1537## variable group ids pulled through via mapping above .. very messy
1538## still missing some OMIP matches .... OMIP revised tables are not explicitly requested anywhere.
1539##
1540            kk = ['var', 'table', 'mip', 'vid', 'priority']
1541    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
1542
1543            vgid = self.prqv.rqv_vg['%s.%s.%s' % (ll[2],ll[1],ll[0])]
1544            thisuuid = str( uuid.uuid1() )
1545            thisl = string.strip(str( ll[0] ) )
1546            for j in range(len(kk)):
1547              if j != 0 and kk[j] != 'table':
1548                item.setAttribute( kk[j], str( ll[j] ) )
1549            item.setAttribute( 'title', thisl + ' ((isd.005))' )
1550            item.setAttribute( 'uid', thisuuid )
1551            item.setAttribute( 'vgid', vgid )
1552            vid = str( ll[3] )
1553            if self.insert.has_key(thisl) and vid == '__new__':
1554                vid = self.insert[thisl]
1555                item.setAttribute( 'vid', self.insert[thisl] )
1556            if vid[0] == '_':
1557              f = {'6hrPlev':'6hr','Omon':'mon','Amon':'mon'}.get( ll[1], '__' )
1558              if f in self.cmvUidByFL and ll[0] in self.cmvUidByFL[f].a:
1559                if len( self.cmvUidByFL[f].a[ll[0]] ) == 1:
1560                  vid = self.cmvUidByFL[f].a[ll[0]][0]
1561                  item.setAttribute( 'vid', vid )
1562                  print 'INFO.090.08801: variable link corrected, %s' % len( self.cmvUidByFL[f].a[ll[0]] )
1563                else:
1564                  print 'WARN.090.08801: multiple options found, %s' % len( self.cmvUidByFL[f].a[ll[0]] )
1565            if vid[0] == '_':
1566              print 'ERROR.090.08801: bad variable ref [%s]' % vid,ll
1567
1568            if vid in self.fx.d2:
1569               if self.fx.d2[vid][3] == u'replace':
1570                 item.setAttribute( 'vid', str( self.fx.d2[vid][4] ) )
1571                 print 'INFO.qqq11: replacing link in requestVar  %s' % str(ll)
1572               else:
1573                 print 'INFO.qqq22: not replacing link in requestVar  %s' % str(ll)
1574            if vid in self.importWbMods.mmsi.ss:
1575              print 'INFO.046.0001: mip map found: ', self.importWbMods.mmsi.ss[vid]
1576              mm = self.importWbMods.mmsi.ss[vid]
1577              self._editRequestVar01( item, mm, ll )
1578               
1579            did = '%s__%s' % (vid,vgid)
1580            if self.vgcheck.has_key(did) and did[0] != '_':
1581              print 'ERROR.090.09001: Duplicate request ....: ',ll,self.vgcheck[did]
1582              dothis = False
1583            else:
1584              self.vgcheck[did] = ll
1585
1586##################################
1587          elif k == 'requestlink':
1588 ## - uuid; mip; tab; objective; grid; gridreq; comment
1589            kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt', 'opar', 'preset', 'ref', 'refNote', 'refid']
1590            ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','ref', 'refNote', 'refid']
1591            emap = {'uid':'uid'}
1592            mip = string.strip(str( ll[1] ) )
1593            obj = string.strip(str( ll[3] ) )
1594            if mip == "GMMIP":
1595              bits = [ mycc(x) for x in string.split( obj, ' ' ) ]
1596            else:
1597              bits = [ mycc(x) for x in string.split( obj, ',' ) ]
1598            for b in bits:
1599              self.objectiveLinks[mip].a[b].append( str( ll[0] ) )
1600            self.requestlinkuid.add( str(ll[0] ) )
1601            self.rqlPreset[str(ll[0])] = ll[9]
1602            dothis = False
1603       
1604 ##           thisl = string.strip(str( ll[2] ) )
1605##################################
1606          elif k == 'requestitem':
1607 ## - mip; tab; expt; rlid; ny
1608## defer so that cross-check of "expt" can be done .. or scan this earlier ....
1609              kk = ['mip', 'tab', 'expt', 'rlid', 'ny', 'nexmax', 'nenmax', 'nymax','treset']
1610              thisl = mycc( '%s %s' % (ll[0],ll[1]) )
1611              if str( ll[3] ) not in self.rqlPreset:
1612                 print 'ERROR.090.02000: requestlink not found .. ',ll
1613                 preset = '-99'
1614              else:
1615                 preset = str( self.rqlPreset[ str( ll[3] ) ] )
1616              if str( ll[3] ) not in self.requestlinkuid:
1617                print 'SEVERE.005.00005: rlid not found: %s' % str(ll)
1618              for j in range(len(kk)):
1619                if kk[j] == 'ny':
1620                  if ll[j] == '':
1621                    thisv = 0
1622                  else:
1623                    try:
1624                      thisv = str( int(ll[j]) )
1625                    except:
1626                      print 'SEVERE: failed to set "ny": %s' % str(ll)
1627                      thisv = 999
1628                else:
1629                  thisv = str( ll[j] )
1630                if not (kk[j] == 'treset' and thisv in ['None','']):
1631                  item.setAttribute( kk[j], thisv )
1632              item.setAttribute( 'title', '%s, %s, %s' % (ll[0],ll[1],ll[2]) )
1633              item.setAttribute( 'uid', str(i) )
1634              item.setAttribute( 'preset', preset )
1635              ku = str(ll[2])
1636              item.setAttribute( 'esid', self.exptPntUid[ku][0] )
1637              item.setAttribute( 'esidComment', str(self.exptPntUid[ku]) )
1638##################################
1639          elif k in ['requestvargroup','tablesection']:
1640            if k == 'requestvargroup':
1641              kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
1642            else:
1643              kk = ['uid', 'gpid', 'mip', 'label', 'title', 'ref', 'refNote']
1644            thisl = string.replace( str( ll[2] ), '.', '-' )
1645            if str(ll[0]) not in self.varGroupUids:
1646              print 'WARN.077.07707: uid not traced: ',ll
1647            else:
1648              print 'INFO.077.07707: uid traced: ',ll
1649            omitrvg = {'C4MIP-Omon','C4MIP-Oclim','HighResMIP-OImon','HighResMIP-Oclim'}
1650            if thisl in omitrvg:
1651              dothis = False
1652            else:
1653              for j in range(len(kk)):
1654                item.setAttribute( kk[j], str( ll[j] ) )
1655####
1656          if dothis:
1657            if labmod:
1658              if string.find( thisl, '_' ) != -1:
1659              #print 'WARNING: underscore in label', ll
1660                thisl = string.replace( thisl, '_', '-' )
1661              if string.find( thisl, '*' ) != -1:
1662                #print 'WARNING: star in label', ll
1663                thisl = string.replace( thisl, '*', '-' )
1664              if string.find( thisl, '!' ) != -1:
1665              #print 'WARNING: exclamation in label', ll
1666                thisl = string.replace( thisl, '!', '-' )
1667              if string.find( thisl, ' ' ) != -1:
1668              #print 'WARNING: space in label', ll
1669                thisl = string.replace( thisl, ' ', '-' )
1670              if string.find( thisl, ':' ) != -1:
1671              #print 'WARNING: colon in label', ll
1672                thisl = string.replace( thisl, ':', '-' )
1673            item.setAttribute( 'label', thisl )
1674            ff[k][0].appendChild( item )
1675           
1676  def write2(self):
1677    """write sections for cmor variable, request variable, structure, spatial and temporal dimensions"""
1678    spsResets = collections.defaultdict(list)
1679    self.spLab2Uid = {}
1680    for ksect in [ u'spatialshape', u'temporalshape', u'cmorvar', u'structure', u'requestvar', u'requestlink']:
1681    ##for ksect in [ u'cmorvar',  u'spatialshape', u'temporalshape', u'structure']:
1682        dil = self.ff[ksect][0].getElementsByTagName('item')
1683        if ksect != 'requestvar':
1684          for d in dil:
1685            self.ff[ksect][0].removeChild(d)
1686        if ksect == u'cmorvar':
1687          ktable = self.cmvinfo.index('mipTable')
1688          kfreq = self.cmvinfo.index('frequency')
1689          kstr = self.cmvinfo.index('stid')
1690          s1 = set()
1691          for r in self.cmv:
1692            if r[0] in s1:
1693              print 'ERROR.090.09005: duplicate key at ',r
1694            s1.add( r[0] )
1695            if len( r[1] ) == 2:
1696              spid = self.spLab2Uid[r[1][0]]
1697              print 'INFO.klklkl: AerChemMIP structure .... ',r[1]
1698            else:
1699              try:
1700                stid = self.strdd[r[1]]
1701              except:
1702                print 'ERROR.999.00099: strdd key not found: %s' % str(r[1])
1703                for k in self.strdd.keys():
1704                  if k[0] == r[1][0]:
1705                    print '*** ',k
1706                raise
1707             
1708            if r[0] in self.fx.d2:
1709              print 'INFO.qqq10: omitting record %s' % str( self.fx.d2[r[0]] )
1710            else:
1711              item = self.doc.createElement( 'item' )
1712              for k in range(len(self.cmvinfo)):
1713                n = self.cmvinfo[k]
1714                if n in self.cmvinfo2:
1715                  if n == 'mipTable' and str(r[k]) == 'CMIP5_Oyr':
1716                    print 'ERROR.047.0002: ',r
1717                  if n == "vid":
1718                    if str(r[k]) == '__var_not_found_012__':
1719                      print 'ERROR.099.00202: bad vid string: %s [%s]' % (r[k],str(r[:3]))
1720                    vid = str(r[k])
1721                  if n == "stid":
1722                    item.setAttribute( n, stid )
1723                  elif n == "label":
1724                    thisl = string.replace( r[k], '_', '' )
1725                    item.setAttribute( n, thisl )
1726                  elif n in ["valid_min","valid_max","ok_max_mean_abs","ok_min_mean_abs"]:
1727                    if str(r[k]) != "" and r[k] not in [None, 'None']:
1728                      if str(r[k]) == "None":
1729                        print 'ERROR.8888.00008: bad valid min/max: ',r[k]
1730                      item.setAttribute( n, str(r[k]) )
1731                  elif n == "frequency":
1732                    fr = freqmap.get( str(r[k]), str(r[k]) )
1733                    item.setAttribute( n, fr )
1734                  elif n == "mipTable":
1735                    tn = tableNameMap.get( str(r[k]), str(r[k]) )
1736                    item.setAttribute( n, tn )
1737                  else:
1738                    item.setAttribute( n, str(r[k]) )
1739
1740### reset table name for OImon ... correcting for frequency as well
1741###
1742              if r[ktable] == 'OImon':
1743                if r[kfreq] == 'mon':
1744                    item.setAttribute( 'mipTable', 'SImon' )
1745                else:
1746                    item.setAttribute( 'mipTable', 'SIday' )
1747              elif r[ktable] in ['em6hr','em3hr','emDay']:
1748                if stid in self.structInfo:
1749                  if string.find( self.structInfo[stid][1], 'time: point' ) != -1:
1750                    item.setAttribute( 'mipTable', r[ktable] + 'pt' )
1751                else:
1752                    print 'WARN.090.09999: structure uid not found',stid, r
1753              if str(vid) not in self.importWbMods.vars.d1:
1754 
1755                  if thisl in self.importWbMods.vars.c1 or (thisl[-2:] in ['17','23'] and thisl[:-2] in self.importWbMods.vars.c1):
1756                    if thisl in self.importWbMods.vars.c1:
1757                      thisn = thisl
1758                    else:
1759                      thisn = thisl[:-2]
1760
1761                    if len( self.importWbMods.vars.c1[ thisn ] ) == 1:
1762                      newvid = self.importWbMods.vars.c1[ thisn ][0]
1763                      item.setAttribute( 'vid', newvid )
1764                      print 'INFO.099.00110: bad vid string replaced: %s [%s]' % (newvid,thisl)
1765                    else:
1766                      print 'ERROR.099.00111: ambiguous bad vid string: %s [%s]' % (vid,thisl)
1767                  else:
1768                    print 'ERROR.099.00112: bad vid string: %s [%s]' % (vid,thisl)
1769              thisuid = r[0]
1770              if self.repl.has_key( thisuid ):
1771                for tag,old,new in self.repl[thisuid]:
1772                  thisold = item.getAttribute( tag )
1773                  if thisold != old:
1774                     ##print 'WARN.yyy: Attempt to replace value which is not present'
1775                    print 'WARN.050.00051: Failed attempt to replace values in cmv: %s old:%s new:%s' % (tag,old,new)
1776                  else:
1777                    if tag == 'vid' and new not in self.importWbMods.vars.d1:
1778                        print 'ERROR.050.00052: Attempt to replave values in cmv with invalid vid: %s old:%s new:%s' % (tag,old,new)
1779                    else:
1780                      item.setAttribute( tag, new )
1781                      print 'INFO.050.00050: replacing values in cmv: %s old:%s new:%s' % (tag,old,new)
1782              self.ff[ksect][0].appendChild( item )
1783        elif ksect == u'structure':
1784          ers = {}
1785          for kk in spsResets:
1786            if len( spsResets[kk] ) > 0:
1787              utarg = spsResets[kk][0][0]
1788              for r in spsResets[kk][1:]:
1789                ers[r[0]] = utarg
1790          flds = self.structList[0]._fields
1791          for nt in self.structList:
1792            item = self.doc.createElement( 'item' )
1793            for f in flds:
1794              if f == 'spid' and nt.__dict__[f] in ers:
1795                item.setAttribute( f, ers[ nt.__dict__[f] ] )
1796                print 'INFO.801.00011: updating target spid .... '
1797              else:
1798                item.setAttribute( f, str( nt.__dict__[f] ) )
1799            self.ff[ksect][0].appendChild( item )
1800        elif ksect == u'spatialshape':
1801
1802     ##    self.dimsSpaceInfo = ['uid','label','title','dimensions','levelFlag','levels']
1803          for k in self.dimsSpace.keys():
1804            rr = self.dimsSpace[k]
1805            kk = rr[3]
1806            if kk == '':
1807              kk = 'scalar'
1808              rr = list(rr)
1809              rr[3] = 'scalar'
1810            elif kk == 'longitude|latitude|plev':
1811              kk = 'longitude|latitude|plev4'
1812              rr = list(rr)
1813              rr[3] = kk
1814            if kk not in spsResets:
1815              item = self.doc.createElement( 'item' )
1816              for i in range(len(self.dimsSpaceInfo)):
1817                item.setAttribute( self.dimsSpaceInfo[i], str( rr[i] ) )
1818              if rr[3] in self.spsh.ss:
1819                lab,ttl,lf,li = self.spsh.ss[rr[3]]
1820                if trace.SPATIALSHAPE_01:
1821                  print 'INFO.035.0001: new spatial shape label: %s, %s' % (lab, ttl)
1822                if ttl[:4] != 'ssd.':
1823                  item.setAttribute( 'title', ttl )
1824                if len(lab) < 4 or lab[:4] != 'ssd-':
1825                  item.setAttribute( 'label', lab )
1826                item.setAttribute( 'levels', li )
1827                item.setAttribute( 'levelFlag', string.lower(lf) )
1828              else:
1829                print 'ERROR.055.00001: spatial shape record not recognised: %s' % str(rr)
1830              print 'INFO.801.00120: new shape for %s' % str(rr)
1831              thisl = item.getAttribute( 'label' )
1832              assert thisl not in self.spLab2Uid.keys(), 'Duplicate spatial shape label: %s' % thisl
1833              self.spLab2Uid[thisl] = item.getAttribute( 'uid' )
1834              self.ff[ksect][0].appendChild( item )
1835            else:
1836              print 'INFO.801.00121: duplicate shape for %s' % str(rr)
1837            spsResets[kk].append( rr )
1838
1839        elif ksect == u'temporalshape':
1840          for k in self.dimsTime.keys():
1841            rr = self.dimsTime[k]
1842            item = self.doc.createElement( 'item' )
1843            for i in range(len(self.dimsTimeInfo)):
1844              item.setAttribute( self.dimsTimeInfo[i], str( rr[i] ) )
1845            self.ff[ksect][0].appendChild( item )
1846        elif ksect == u'requestvar':
1847          ##kk = ['var', 'table', 'mip', 'vid', 'priority']
1848          kk = ['label', 'table', 'mip', 'vid', 'priority','vgid','title','uid']
1849          kktr = {'vgid':'gpid', 'title':'label'}
1850    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
1851          kkf = 0
1852          for t in self.rqv:
1853            item = self.doc.createElement( 'item' )
1854            ###assert len(t) == len(kk), 'BAD request variable line: %s' % str(t)
1855            for i in range(len(kk)):
1856              k = kktr.get( kk[i], kk[i] )
1857              v = t[  self.rqvinfo.index(k) ]
1858              if k == 'priority':
1859                item.setAttribute( kk[i], str( int(v) ) )
1860              elif kk[i] == 'label':
1861                thisl = string.replace( v, '_', '' )
1862                item.setAttribute( kk[i], thisl )
1863              elif kk[i] == 'title':
1864                if str(v) == 'bsi':
1865                  print 'INFO.999.09900: ',t
1866                item.setAttribute( kk[i], str( v ) + ' ((isd.006))' )
1867              elif kk[i] == 'table':
1868                pass
1869              else:
1870                item.setAttribute( kk[i], str( v ) )
1871
1872            vid = str( t[2] )
1873            if vid in self.fx.d2:
1874               if self.fx.d2[vid][3] == u'replace':
1875                 item.setAttribute( 'vid', str( self.fx.d2[vid][4] ) )
1876                 print 'INFO.qqq12: replacing link in requestVar  %s' % str(t)
1877            if vid in self.importWbMods.mmsi.ss:
1878              print 'INFO.046.0002: mip map found: ', self.importWbMods.mmsi.ss[vid]
1879              mm = self.importWbMods.mmsi.ss[vid]
1880              self._editRequestVar01( item, mm, t )
1881              ##item.setAttribute( 'vid', mm[0].vid2 )
1882              ##if len( mm ) > 1:
1883                ##assert len( mm ) < 3, 'Unable to deal with triple clone'
1884                ##cln = item.cloneNode(True)
1885                ##cln.setAttribute( 'uid', str( uuid.uuid1() ) )
1886                ##cln.setAttribute( 'vid', mm[1].vid2 )
1887                ##self.ff[ksect][0].appendChild( cln )
1888                ##print 'INFO.046.0003: request variable split:', t[1]
1889             
1890            did = '%s__%s' % (t[2],t[3])
1891            if self.vgcheck.has_key(did):
1892              print 'ERROR.090.09002: Duplicate request ....: ',t,self.vgcheck[did]
1893            else:
1894              self.vgcheck[did] = t
1895              self.ff[ksect][0].appendChild( item )
1896              assert len( self.rqvClone.keys() ) > 5, 'rqvClone does not appear to be initialied: %s' % len( self.rqvClone.keys() )
1897              if self.rqvClone.has_key(t[0]):
1898                kkf += 1
1899                for id in self.rqvClone[t[0]]:
1900                  cln = item.cloneNode(True)
1901                  cln.setAttribute( 'vgid', id )
1902                  cln.setAttribute( 'uid', str( uuid.uuid1() ) )
1903                  self.ff[ksect][0].appendChild( cln )
1904                  print 'INFO.090.01010: request variable cloned:', t[1]
1905##
1906######################################################################################
1907##
1908        elif ksect == u'requestlink':
1909 ## - uuid; mip; tab; objective; grid; gridreq; comment
1910            kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt', 'opar', 'preset', 'ref', 'refNote', 'refid']
1911            ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','ref', 'refNote', 'refid']
1912       
1913            thissh = self.skey['requestlink']
1914            for k in thissh:
1915              if k[0] != '_':
1916                ll = thissh[k][:]
1917                thisl = string.strip(str( ll[2] ) )
1918                uid = string.strip(str( ll[0] ) )
1919                item = self.doc.createElement( 'item' )
1920                for j in range(len(kk)):
1921                  thiskk = kk[j]
1922## preset mover to request item .... so it can also be used on a per-experiment basis
1923                  if thiskk != 'preset':
1924                    try:
1925                      if kk[j] == 'comment':
1926                        v = utils_wb.uniCleanFunc( v )
1927                      else:
1928                        v = str( ll[j] )
1929                    except:
1930                      print thisl, kk[j]
1931                      print 'ERROR.099.0001: Failed to convert string '
1932                      print ll
1933                      v = '__error_99_1__'
1934
1935### redirect to new variable group if specified in mappings
1936##
1937                    if kk[j] == 'refid' and self.rvgUidMapping.has_key(v):
1938                        v = self.rvgUidMapping[v]
1939                        print 'INFO.090.00200: variable group reference reset in %s [%s]' % (thisl,uid)
1940
1941                    item.setAttribute( thiskk, v )
1942
1943                item.setAttribute( 'title', thisl )
1944                if self.rqlRedirect.has_key( ll[0] ):
1945                   print 'INFO.088.02020: redirect detected ',ll
1946                   item.setAttribute( 'refid', self.rqlRedirect[ ll[0] ] )
1947                self.ff[ksect][0].appendChild( item )
1948##################################
1949               
1950
1951  def _editRequestVar01( self, item, mm, t ):
1952              item.setAttribute( 'vid', mm[0].vid2 )
1953              item.setAttribute( 'label', mm[0].lab2 )
1954              if len( mm ) > 1:
1955                assert len( mm ) < 3, 'Unable to deal with triple clone'
1956                cln = item.cloneNode(True)
1957                cln.setAttribute( 'uid', str( uuid.uuid1() ) )
1958                cln.setAttribute( 'label', mm[1].lab2 )
1959                self.ff['requestvar'][0].appendChild( cln )
1960                print 'INFO.046.0003: request variable split:', t[1]
1961
1962  def finishExptGrp(self):
1963    """finish exptGroup section and create exptgrouplink section"""
1964    this = self.doc.getElementsByTagName('exptGroup')[0]
1965            ### kk = ['uid','label','tierMin','ntot']
1966    for k in self.exptPntUid.keys():
1967      u,typ = self.exptPntUid[k]
1968##      if not isg:
1969        ##item = self.doc.createElement( 'item' )
1970        ##item.setAttribute( uid, u )
1971    ##this = self.doc.getElementsByTagName('exptGroupLink')[0]
1972    ##dil = this.getElementsByTagName('item')
1973    ##for d in dil:
1974          ##this.removeChild(d)
1975    ##this.appendChild( item )
1976
1977  def reviewExpt(self):
1978    """Prepare cross-linking information to populate requestitem, exptgroup and exptgrouplink"""
1979    sh = shelve.open( '../framework/sh_links/exptMappings', 'r' )
1980    extraMappings={ 'LS3MIP-1, LS3MIP-2':['LmipH', 'LmipF'] }
1981    ks = sorted( self.exptPnt.keys() )
1982    self.exptPntMap = collections.defaultdict( list )
1983    self.exptPntUid = {}
1984    ner = 0
1985    ngr = 0
1986    nmr = 0
1987    nuns = 0
1988    nls = 0
1989    for k0 in ks:
1990      k = string.replace( string.replace( k0, '\n', ' ' ), '  ', ' ')
1991      thisl = None
1992      if sh.has_key(k):
1993        thisl = sh[k]
1994      elif extraMappings.has_key(k):
1995        thisl = extraMappings[k]
1996      else:
1997        print 'ERROR.080.00010: no mapping founds for experiment %s' % k
1998     
1999
2000      if thisl != None:
2001        thisu = None
2002        thisls = set( thisl )
2003        linkType = None
2004        for k2 in thisls:
2005          ok = True
2006          if self.experiments.has_key(k2):
2007            ner += 1
2008            linkType = 'expt'
2009            thisu = self.experiments[k2]
2010          elif self.experimentGrp.has_key(k2):
2011            ngr += 1
2012            thisu = self.experimentGrp[k2]
2013            linkType = 'grp'
2014          elif k2 in self.mips:
2015            nmr += 1
2016            thisu = k2
2017            linkType = 'mip'
2018          else:
2019            ok = False
2020            print 'ERROR.080.00999: target experiment not found: %s [%s]' % (k2,k)
2021          if not ok:
2022            self.exptPntMap[k].append( k2 )
2023##
2024## store uid of expt group to be pointed at.
2025##
2026        if len(thisls) == 1 and thisu != None:
2027          self.exptPntUid[k0] = (thisu, linkType, thisls)
2028        else:
2029          self.exptPntUid[k0] = (str( uuid.uuid1() ), 'list', thisls )
2030          nls += 1
2031      else:
2032          nuns += 1
2033          self.exptPntUid[k0] = (None,None)
2034     
2035    sh.close()
2036    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)
2037
2038  def reviewObj(self):
2039## review objectives
2040##
2041    ol = []
2042    fnd1 = set()
2043    for m in self.objectives.keys():
2044      not_used = []
2045      used = set()
2046      not_found = []
2047      found = []
2048      alist = ['All','All?','all']
2049      aaa = [self.objectiveLinks[m].a.has_key(x) for x in ['All','All?','all'] ]
2050      us1 = set()
2051      for k in self.objectiveLinks[m].a:
2052        x = None
2053        if k == 'AllExceptPaleorcms':
2054          x = self.objectives[m].keys()
2055          x.pop( x.index( 'Paleorcms' ) )
2056        elif k == 'AllExceptNaturalVariability':
2057          x = self.objectives[m].keys()
2058          x.pop( x.index( 'NaturalVariability' ) )
2059
2060        if x != None:
2061          fnd1.add(k)
2062          for i in x:
2063            used.add(i)
2064            us1.add(i)
2065            for u in self.objectiveLinks[m].a[k]:
2066              ol.append( (m,self.objectives[m][i], u ) )
2067         
2068      allused = (m != 'GMMIP') and any( aaa )
2069      for o in self.objectives[m].keys():
2070        if allused or self.objectiveLinks[m].a.has_key(o):
2071          used.add(o)
2072          for u in self.objectiveLinks[m].a[o]:
2073            ol.append( (m,self.objectives[m][o], u ) )
2074          for k in alist:
2075            if self.objectiveLinks[m].a.has_key(k):
2076              for u in self.objectiveLinks[m].a[k]:
2077                ol.append( (m,self.objectives[m][o], u ) )
2078        elif o not in us1:
2079          not_used.append(o)
2080
2081      for o in self.objectiveLinks[m].a.keys():
2082        if (o in {'All','All?'} and len(self.objectives[m].keys()) > 0 ) or self.objectives[m].has_key(o) or o in fnd1:
2083          found.append(o)
2084        else:
2085          not_found.append(o)
2086      if len(not_used) > 0 or len(not_found) > 0:
2087        print 'WARN.080.00002: %s: OK %s: unused: %s: not found:%s' % (m,str(used),str(not_used),str(not_found))
2088      else:
2089        print 'INFO.080.00002: %s: all objectives matched' % m
2090    self.objList = ol
2091
2092
2093  def finish(self):
2094## varChoice section
2095    self.choices()
2096##
2097    self.reviewObj()
2098##
2099##
2100    if len( self.prqv.addExrqvg )  > 0:
2101      this = self.doc.getElementsByTagName('requestVarGroup')[0]
2102      kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
2103      for k in self.prqv.addExrqvg:
2104         item = self.doc.createElement( 'item' )
2105         ll = self.prqv.exrqvg[k]
2106         thisl = string.replace( str( ll[2] ), '.', '-' )
2107         for j in range(len(kk)):
2108              if kk[j] == 'refNote':
2109                item.setAttribute( kk[j], str( ll[j] ) + '((isd.004))' )
2110              else:
2111                item.setAttribute( kk[j], str( ll[j] ) )
2112         this.appendChild( item )
2113##
2114##  objectiveLink
2115##
2116    this = self.doc.getElementsByTagName('objectiveLink')[0]
2117    dil = this.getElementsByTagName('item')
2118    for d in dil:
2119          this.removeChild(d)
2120    for t in self.objList:
2121       item = self.doc.createElement( 'item' )
2122       item.setAttribute( 'label', t[0] )
2123       item.setAttribute( 'oid', t[1] )
2124       item.setAttribute( 'rid', t[2] )
2125       thisuuid = str( uuid.uuid1() )
2126       item.setAttribute( 'uid', thisuuid )
2127       this.appendChild( item )
2128##
2129## remarks
2130##
2131    this = self.doc.getElementsByTagName('remarks')[0]
2132    dil = this.getElementsByTagName('item')
2133    for d in dil:
2134          this.removeChild(d)
2135
2136    txt = self.doc.toprettyxml(indent='\t', newl='\n', encoding=None)
2137    if self.schemaMode == 'dreq2':
2138      ofn = 'trial2_20150831.xml'
2139    else:
2140      ofn = 'trial_20150831.xml'
2141    oo = open( ofn, 'w' )
2142    lines = string.split( txt, '\n' )
2143    for line in lines:
2144      l = utils_wb.uniCleanFunc( string.strip(line) )
2145      if empty.match(l):
2146        continue
2147      else: 
2148        oo.write(l + '\n')
2149    oo.close()
2150
2151  def choices(self):
2152    """Populate the 'varChoice' section, using the information in the 'choices' dictionary in 'choicecfg'"""
2153
2154    ccfg = choiceCfg.choices( self )
2155    self.ccfg = ccfg
2156##
2157##  choices
2158##
2159    this = self.doc.getElementsByTagName('varChoice')[0]
2160    dil = this.getElementsByTagName('item')
2161    for d in dil:
2162          this.removeChild(d)
2163    for k in ccfg.choices.keys():
2164       item = self.doc.createElement( 'item' )
2165       cc = ccfg.choices[k]
2166       for kk in cc.keys():
2167         item.setAttribute( kk, cc[kk] )
2168       this.appendChild( item )
2169       print 'INFO.zzz.00008: Appending ',cc[kk]
2170
2171    this = self.doc.getElementsByTagName('varChoiceLinkR')[0]
2172    dil = this.getElementsByTagName('item')
2173    for d in dil:
2174          this.removeChild(d)
2175    for cc in ccfg.varChoiceLnk:
2176       item = self.doc.createElement( 'item' )
2177       print 'INFO.zzz', cc
2178       for i in range( len( ccfg.varChoiceLnkInfo ) ):
2179         item.setAttribute( ccfg.varChoiceLnkInfo[i], cc[i] )
2180       this.appendChild( item )
2181
2182    this = self.doc.getElementsByTagName('varChoiceLinkC')[0]
2183    dil = this.getElementsByTagName('item')
2184    for d in dil:
2185          this.removeChild(d)
2186    for cc in ccfg.varChoiceLnkCfg:
2187       item = self.doc.createElement( 'item' )
2188       for i in range( len( ccfg.varChoiceLnkCfgInfo ) ):
2189         item.setAttribute( ccfg.varChoiceLnkCfgInfo[i], cc[i] )
2190       this.appendChild( item )
2191
2192    ##self.varChoiceLnkCfgInfo = [ 'uid', 'label', 'title', 'vid', 'cid', 'cfgid', 'cfg'
2193
2194  def importRepl(self,rfile='uuidreplace.csv'):
2195    for l in open(rfile).readlines():
2196      bits = string.split( string.strip(l), '\t' )
2197      assert len(bits) == 7, 'Could not parse item replacement file'
2198      self.repl[ bits[3] ].append( (bits[2],bits[0],bits[1] ) )
2199      self.replItems[bits[0]] = bits[1]
2200
2201  def importRemove(self,rfile='uuidremove.csv'):
2202    for l in open(rfile).readlines():
2203      self.remo[ string.strip(l) ] = 1
2204
2205  def importUpdate(self,rfile='uuidupdate.csv'):
2206    for l in open(rfile).readlines():
2207      bits = string.split( string.strip(l), '\t' )
2208      tgs = string.strip( bits[2] )
2209      if string.find( tgs, ' ' ) == -1:
2210        tags = [tgs,]
2211      else:
2212        tags = string.split( tgs )
2213      self.upda[ bits[0] ] =  {'comment':bits[1], 'tags':tags, 'label':bits[3], 'title':bits[4] }
2214
2215  def importInsert(self,rfile='uuidinsert.csv'):
2216    for l in open(rfile).readlines():
2217      bits = string.split( string.strip(l), '\t' )
2218      if bits[0] == 'unique':
2219         self.insert[bits[1]] = bits[3]
2220
2221mode = 'dreq2'
2222sampleXml = '../framework/out/%sSample.xml' % mode
2223from scansh import rq
2224
2225##cmip5GrpLk = collections.defaultdict( dict )
2226##for k in rq.cmip5Grps.keys():
2227  ##bits = string.split(k,'_')
2228  ##tab = bits[0]
2229  ##for v in rq.cmip5Grps[k]:
2230    ##cmip5GrpLk[tab][v] = k
2231
2232m = main(sampleXml, rq,run=True, schemaMode=mode, doRepl=True)
2233
2234ks = m.prqv.err0010.keys()
2235ks.sort()
2236for k in ks:
2237    print 'ERROR.001.0010: variable group not identified: %s [%s]' % (k,m.prqv.err0010[k])
2238ks = m.prqv.err0020.keys()
2239ks.sort()
2240for k in ks:
2241    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.