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

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

partial updates for AerChemMIP, SIMIP

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
29class replaceItems(object):
30  def __init__(self):
31    self.v = collections.defaultdict( list )
32    self.items = {}
33
34WbMods = importWbMods.run()
35tableUtils = ivg.tableUtils()
36
37nt__trace = collections.namedtuple( 'trace', ['GROUPITEM_ta','SPATIALSHAPE_01'] )
38trace = nt__trace( False, False )
39
40tab2freq = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
41                  u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
42                  u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
43                  u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
44                  u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
45                  u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
46                  u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
47                  u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'mon', \
48                  u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
49                  u'DCPP-day':'day',  \
50                  u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
51                  'OImon':'mon', 'Omon_oth':'mon', 'Omon':'mon',  'Oyr':'yr', 'Omon_3d':'mon', \
52                  u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr', \
53                  u'cf3hr':'3hr', u'Amon':'mon', u'aero':'mon', u'aero_3d':'mon', u'6hrPlev':'6hr', u'aero_oth':'mon', \
54                  u'cf3hr_grid':'3hr', u'LImon':'mon', u'cfSites':'subhr', u'day_oth':'day', u'cfDay_2d':'day', u'day':'day' }
55
56freq2tab = collections.defaultdict( list )
57for k in tab2freq:
58  freq2tab[tab2freq[k]].append( k )
59
60tableNameMap = {'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' }
61
62reportedRedundantTables = set()
63redundantTables = ['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']
64
65## mapping of variable groups representing tables ....
66mappedTables =  {'Omon':'OMIP-Omon', 'OMIP-Oyr':'Oyr', 'OImon':'SIMIP-seaicemon' }
67mappedTables =  {'Omon':'OMIP-Omon', 'CMIP5-Oyr':'OMIP-Oyr', 'OImon':'SIMIP-seaicemon', 'CMIP5-Omon':'OMIP-Omon' }
68
69freqmap = {'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'  }
70
71nt_expt = collections.namedtuple( 'expt', ['uid', 'label', 'mip', 'egid' ] )
72realmdef = { '__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]'], 
73        '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]'],
74        '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]'],
75        '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]'],
76        'seaIce':['SIMIP [seaicemon]', 'SIMIP [seaiceday]' ],
77        'landIce':['ISMIP6 [new_LImon]', 'PMIP [PMIP-LIclim]', 'ISMIP6 [icesheetyear]', 'ISMIP6 [new_fx]', 'ISMIP6 [icesheetmon]'],
78        '__unset__':['LS3MIP [LWday]', 'LS3MIP [LEday]'] }
79
80realmdefix = {}
81for k in realmdef.keys():
82  if k != '__all__':
83    for s in realmdef[k]:
84      assert not realmdefix.has_key(s), 'Duplicate targ value in realmdef: %s [%s]' % (s,k)
85      realmdefix[s] = k
86
87for k in realmdef['__all__']:
88  assert realmdefix.has_key(k), 'Key %s not found in realmdefix' % k
89
90class cls_s1(object):
91  def __init__(self):
92    self.a = collections.defaultdict( list )
93
94def mycc(s):
95      s = string.replace( s, '&', '' )
96      if len(s) > 0 and s[-1] == '+':
97        s = s[:-1] + 'ETC'
98## camelcase the input string
99      s1 = string.lower( string.replace(string.strip(str( s) ), '-', ' ') )
100      return string.replace( string.capwords( s1 ), ' ', '' )
101
102empty=re.compile('^$')
103
104def test( x,m):
105  if not x:
106    print m
107  return x
108
109class lcm(object):
110  def __init__(self,a,b):
111    self.a = {}
112    self.b = {}
113    for i in a:
114      self.a[string.lower(i)] = i
115    for i in b:
116      self.b[string.lower(i)] = i
117
118class main(object):
119
120  def __init__(self,src,rq,doRepl=False,run=False,schemaMode='dreq'):
121    self.schemaMode = schemaMode
122    self.requestlinkuid = set()
123    self.src=src
124    self.vgcheck = {}
125    self.rqlPreset = {}
126    fok = [test(os.path.isfile(src),'%s not found' % src), ]
127    assert all( fok), 'Required input file(s) missing'
128    self.fix = WbMods.fix
129    self.spsh = WbMods.ls
130    self.cmDims = WbMods.cm
131    self.importWbMods = WbMods
132
133    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]:
134       print sh['__info__']
135
136    self.repl = collections.defaultdict( list )
137    self.replItems = {}
138    self.rep = {'cmv':replaceItems()}
139
140    self.err0010 = collections.defaultdict( int )
141    self.defaultP = {}
142    self.remo = {}
143    self.upda = {}
144    self.insert = {}
145    self.exptSet = set()
146    self.exptGrpDict = {}
147
148    self.objectives = collections.defaultdict( dict )
149    self.objectiveLinks = collections.defaultdict( cls_s1 )
150    self.experiments = {}
151    self.experimentGrp = {}
152    self.exptPntUid = {}
153    self.exptPnt = collections.defaultdict( list )
154    self.mips = set()
155    self.dsortdd = {}
156
157    if doRepl:
158      self.importRepl()
159      self.importRepl(rfile='CMVreplace.csv',mode='cmv')
160      self.importRemove()
161      self.importUpdate()
162      self.importInsert()
163    self.e15_10 = 0
164    self.doc = xml.dom.minidom.parse( self.src  )
165    self.vocabs = xml.dom.minidom.parse( 'vocabs.xml' )
166    self.skey = {'experiment':rq.expt, 'exptgroup':rq.exgp, \
167         'objective':rq.objec, 'var':rq.vars,'ovar':rq.refti, 'groupitem':rq.grps, \
168         'revisedtabitem_xxx':rq.revti, 'requestlink':rq.rqli, 'requestitem':rq.rqit, \
169         'requestvargroup':rq.rqvg, 'tablesection':rq.rqsect, 'requestvar':rq.revti}
170
171    self.newImport = False
172    self.prepVar()
173    self.writeTimeSlice()
174    self.writeMip()
175    self.writeSn()
176    self.writeMcfg()
177    self.writeProcNotes()
178    self.writeCmDim()
179    self.writeVar()
180    self.prep01()
181    self.prepRequestVarGroup()
182    self.prep(rq)
183    self.addAerChem()
184    self.cmvAudit(0)
185    self.prepRequestItem()
186    self.reviewExpt()
187    if run:
188      self.run(rq)
189      self.prepRequestLink()
190      self.finishRequestLink()
191      self.writeRelations()
192      if self.schemaMode == 'dreq2':
193        self.write2()
194      self.finish()
195
196  def writeProcNotes(self):
197    xx = self.vocabs.getElementsByTagName( 'processingOptions' )
198    assert len(xx) == 1, 'Expecting one element named "processingOptions", found %s' % len(xx)
199    iDoc = xx[0]
200## <item id="tmpid.0003" label="C4MIP" status="" title="Coupled Climate Carbon Cycle Model Intercomparison Project" url="http://c4mip.lsce.ipsl.fr/"/>
201    thiss = self.doc.getElementsByTagName( 'tags' )[0]
202    dil = thiss.getElementsByTagName('item')
203    for d in dil:
204      thiss.removeChild(d)
205    for i in iDoc.getElementsByTagName('item'):
206      item = self.doc.createElement( 'item' )
207      thisl = i.getAttribute( 'label' )
208      for k in ['title','description','label']:
209        item.setAttribute( k, i.getAttribute( k ) )
210      uid =  'TAG:%s' % thisl
211      item.setAttribute( 'uid', uid )
212      thiss.appendChild( item )
213
214  def writeRelations(self):
215    thiss = self.doc.getElementsByTagName( 'varRelations' )[0]
216    dil = thiss.getElementsByTagName('item')
217    for d in dil:
218      thiss.removeChild(d)
219    for i in self.fix.relations:
220      item = self.doc.createElement( 'item' )
221      for j in range( len( self.fix.relationinfo ) ):
222        item.setAttribute( self.fix.relationinfo[j], i[j] )
223      thiss.appendChild( item )
224
225    thiss = self.doc.getElementsByTagName( 'varRelLnk' )[0]
226    dil = thiss.getElementsByTagName('item')
227    for d in dil:
228      thiss.removeChild(d)
229    cc = collections.defaultdict(int)
230    for i in self.fix.relationlinks:
231      item = self.doc.createElement( 'item' )
232      tvp = i[1]
233      ix = cc[tvp]
234      cc[tvp] += 1
235      for j in range( len( self.fix.relationlinkinfo ) ):
236        item.setAttribute( self.fix.relationlinkinfo[j], i[0][j] )
237      if tvp in self.cmvUidByTVP:
238        vid = self.cmvUidByTVP[ tvp ][ix]
239        item.setAttribute( 'rid', vid )
240        print 'INFO.093.00011: found: %s' % str(tvp)
241      else:
242        t,v,p = tvp
243        if ('CMIP5_%s' % t,v,p) in self.cmvUidByTVP:
244          if ix >= len(self.cmvUidByTVP[ ('CMIP5_%s' % t,v,p) ] ):
245            print 'WARN.093.00011b: not found: %s, %s' % (str(tvp),ix)
246          else:
247            vid = self.cmvUidByTVP[ ('CMIP5_%s' % t,v,p) ][ix]
248            item.setAttribute( 'rid', vid )
249            print 'INFO.093.00011a: found: %s' % str(tvp)
250        elif t[-2:] in ['pt','zm'] and ( t[:-2],v,p) in self.cmvUidByTVP:
251          vid = self.cmvUidByTVP[ ( t[:-2],v,p) ][ix]
252          item.setAttribute( 'rid', vid )
253          print 'INFO.093.00011a: found: %s' % str(tvp)
254        else:
255          print 'WARN.093.00011: not found: %s' % str(tvp)
256      thiss.appendChild( item )
257
258  def writeMcfg(self):
259    self.cfgUids = set()
260    xx = self.vocabs.getElementsByTagName( 'modelConfig' )
261    assert len(xx) == 1, 'Expecting one element named "modelConfig", found %s' % len(xx)
262    iDoc = xx[0]
263## <item id="tmpid.0003" label="C4MIP" status="" title="Coupled Climate Carbon Cycle Model Intercomparison Project" url="http://c4mip.lsce.ipsl.fr/"/>
264    thiss = self.doc.getElementsByTagName( 'modelConfig' )[0]
265    dil = thiss.getElementsByTagName('item')
266    for d in dil:
267      thiss.removeChild(d)
268    for i in iDoc.getElementsByTagName('item'):
269      item = self.doc.createElement( 'item' )
270      thisl = i.getAttribute( 'label' )
271      for k in ['title','MIPs','usage','range','type']:
272        item.setAttribute( k, i.getAttribute( k ) )
273      uid = str( thisl )
274      item.setAttribute( 'uid', uid )
275      item.setAttribute( 'label', uid )
276      self.cfgUids.add( uid )
277      thiss.appendChild( item )
278
279  def writeCmDim(self):
280    thiss = self.doc.getElementsByTagName( 'grids' )[0]
281    dil = thiss.getElementsByTagName('item')
282    for d in dil:
283      thiss.removeChild(d)
284    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' ]
285    for j in self.cmDims.ss.keys():
286      item = self.doc.createElement( 'item' )
287      for i in range(len(kk)):
288        if kk[i] in ['valid_min','valid_max']:
289          if str( self.cmDims.ss[j][i] ) != '':
290            item.setAttribute( kk[i], str( self.cmDims.ss[j][i] ) )
291        else:
292          item.setAttribute( kk[i], str( self.cmDims.ss[j][i] ) )
293      uid = 'dim:%s' % str( self.cmDims.ss[j][1] )
294      item.setAttribute( 'uid', uid )
295      thiss.appendChild( item )
296
297  def writeVar(self):
298    thiss = self.doc.getElementsByTagName( 'var' )[0]
299    dil = thiss.getElementsByTagName('item')
300    for d in dil:
301      thiss.removeChild(d)
302#<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"/>
303    kk= ['label', 'title', 'description', 'procComment', 'procnote', 'prov', 'provmip', 'sn', 'units', 'uid','defaultp','replaced_by']
304    for uid in self.importWbMods.vars.d1:
305      item = self.doc.createElement( 'item' )
306      thisr = self.importWbMods.vars.d1[uid]
307      for i in range( len(kk) -2 ):
308           item.setAttribute( kk[i], thisr[i] )
309      if len( self.importWbMods.vars.c1[ thisr[0] ] ) == 1:
310         id = thisr[0]
311      else:
312         id = '%s.%s' % (thisr[0],self.importWbMods.vars.c1[ thisr[0] ].index( uid ) )
313         print 'INFO.090.00050: setting id for non-unique variable name: %s' % id
314      item.setAttribute( 'id', id )
315      thiss.appendChild( item )
316
317  def writeSn(self):
318    import loadcf
319    cf = loadcf.cf()
320    thiss = self.doc.getElementsByTagName( 'standardname' )[0]
321    dil = thiss.getElementsByTagName('item')
322    for d in dil:
323      thiss.removeChild(d)
324
325    for i in sorted( cf.names.keys() ):
326      item = self.doc.createElement( 'item' )
327      d,u = cf.names[i]
328      uid = str(i)
329      title = string.capwords( string.replace( uid, '_', ' ' ) )
330      label = string.replace( title, ' ', '' )
331      for w in ['Of','In','On','By']:
332        ww = ' %s ' % w
333        title = title.replace( ww, string.lower( ww ) )
334      item.setAttribute( 'uid', uid  )
335      item.setAttribute( 'label', label  )
336      item.setAttribute( 'title', title  )
337      item.setAttribute( 'units', str(u) )
338      item.setAttribute( 'description', uniCleanFunc( d ) )
339      thiss.appendChild( item )
340
341  def writeTimeSlice(self):
342    xx = self.vocabs.getElementsByTagName( 'timeSlice' )
343    assert len(xx) == 1, 'Expecting one element named "activity", found %s' % len(xx)
344    iDoc = xx[0]
345    thiss = self.doc.getElementsByTagName( 'timeSlice' )[0]
346    dil = thiss.getElementsByTagName('item')
347    for d in dil:
348      thiss.removeChild(d)
349
350    for i in iDoc.getElementsByTagName('item'):
351      item = self.doc.createElement( 'item' )
352      label = i.getAttribute( 'label' )
353      for k in ['label','title','type']:
354        item.setAttribute( k, i.getAttribute( k ) )
355      for k in ['start', 'end', 'step', 'sliceLen', 'nyears']:
356        if i.getAttribute( k ) != '':
357          v = str( int( float( i.getAttribute( k ) ) ) )
358          item.setAttribute( k, v )
359      item.setAttribute( 'uid', '_slice_%s' % label )
360      thiss.appendChild( item )
361
362  def writeMip(self):
363    self.mipUids = set()
364    xx = self.vocabs.getElementsByTagName( 'activity' )
365    assert len(xx) == 1, 'Expecting one element named "activity", found %s' % len(xx)
366    mipDoc = xx[0]
367## <item id="tmpid.0003" label="C4MIP" status="" title="Coupled Climate Carbon Cycle Model Intercomparison Project" url="http://c4mip.lsce.ipsl.fr/"/>
368    thiss = self.doc.getElementsByTagName( 'mip' )[0]
369    dil = thiss.getElementsByTagName('item')
370    for d in dil:
371      thiss.removeChild(d)
372    for i in mipDoc.getElementsByTagName('item'):
373      item = self.doc.createElement( 'item' )
374      mip = i.getAttribute( 'label' )
375      for k in ['title','url']:
376        item.setAttribute( k, i.getAttribute( k ) )
377      uid = string.replace( mip, ' ', '' )
378      item.setAttribute( 'uid', uid )
379      item.setAttribute( 'label', uid )
380      self.mipUids.add( uid )
381      thiss.appendChild( item )
382
383    if "DECK" not in self.mipUids:
384      item = self.doc.createElement( 'item' )
385      item.setAttribute( 'uid', 'DECK' )
386      item.setAttribute( 'url', '' )
387      item.setAttribute( 'label', 'DECK' )
388      item.setAttribute( 'title', 'DECK - set of standard CMIP runs' )
389      self.mipUids.add( "DECK" )
390      thiss.appendChild( item )
391
392  def prepRequestVarGroup(self):
393    self.varGroupByLabel = {}
394    self.varGroupUids = set()
395    nsev = 0
396    ss = set()
397    for k in ['requestvargroup','tablesection']:
398      if k == 'requestvargroup':
399              kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
400              il = 2
401      else:
402              kk = ['uid', 'gpid', 'mip', 'label', 'title', 'ref', 'refNote']
403              il = 3
404      thissh = self.skey[k]
405      for r in thissh:
406        if r[0] != '_':
407          thisl = str( thissh[r][il] )
408          if self.varGroupByLabel.has_key( thisl ):
409            print 'ERROR.090.00012: Duplicate label in variable groups: %s' % thisl
410            nsev += 1
411            if thisl in ['OMIP-Oyr', 'CMIP5-Oyr']:
412              print 'ERROR.Oyr: ',thissh[r]
413            ss.add( thisl )
414          self.varGroupByLabel[thisl] = r
415          self.varGroupUids.add( thissh[r][0] )
416
417    for k in self.prqv.exrqvg.keys():
418         ll = self.prqv.exrqvg[k]
419         thisl = string.replace( str( ll[2] ), '.', '-' )
420         if self.varGroupByLabel.has_key( thisl ):
421            print 'ERROR.090.00013: Duplicate label in variable groups: %s, %s' % (k,thisl)
422            nsev += 1
423            ss.add( thisl )
424            if thisl in ['OMIP-Oyr', 'CMIP5-Oyr']:
425              print 'ERROR.Oyr: ',k,ll
426         self.varGroupByLabel[thisl] = k
427         self.varGroupUids.add( ll[0] )
428
429    self.rvgUidMapping = {}
430    for k in mappedTables.keys():
431      assert k not in ss and mappedTables[k] not in ss, 'Ambiguous table mapping because of duplicate variable group labels: %s' % k
432      ##assert self.varGroupByLabel.has_key( k ),'Table mapping key not found: %s' % k
433      assert self.varGroupByLabel.has_key( mappedTables[k] ),'Table mapping target not found: %s [%s]' % (mappedTables[k], str(self.varGroupByLabel.keys()) )
434      if k in mappedTables and k in self.varGroupByLabel:
435        self.rvgUidMapping[self.varGroupByLabel[k]] = self.varGroupByLabel[ mappedTables[k] ]
436        print 'INFO.090.00012: request variable mapping initialised: %s --> %s' % (k,mappedTables[k])
437      else:
438        print 'INFO.090.00011: request variable mapping NOT initialised: %s --> %s' % (k,mappedTables[k])
439     
440    assert nsev < 20, 'Multiple duplicate labels in variable groups: %s' % nsev
441
442  def prepVar(self):
443      thissh = self.skey['var']
444      self.varsxx = None
445      if self.newImport:
446#['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0', 'rlm0']
447        self.vars = collections.defaultdict( list )
448        self.vars1 = collections.defaultdict( list )
449        for k in thissh:
450          if k[0] != '_':
451            ll = thissh[k][:]
452            thisl = str( ll[2] )
453            self.vars[thisl].append( k )
454            self.vars1[str( ll[0] )].append( k )
455      else:
456        self.varsxx = collections.defaultdict( list )
457        for k in thissh:
458          if k[0] != '_':
459            ll = thissh[k][:]
460            thisl = str( ll[2] )
461            self.varsxx[str( ll[0] )].append( k )
462
463  def prepRequestItem(self):
464      thissh = self.skey['requestitem']
465      s1 = collections.defaultdict( set )
466      for k in thissh:
467        if k[0] != '_':
468          ll = thissh[k][:]
469          ku = str(ll[2])
470          s1[ll[0]].add(ll[-1])
471##
472          self.exptPnt[ku].append( str(k) )
473      print 'INFO.dddd: %s: %s' % ('DAMIP',str( s1['DAMIP'] ) )
474      self.tsliceMap = {}
475      self.tsliceMap['DAMIP'] = {'18 (1850, 1860, ..,  2010, 2020)':'DAMIP18', 'all':None, '8\n(2030, 2040, .., 2090, 2100)':'DAMIP8', '61\n(1960-2020)':'DAMIP61', '40\n(2026-2045, 2081-2100)':'DAMIP40', '20\n(2081-2100)':'DAMIP20', '42\n(1979-2020)':'DAMIP42' }
476
477      thissh = self.skey['experiment']
478      for k in thissh:
479        if k[0] != '_':
480          ll = thissh[k][:]
481          thisl = str( ll[2] )
482          self.mips.add( str( ll[4] ) )
483          self.experiments[thisl] = str( ll[0] )
484          self.exptSet.add( nt_expt._make( [str( ll[0] ), thisl, str( ll[4] ), str( ll[1] ) ] ) )
485          ##nt_expt = collections.namedtuple( 'expt', ['uid', 'label', 'mip', 'egid' ] )
486
487      thissh = self.skey['exptgroup']
488      for k in thissh:
489        if k[0] != '_':
490          ll = thissh[k][:]
491          thisl = str( ll[1] )
492          self.exptGrpDict[thisl] = str( ll[1] )
493          self.experimentGrp[thisl] = str( ll[0] )
494
495      mm = []
496      for m in self.mips:
497        if m not in self.mipUids:
498          mm.append(m)
499      assert len(mm) == 0, 'Not all mips found: %s: %s' % (str(mm),str(self.mipUids))
500
501  def prepRequestLink(self):
502      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',
503      'concdust,concaerh2o,reffclwc,emiso4,loadso4,concso2,emidust,emiss,conccmcn,emiso2,concnmcn,concss,reffclws,loadss,conccn',
504      'rsdsdiff,dryso4,wetso2,cldnci,od550lt1aer,reffclwtop,dryss,wetso4,sconcso4,cldncl,abs550aer,wetss,rsdscsdiff,wetdust,ec550aer,cldnvi,dryso2,drydust,od550aer,sconcss,sconcdust',
505      'thkcello,wmo,uo,hfnorth,tos,sos,soga,masscello,hfy,msftmrhoz,masso,pso,mlotst,zos,zostoga,rhopoto,hfydiff,hfbasin,ficeberg2d,thetao,so,zossga,dpco2,msftmyz,tauvo,sfdsi,msftyrhoz,spco2,fddtalk,hfxdiff,omlmax,htovovrt,sltovovrt,vmo,tauuo,volo,zsatarag,fgco2,zosga,wfo,vo,msftyyz,mfo,ficeberg,friver,msftbarot,umo,intpcalcite,intparag,fddtdic,hfx,agessc,hfbasindiff',
506      'difvmo,difvho,difvso',  'pr, tas, huss & rsds' , 'ta, ua, va, zg, hus'}
507      s1 = {'vstar, wstar, fy, fz, acceldivf[utenddivf], accelogw[utendogw], accelnogw[utendnogw], diabdrag[utenddiabdrag]'}
508      self.varGroupSs2 = collections.defaultdict( cls_s1 )
509      self.varGroupSubset = collections.defaultdict( dict )
510      kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','preset', 'ref', 'refNote', 'refid']
511##
512## preset is in the wrong place here ..... should be on the linked experiment group ...
513## 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....
514##
515# create lists of variables wanted from groups, indexed by uid of group and requestLink
516      map8 = lambda x: map( string.strip, string.split( string.replace(x,'&',','), ',' ) )
517      thissh = self.skey['requestlink']
518      for k in thissh:
519        if k[0] != '_':
520          rr = thissh[k][:]
521          if rr[8] in s0:
522            print 'INFO.077.07060: rr[8] matched .... ', rr[8]
523            vl0 = map8( rr[8] )
524          elif rr[7] in s0:
525            print 'INFO.077.07070: rr[7] matched .... ', rr[7]
526            ##vl0 = map( string.strip, string.split( rr[7], ',' ) )
527            vl0 = map8( rr[7] )
528          elif rr[8] in s1:
529            print 'INFO.077.07071: rr[8] matched .... ', rr[8]
530            ##vl0 = map( string.strip, string.split( rr[8], ',' ) )
531            vl0 = map8( rr[8] )
532          else:
533            if rr[7] == 'list':
534              print 'WARN.077.07070: ',rr
535            vl0 = None
536
537          if vl0 != None:
538            vl = set()
539            for v in vl0:
540              if string.find( v, '[' ) != -1:
541                bits = string.split( v, '[' )
542                vl.add( (bits[0],bits[1][:-1]) )
543              else:
544                vl.add(v)
545            m = str(rr[1])
546
547            self.varGroupSubset[str(rr[-1])][rr[0]] = vl
548            self.varGroupSs2[str(rr[-1])].a[(m,tuple(vl))].append(rr[0])
549            print 'INFO.077.07080: ',m,vl, rr[-1]
550
551##
552## not finding new variables .... may be better to redefine the groups ...
553##
554###
555### get full list of variables for each variable group
556###
557      thissh = self.skey['requestvar']
558      kk = ['label', 'table', 'mip', 'vid', 'priority','vgid','title','uid']
559      varGroupFull = collections.defaultdict( dict )
560      for k in thissh:
561        if k[0] != '_':
562          ll = thissh[k][:]
563          vgid = self.prqv.rqv_vg['%s.%s.%s' % (ll[2],ll[1],ll[0])]
564          ##if ll[1][:4] == 'DYVR':
565          print 'INFO.802.00001: ',ll, vgid in self.varGroupSubset.keys()
566          if vgid in self.varGroupSubset.keys():
567             varGroupFull[vgid][ll[0]] = k
568
569      for ll in self.rqv:
570          vgid = ll[  self.rqvinfo.index('gpid') ]
571          if vgid in self.varGroupSubset.keys():
572             varGroupFull[vgid][ll[1]] = ll[0]
573###
574### check that all variable groups covered
575###
576      nf = []
577      for k in self.varGroupSubset.keys():
578       if not (k in varGroupFull):
579         nf.append(k)
580
581      if len(nf) != 0:
582        for k in nf:
583          for k2 in self.varGroupSubset[k].keys():
584            print 'ERROR.080.06000: Variable group not found: ',k,k2,self.varGroupSubset[k][k2]
585##
586## some missing groups ...
587## appear to be missing MIP tables, e.g. CCMI_monthly
588## CCMI_monthly exists, but has no variables linking to it.
589##
590        print 'ERROR.080.06000:  %s %s' % (len(nf),len(varGroupFull.keys()))
591
592
593      shrvg = self.skey['requestvargroup']
594      for k in self.varGroupSs2:
595        if k not in varGroupFull:
596          print 'ERROR.080.06001: not in varGroupFull: %s [%s] %s' % (k,str(self.varGroupSs2[k].a.keys()), str( shrvg[k] ) )
597
598      self.rqvClone = collections.defaultdict( list )
599      self.rqvgrpExtra = []
600      self.rqlRedirect = {}
601      for k in varGroupFull:
602        for m,k2 in self.varGroupSs2[k].a:
603          ok1 = []
604          for i in k2:
605            i1 = i
606            if type(i) in [type(''),type(u'')]:
607              if string.find( i, 'and ' ) != -1:
608                i1 = string.split(i)[-1]
609                print 'INFO.099.09090: split i:',i,i1
610              ok1.append( varGroupFull[k].has_key(i1) )
611            elif type(i) == type( () ) and len(i) == 2:
612              ok1.append( varGroupFull[k].has_key(i[0]) or varGroupFull[k].has_key(i[1]) )
613            else:
614              print 'ERROR.080.06055: skipping unrecogised element: ',i
615              ok1.append( False )
616
617          ok = all( ok1 )
618          if not ok:
619            k2m = [  k2[i]  for i in range(len(k2)) if not ok1[i] ]
620            print 'ERROR.080.06060: not all vars found [%s] %s' % ( k, str(k2m) )
621          else:
622##
623## create new variable group and update link(s)
624##
625            gpid = str( uuid.uuid1() )
626            for rqlid in self.varGroupSs2[k].a[(m,k2)]:
627              self.rqlRedirect[rqlid] = gpid
628              ##kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
629## e.g. ['4db2f616-6d9e-11e5-b29a-ac72891c3257', 'DAMIP', u'DynVar-day', u'DAMIP: DynVar-day', 'new', u'DynVar.DYVR_daily']
630            ll =  rq.rqvg[k][:]
631            ll[0] = gpid
632            ll[2] += '-subset'
633            ll[-1] += ' (subset)'
634            self.rqvgrpExtra.append( ll )
635            print 'INFO.080.06060: subset validated, ', ll
636            for i in k2:
637##
638## set a marker to clone request variable record, with new group id
639##
640              i1 = i
641              if type(i) == type( () ) and len(i) == 2:
642                if varGroupFull[k].has_key(i[0]):
643                  i1 = i[0]
644                else:
645                  i1 = i[1]
646              elif string.find( i, 'and ' ) != -1:
647                i1 = string.split(i)[-1]
648              self.rqvClone[varGroupFull[k][i1]].append( gpid )
649
650  def finishRequestLink(self):
651    this = self.doc.getElementsByTagName('requestVarGroup')[0]
652## e.g. ['4db2f616-6d9e-11e5-b29a-ac72891c3257', 'DAMIP', u'DynVar-day', u'DAMIP: DynVar-day', 'new', u'DynVar.DYVR_daily']
653    kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
654    for ll in self.rqvgrpExtra:
655         item = self.doc.createElement( 'item' )
656         thisd = {}
657         for j in range(len(kk)):
658              if kk[j] == 'refNote':
659                item.setAttribute( kk[j], str( ll[j] ) + '((isd.010))' )
660                thisd[kk[j]] = str( ll[j] ) + '((isd.010))'
661              else:
662                item.setAttribute( kk[j], str( ll[j] ) )
663                thisd[kk[j]] = str( ll[j] )
664         this.appendChild( item )
665         self.rqvgList.append( thisd )
666##
667
668  def prep01(self):
669#### prepare some links for request variables
670    addex = True
671    self.prqv = ivg.prepRequestVar(addex)
672    self.prqv.run()
673
674  def prep(self,rq):
675## keys here match section element names in schema
676    #for k in [ 'var','ovar','groupitem', 'revisedtabitem']:
677## lists for 3 new sections
678### uuid, spid, tmid, cell_methods, cell_measures, description, procNote, prov
679    structure = [] 
680    self.structInfo = {}
681### uuid, label, dimensions, shape, levels, levelFlag
682    spatialshp = []
683### uuid, label, dimension, tstyle
684    temporalshp = []
685### cmor variables
686    self.cmv = []
687    self.rqvList = []
688    self.rqvgList = []
689    self.cmvUidByFL = collections.defaultdict( cls_s1 )
690    self.cmvUidByTab = collections.defaultdict( cls_s1 )
691    self.cmvUidByTVP = collections.defaultdict( list )
692    self.cmvByLab = collections.defaultdict( dict )
693    self.cmvs = set()
694    self.cmvinfo = ('uid','stid','label','title','description','vid', \
695                    'deflate_level', 'shuffle', 'ok_max_mean_abs', 'flag_meanings', 'type', 'ok_min_mean_abs',  \
696                    'deflate', 'valid_min', 'flag_values', 'modeling_realm', 'valid_max', 'positive', 'mipTable', \
697                    'prov', 'provNote', 'frequency', 'rowIndex', 'coordinates','defaultPriority','mipTableSection')
698    self.cmvinfo2 = ('uid','stid','label','title','description','vid', \
699                    'deflate_level', 'shuffle', 'ok_max_mean_abs', 'type', 'ok_min_mean_abs',  \
700                    'deflate', 'valid_min', 'modeling_realm', 'valid_max', 'positive', 'mipTable', 'mipTableSection',  \
701                    'prov', 'provNote', 'frequency', 'rowIndex', 'defaultPriority')
702    self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
703
704
705    thissh = self.skey['var']
706    self.varUidByName = self.importWbMods.vars.c1
707    ##self.varUidByName = collections.defaultdict( list )
708    if self.newImport:
709      oo = open('refDefaultP.txt', 'w' )
710      for k in thissh:
711         if k[0] != '_':
712##['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0']
713            thisuuid = str(k)
714            self.defaultP[thisuuid] = thissh[k][-1]
715            oo.write( '%s\t%s\t%s\t%s\n' % (k, thissh[k][0], thissh[k][2], thissh[k][-1] ) )
716            ##self.varUidByName[thissh[k][0]].append( thisuuid )
717      oo.close()
718    else:
719      ## ['label', 'title', 'description', 'procComment', 'procnote', 'prov', 'provmip', 'sn', 'units', 'uid','defaultp']
720      self.vars = collections.defaultdict( list )
721      self.vars1 = collections.defaultdict( list )
722      for uid in self.importWbMods.vars.d1:
723        self.defaultP[uid] = self.importWbMods.vars.d1[uid][-1]
724## collection indexed by short_name
725        self.vars1[self.importWbMods.vars.d1[uid][0]].append( uid )
726## collection indexed by standard_name
727        self.vars[self.importWbMods.vars.d1[uid][7]].append( uid )
728
729### request variables
730    self.rqv = []
731    self.realmByVar = collections.defaultdict( list )
732    for ksect in [ 'ovar','groupitem']:
733      thissh = self.skey[ksect]
734      if ksect == 'ovar':
735            setu1 = set()
736            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']
737            id = kk.index('dimensions')
738            ivid = kk.index('vid')
739            thisnt = collections.namedtuple( 'ovar', kk )
740            ov = []
741            dset = set()
742            ds2 = set()
743            ovuu = {}
744            for k in thissh:
745              if k[0] != '_':
746                rr = thissh[k][:]
747                if rr[id] == 's|c|a|l|a|r':
748                  print 'ERROR.060.0001: bad dimension string detected and corrected: %s' % rr[id]
749                  rr[id] = ''
750                if string.find( rr[23], 'plevs' ) != -1:
751                   print 'INFO.qqqq01: ',rr[21:24]
752                rr[23] = string.replace(rr[23], 'plevs', 'plev17')
753                if rr[24][-3:] in ['700','200','850','000']:
754                  print 'INFO.022.0001: Setting p... coordinate for ',rr[24]
755                  if rr[24][-3:] == '000':
756                    assert rr[24][-4:] == '1000',str(rr)
757                    thisc = 'p%s' % rr[24][-4:]
758                  else:
759                    thisc = 'p%s' % rr[24][-3:]
760                  if thisc not in rr[id]:
761                    rr[id] += '|' + thisc
762                tt = thisnt._make( rr ) 
763                if tt.uid in setu1:
764                  print 'ERROR.099.0002: duplicate uuid: %s: %s' % (uuid,str(rr))
765                if str(tt.vid) == '__var_not_found_012__':
766                  print 'ERROR.099.00102: bad vid string: %s [%s]' % (tt.vid,tt.out_name)
767                       
768                if str(tt.vid) not in self.importWbMods.vars.d1:
769                  if tt.out_name in self.importWbMods.vars.c1:
770                    if len( self.importWbMods.vars.c1[ tt.out_name ] ) == 1:
771                      rr[ivid] = self.importWbMods.vars.c1[ tt.out_name ][0]
772                      tt = thisnt._make( rr ) 
773                      print 'INFO.099.00103: bad vid string replaced: %s [%s]' % (tt.vid,tt.out_name)
774                    else:
775                      print 'ERROR.099.00104: ambiguous bad vid string: %s [%s]' % (tt.vid,tt.out_name)
776                  else:
777                    print 'ERROR.099.00105: bad vid string: %s [%s]' % (tt.vid,tt.out_name)
778                setu1.add(tt.uid)
779                ov.append( tt )
780                dset.add( ov[-1].dimensions )
781                ds2.add( (tt.dimensions,tt.cell_methods,tt.cell_measures,tt.flag_values, tt.flag_meanings) )
782                ovuu[tt.uid] = tt
783                if rr[22][-3:] in ['mon','day','3hr']:
784                  fr = rr[22][-3:]
785                elif rr[22][-2:] in [ 'yr','fx']:
786                  fr = rr[22][-2:]
787                else:
788                  fr = tab2freq[rr[22]]
789   
790                prov = '%s ((isd.003))' % tt.mipTable
791                if tt.mipTable[:4] == 'OMIP':
792                  prov = 'CMIP6 [OMIP] ((isd.001))'
793                elif string.find( tt.mipTable, '_' ) != -1:
794                  prov = '%s [%s] ((isd.002))' % tuple( string.split( tt.mipTable, '_' ) )
795
796                if tt.var[:5] == 'xx..ccmi_':
797                  pass
798                else:
799                  lab = tt.var
800                  if lab in {'*','include Oyr 3D tracers'}:
801                    lab = '-copy-'
802##
803## insert conditional on redundant tables here ...
804##
805                  if tt.mipTable in redundantTables:
806                    if tt.mipTable not in reportedRedundantTables:
807                      print 'INFO.000.11111: redundant table spotted: ',tt.mipTable
808                      reportedRedundantTables.add( tt.mipTable )
809                  else:
810                    if tt.uid in self.cmvs:
811                       print 'ERROR.090.09010: duplicate cmv uid :',tt.__dict__
812                    self.cmvs.add( tt.uid )
813                    if lab != '-copy-' and string.find( lab, '-' ) != -1:
814                      print 'ERROR.207.00010: bad character in label: %s' % lab
815                      lab = string.replace( lab, '-', '' )
816                    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, \
817                      tt.deflate_level, tt.shuffle, tt.ok_max_mean_abs, tt.flag_meanings, tt.type, tt.ok_min_mean_abs, \
818                      tt.deflate, tt.valid_min, tt.flag_values, tt.modeling_realm, tt.valid_max, tt.positive, tt.mipTable, \
819                      prov, tt.ssect, fr, tt.rowIndex, '',int(tt.priority), tt.ssect) )
820                    self.realmByVar[ lab ].append( tt.modeling_realm )
821                    if string.strip( tt.gpid ) == '':
822                       print 'ERROR.090.0990: blank gpid: ',lab,tt.mipTable
823                    vgid = tt.gpid
824                    if tt.mipTable[:4] == 'OMIP':
825                       m,t = string.split( tt.mipTable, '.' )
826                       vgid = self.prqv.getvgid( [None,t,m] )
827                       if vgid[0] != '_':
828                         if vgid != tt.gpid:
829                           print 'INFO.090.0990: link repare:',tt.gpid,lab,tt.mipTable,vgid
830                    self.rqv.append( (str( uuid.uuid1() ),lab, tt.uid, vgid, tt.priority,tt.mipTable,tt.mipTable) )
831                    if lab == 'sisnconc':
832                      print 'INFO.sisnconc.0002:', self.rqv[-1]
833                    thisd = {}
834                    for k9 in range(len(self.rqvinfo)):
835                      thisd[self.rqvinfo[k9]] = self.rqv[-1][k9]
836                    self.rqvList.append( (thisd, 'prep:thisd' ) )
837                    if vgid not in self.varGroupUids:
838                      print 'ERROR.099.09901: bad vgid: ',self.rqv[-1]
839    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
840            self.dsort( dset )
841            print self.dsortdd[ksect][0].keys()
842
843      elif ksect == 'groupitem':
844            kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'priority', 'mip', 'uid', 'rowIndex', 'new', 'gpid', 'vkey', 'vid']
845            thisnt = collections.namedtuple( 'groupitem', kk + ['cmorv',] )
846            il = kk.index( 'levels' )
847            iu = kk.index( 'uid' )
848            idx = kk.index( 'descriptionEx' )
849            ixvid = kk.index( 'vid' )
850            ixvar = kk.index( 'var' )
851            ixp = kk.index( 'priority' )
852            dset = set()
853            dsgpi = set()
854            gi = []
855            s1 = set()
856            sm = set()
857            varsets = []
858            nov = 0
859            setu = set()
860            for k in thissh.keys():
861              if k[0] != '_':
862                rr = thissh[k][:]
863                if trace.GROUPITEM_ta and rr[ixvar] == 'ta':
864                  print 'INFO.045.00004: groupitem: ',rr
865
866                if rr[ixvar] == 'sisnconc':
867                  print 'INFO.sisnconc.0010:',rr
868
869##
870## convert floats back to integer
871##
872                if type(rr[ixp]) == type(1.):
873                  rr[ixp] = int(rr[ixp])
874##
875## split variable, create 2nd record at 23 levels.
876##
877                if rr[iu] in setu:
878                  print 'ERROR.099.0001: duplicate uuid in varGroups ... %s:: %s' % (uuid,str(rr))
879                if rr[iu] in setu1:
880                  print 'ERROR.099.0003: duplicate uuid in varGroups/ovar ... %s:: %s' % (uuid,str(rr))
881                setu.add(rr[iu])
882                if rr[il] in  {u'17 (or 23 )', u'17 (or 23)', u'17 (or23)', u'10/17/23'}:
883                  if rr[il] == u'10/17/23':
884                     lev0 = 10
885                     levsp = [17,23]
886                  else:
887                     lev0 = 17
888                     levsp = [23,]
889                  rr[ixp] = 1
890                  p = 1
891                  for lp in levsp:
892                    p += 1
893                    rr0 = rr + [rr[1] + str(lp),]
894                    rr0[ixp] = p
895                    rr0[il] = lp
896                    rr0[iu] = str( uuid.uuid1() )
897                    tt = thisnt._make( rr0 )
898                    if str(tt.vid) == '__var_not_found_012__':
899                      print 'ERROR.099.00104: bad vid string: %s [%s]' % (tt.vid,tt.var)
900                    gi.append( tt )
901                    varsets.append( (rr0[iu], 2, rr[iu], 1, 'variables at multiple vertical resolutions' ) )
902                  rr[il] = lev0
903                  tt = thisnt._make( rr + [rr[1] + str(lev0),] )
904                elif rr[il] in [u'Model levels or plev_27', u'Model levels or 27Plevs',u'27',27.]:
905                  rr0 = rr + [rr[1] + '27',]
906                  print 'INFO.0088.07007: ',rr0
907                  rr0[il] = 27
908                  rr0[iu] = str( uuid.uuid1() )
909                  if str(rr0[ixvid]) == '__var_not_found_012__':
910                    if str(rr0[ixvar]) in self.varUidByName:
911                      if len( self.varUidByName[rr0[ixvar]] ) == 1:
912                        rr0[ixvid] = self.varUidByName[rr0[ixvar]][0]
913                  tt = thisnt._make( rr0 )
914                  if str(tt.vid) == '__var_not_found_012__':
915                    print 'ERROR.099.00105: bad vid string: %s [%s]' % (tt.vid,tt.var)
916##
917## no longer requesting all option of "all or ..."
918##
919                  ##gi.append( tt )
920                  ##rr[il] = 'all'
921                  ##tt = thisnt._make( rr + [rr[1],] )
922                  varsets.append( (rr0[iu], 0, rr[iu], 0, 'Variables on model levels or 27 pressure levels' ) )
923                elif string.find( rr[idx], '850 hPa' ) != -1:
924                  print 'INFO.0099.0016: ', rr
925                  if rr[1][-3:] != '850':
926                    rr = rr + [rr[1] + '850',]
927                  else:
928                    rr = rr + [rr[1],]
929                  tt = thisnt._make( rr )
930                else:
931##
932## this point ... to mark HighResMIP 7 levels as distinct from CFMIP.
933## enough information in "mip" tag of tt record
934##
935                  if type( rr[il] ) == type(1.):
936                    if rr[il] == 7. and rr[10] == 'HighResMIP':
937                      print 'INFO.qqq03:',rr[il],rr
938                      rr[5] = rr[5] + '*'
939                  if str(rr[ixvid]) == '__var_not_found_012__':
940                    ok = False
941                    if str(rr[ixvar]) in self.varUidByName:
942                      if len( self.varUidByName[rr[ixvar]] ) == 1:
943                        rr[ixvid] = self.varUidByName[rr[ixvar]][0]
944                        print 'INFO.099.00106: correcting vid for %s' % rr[ixvar]
945                        ok = True
946                    if not ok:
947                        print 'WARN.099.00106: error in vid for %s not corrected' % rr[ixvar]
948                  tt = thisnt._make( rr + [rr[1],] )
949                  if str(tt.vid) == '__var_not_found_012__':
950                    print 'ERROR.099.00106: bad vid string: %s [%s]' % (tt.vid,tt.var)
951                 
952                if str(tt.mip) != 'OMIP':
953                  gi.append( tt )
954                  ##if tt.mip == 'SIMIP' and tt.mask == 'yes':
955                    ##sm.add( 'seaIce' )
956                  ##else:
957                  sm.add( tt.mask )
958
959            print '####### masks: ',sm
960            smdd = {}
961            dsn = {'floating ice shelf':u'floating ice sheet', u'ocean':u'sea', 'yes':'seaIce' }
962            d1 = {u'land':(False,'area: mean where land'), \
963                  u'grounded ice sheet':(True,'area: mean where grounded_ice_sheet'), \
964                  u'ice sheet':(True,'area: mean where ice_sheet'), \
965                  u'floating ice sheet':(True,'area: mean where floating_ice_sheet'), \
966                  u'where snow on sea ice':(True,'area: mean where snow over sea_ice'), \
967                  u'where melt ponds':(True,'area: mean where melt_pond over sea_ice'), \
968                  u'where ridge':(True,'area: mean where sea_ice_ridge over sea_ice'), \
969                  u'where sea ice':(True,'area: mean where sea_ice'), \
970                  u'floating ice shelf':(True,'area: mean where floating_ice_sheet'), \
971                  u'seaIce':(True,'area: mean where sea_ice over sea'), \
972                  u'sea':(False,'area: mean where sea') }
973
974            for s in sm:
975              if s in  ['', 'no', u'none',u'Southern hemisphere', u'Northern hemisphere']:
976                smdd[s] = (False,'')
977              else:
978                s1 = string.strip(s)
979                try:
980                  smdd[s] = d1[ dsn.get( s1,s1 ) ]
981                except:
982                  print s, dsn.get( s1,s )
983                  raise
984
985            setu = set()
986
987            ccchk = ivg.checkCmv(gi)
988            nrep = 0
989
990            for tt in gi:
991                gr = 'a'
992                if tt.mip == 'OMIP' \
993                    or any( [string.find(tt.table,i) != -1 for i in ['Omon','Oyr','Oclim','OImon','Ocean'] ] ) \
994                    or any( [string.find(tt.group,i) != -1 for i in ['Omon','Oyr','Oclim','OImon','Ocean'] ] ):
995                  gr = 'o'
996                if self.varsxx != None:
997                  if tt.cmorv in self.varsxx:
998                    sss = set()
999                    for k in self.varsxx[tt.cmorv]:
1000                      sss.add(self.skey['var'][k][-1] )
1001                    sss = list(sss)
1002                    if len(sss) == 1:
1003                      if sss[0] == 'ocean':
1004                        gr = 'o'
1005                      elif sss[0] == 'atmos':
1006                        gr = 'a'
1007                    print 'INFO:lllw:', tt.cmorv, sss, gr
1008                if tt.cmorv in ['talknat', 'sltbasin']:
1009                   print 'INFO.llll: ',tt,gr
1010##
1011## adding label for mip here messes up referencing later ...
1012##
1013
1014                if tt.mip == 'SIMIP':
1015                  grprov = "SIMIP"
1016                else:
1017                  grprov = ""
1018
1019                if tt.cmorv[-3:] in ['700','200','300','850','000']:
1020                  print 'INFO.022.0002: Setting p... coordinate for ',tt
1021                  if tt.cmorv[-5:] in [ 't2000']:
1022                    thisc = 't2000'
1023                  elif tt.cmorv[-5:] in [ 't300', 't700']:
1024                    thisc = tt.cmorv[-4:]
1025                  elif tt.cmorv[-3:] == '000':
1026                    assert tt.cmorv[-4:] == '1000',str(tt)
1027                    thisc = 'p%s' % tt.cmorv[-4:]
1028                  else:
1029                    thisc = 'p%s' % tt.cmorv[-3:]
1030                  thissh  = '%s|%s' % (tt.shape, thisc)
1031                else:
1032                  thissh = tt.shape
1033
1034                dset.add( (thissh, tt.levels,tt.tstyle,gr) )
1035                dsgpi.add( (thissh,tt.levels,tt.tstyle,gr,smdd[tt.mask], 'None', 'None', grprov) )
1036### need to check where variables are, perhaps, refering to "ovar"
1037            ##kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'rowIndex', 'new', 'gpid', 'vkey', 'vid']
1038                prov = '%s [%s]' % (tt.mip,tt.group)
1039                provNote = ''
1040                lab = tt.cmorv
1041                if lab in {'*','include Oyr 3D tracers'}:
1042                  lab = '-copy-'
1043                elif lab == 'wap (omega)':
1044                  lab = 'wap'
1045                  provNote = 'wap (omega)'
1046                lab = string.replace( string.strip(lab), '_', '-' )
1047                if tt.uid in setu:
1048                     print 'SEVERE[1]: duplicate uuid: ',tt.__dict__
1049                setu.add( tt.uid )
1050                fr = freqmap.get( tt.freq, tt.freq )
1051                ntab = 'em%s' % string.capwords( fr )
1052                if fr == '6hr' and tt.levels in ['7h',4.0, '4']:
1053                  ntab = '6hrPlev'
1054                  print 'INFO.033.00001: adding to 6hrPlev ....',lab, tt.__dict__
1055               
1056                if ovuu.has_key(tt.vid):
1057                  tt1 = ovuu[tt.vid]
1058                  if tt1.modeling_realm == 'seaIce':
1059                    ntab = 'OImon'
1060                  if tt.priority in [1,2,3]:
1061                    p = tt.priority
1062                  else:
1063                    p = int(tt1.priority)
1064                  thisrealm = tt1.modeling_realm
1065                  if gr == 'o' and thisrealm == 'atmos':
1066                    thisrealm = 'ocean'
1067                  thiscmv = (tt.uid, (thissh,tt.levels,tt.tstyle,gr,smdd[tt.mask],tt1.flag_values,tt1.flag_meanings), lab, '__from %s' % tt.table, tt.descriptionEx, tt1.vid, \
1068                    tt1.deflate_level, tt1.shuffle, tt1.ok_max_mean_abs, tt1.flag_meanings, tt1.type, tt1.ok_min_mean_abs, \
1069                    tt1.deflate, tt1.valid_min, tt1.flag_values, thisrealm, tt1.valid_max, tt1.positive, ntab, \
1070                    prov, provNote, tt.freq, tt.rowIndex, '', int(p),'') 
1071                  self.realmByVar[ lab ].append( thisrealm )
1072                  thisrqv = [str( uuid.uuid1() ),lab, tt.uid, tt.gpid, p, tt.mip, tt.group]
1073                  if lab == 'sisnconc':
1074                    print 'INFO.sisnconc.0001a:', thisrqv
1075                  nov += 1
1076                else:
1077                  thisrealm = ''
1078                  if realmdefix.has_key( prov ):
1079                    thisrealm = realmdefix[prov]
1080                  else:
1081                    print 'WARN:070.00001: realm not found for %s,%s' % (lab,prov)
1082                  if gr == 'o' and thisrealm == 'atmos':
1083                    thisrealm = 'ocean'
1084
1085                  if thisrealm == 'seaIce':
1086                    ntab = 'OImon'
1087
1088                  if tt.priority in [1,2,3]:
1089                    p = tt.priority
1090                    ptr = 1
1091                  elif  self.defaultP.get( tt.vid, 102) in [1,2,3]:
1092                    p = self.defaultP.get( tt.vid, 102)
1093                    ptr = 2
1094                  else:
1095                    p = 1
1096                    print 'WARN:070.00002: priority defaulting to 1 for %s,%s' % (lab,prov)
1097                    ptr = 3
1098
1099                  if lab != '-copy-' and string.find( lab, '-' ) != -1:
1100                      print 'ERROR.207.00020: bad character in label: %s' % lab
1101                      lab = string.replace( lab, '-', '' )
1102
1103                  thiscmv = (tt.uid, (thissh,tt.levels,tt.tstyle,gr,smdd[tt.mask], 'None', 'None'), lab, '__from %s' % tt.table, tt.descriptionEx, tt.vid, \
1104                    0, 0, 0, 0, '', 0, \
1105                    0,0,0, thisrealm, 0, '', ntab, \
1106                    prov, provNote, tt.freq, tt.rowIndex, '', str(p), '') 
1107                  self.realmByVar[ lab ].append( thisrealm )
1108
1109                  thisrqv = [str( uuid.uuid1() ),lab, tt.uid, tt.gpid, p, tt.mip, tt.group] 
1110                  if lab == 'sisnconc':
1111                    print 'INFO.sisnconc.0001b:', thisrqv, ptr, thiscmv
1112                if trace.GROUPITEM_ta and lab  == 'ta':
1113                    print 'INFO.045.00005: groupitem: ',thisrqv
1114                if "t2000" in thissh:
1115                   print 'BBBB', thiscmv
1116
1117
1118                if ccchk.uidReplace.has_key(thiscmv[0]):
1119                  nrep += 1
1120                  thisrqv[2] = ccchk.uidReplace[thiscmv[0]]
1121                else:
1122                  self.cmv.append( thiscmv )
1123                self.rqv.append( thisrqv )
1124                if self.rqv[-1][3] not in self.varGroupUids:
1125                      print 'ERROR.099.09902: bad vgid: ',self.rqv[-1]
1126## Variables marked with shape '?' from PMIP are actually defined by OMIP ....
1127                if tt.shape == '?':
1128                  print 'ERROR.801.00001: shape not set: %s, %s, %s' % ( tt.shape,tt.mip,tt.var)
1129
1130            ##['', 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']
1131            self.dsort( dset,mode=ksect )
1132            print 'INFO.088.00001: nrep=%s' % nrep
1133            print 'INFO.088.00002: nov=%s [%s]' % (nov,len(gi))
1134
1135
1136    nrep = []
1137    for c in self.cmv:
1138      u,v,f,t,p,pn = (c[0],c[2],c[21],c[18],c[19],c[20])
1139      self.cmvUidByFL[f].a[v].append( u ) 
1140      self.cmvUidByTab[t].a[v].append( u ) 
1141      if v[0] != '-':
1142        if (t,v,p) in self.cmvUidByTVP:
1143          nrep.append( (t,v,p)  )
1144      self.cmvUidByTVP[ (t,v,p) ].append( u )
1145      self.cmvByLab[v][ u ]  = (f,t)
1146    if len( nrep) > 0:
1147       print 'WARN.108.00088: unresolved .... %s' % len(nrep)
1148       for n in nrep:
1149         print n
1150
1151#######################################################################################
1152#################
1153    std = set()
1154    ssd = set()
1155    etd = {}
1156    esd = {}
1157    tshp = { 'time':['time-mean','Temporal mean'], 'time1':['time-point','Instantaneous value (i.e. synoptic or time-step value)'], \
1158             'time2':['climatoglogy','Climatological mean'], \
1159             '':['None','No temporal dimensions ... fixed field'], 'xxxx':['unknown','dimension not recognised'] }
1160
1161    for ksect in [ 'ovar','groupitem']:
1162#### create structure list for spatial and temporal dimensions
1163      for t in self.dsortdd[ksect][0].keys():
1164        tdim, tt = self.dsort_u1( self.dsortdd[ksect][0][t], self.dsortdd[ksect][1] )
1165
1166        std.add( tdim )
1167        ssd.add( tt )
1168        ##ssd.add( (sdim,lfl,nl) )
1169
1170    for s in std:
1171       label, description = tshp.get(s,tshp['xxxx'])
1172       u = str( uuid.uuid1() )
1173       etd[s] = (u,label,description,s)
1174    kk = 0
1175    self.spidInfo = {}
1176    for s in ssd:
1177       d,lfl,nl = s
1178       u = str( uuid.uuid1() )
1179       kk+=1
1180       lab = 'ssd-%3.3i' % kk
1181       description = 'ssd.%3.3i' % kk
1182       esd[s] = (u,lab,description,d,lfl,nl)
1183       self.spidInfo[u] = (u,lab,description,d,lfl,nl)
1184
1185    esd['Y-na'] = (str( uuid.uuid1() ),'extra','extra','latitude','false',1)
1186    self.dimsTime = etd
1187    self.dimsTimeInfo = ['uid','label','title','dimensions']
1188    self.dimsSpace = esd
1189    self.dimsSpaceInfo = ['uid','label','title','dimensions','levelFlag','levels']
1190       
1191    sshp = set()
1192    eshp = set()
1193    ll = []
1194    lls = ivg.structureList()
1195    nt_dims = collections.namedtuple( 'dims', ['uid','label','spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','description','procNote','prov'] )
1196    kk = 0
1197    strdd = {}
1198    ee3 = {}
1199    for dims,cmet,cmea,flgv, flgm in ds2:
1200        tdim, tt = self.dsort_u1( self.dsortdd['ovar'][0][dims], self.dsortdd['ovar'][1] )
1201        d1,odim,d2,crd = self.dsortdd['ovar'][0][dims]
1202        sdim,lfl,nl = tt
1203        u = str( uuid.uuid1() )
1204        spid = esd[tt][0]
1205        tmid = etd[tdim][0]
1206        kk += 1
1207        label = 'str-%3.3i' % kk
1208        proc = ''
1209        prov = 'CMIP5/OMIP'
1210        desc = ''
1211        print 'INFO.zzz01: ',dims, crd
1212        t0 = (dims,cmet,cmea,flgv,flgm)
1213        if cmet == 'None':
1214          cmet = ''
1215        if cmea == 'None':
1216          cmea = ''
1217        if flgv == 'None':
1218          flgv = ''
1219        if flgm == 'None':
1220          flgm = ''
1221        t1 = (dims,cmet,cmea,flgv,flgm)
1222        u = lls.add( [u,label,spid,tmid, odim, crd, cmet, cmea, flgv, flgm, desc, proc, prov] )
1223        self.structInfo[u] = (label,cmet,spid)
1224        strdd[t0] = u
1225        strdd[t1] = u
1226         
1227
1228    ttt = [ {u'Instantaneous (end of year)', 'instantaneous', 'point', 'Synoptic', u'synoptic', u'time: point'},
1229        {'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(), {''}]
1230    cmetl = ['time: point', 'time: mean', 'time: mean within years time: mean over years ', '']
1231    cmetlsi = ['time: point', ('time: mean area: mean where sea_ice over sea','time: mean where sea_ice area: mean where sea_ice'), 'time: mean within years time: mean over years ', '']
1232    ee1 = {}
1233    for shp,lvls,sty,gr,tmsk, flgv, flgm, prov in dsgpi:
1234        t = (shp,lvls,sty,gr)
1235        if "t2000" in shp:
1236           print 'CCCC',shp,lvls,sty,gr,tmsk, flgv, flgm, prov
1237        tdim, tt = self.dsort_u1( self.dsortdd['groupitem'][0][t], self.dsortdd['groupitem'][1] )
1238        d1,odim,d2,crd = self.dsortdd['groupitem'][0][t]
1239        print 'INFO.099.6666: ',d1,odim,d2,crd
1240        tflm, msk = tmsk
1241        sdim,lfl,nl = tt
1242        u = str( uuid.uuid1() )
1243        spid = esd[tt][0]
1244        tmid = etd[tdim][0]
1245        cmea = 'area: areacell%s' % gr
1246        cmet = ''
1247        if sty == u'weighted time mean':
1248           print 'INFO.xxxx: ',shp,lvls,sty,gr,tmsk, flgv, flgm, prov
1249        for i in range(4):
1250          if sty in ttt[i]:
1251            if i == 1 and prov == 'SIMIP':
1252              if sty == u'weighted time mean':
1253                 cmet = 'time: mean where sea_ice area: mean where sea_ice'
1254              else:
1255                 cmet = 'time: mean area: mean where sea_ice over sea'
1256            else:
1257              cmet = cmetl[i]
1258        if cmet == '':
1259          cmet = msk
1260        elif msk != '':
1261          cmet += ' ' + msk
1262        kk += 1
1263        label = 'str-%3.3i' % kk
1264        proc = ''
1265        if prov == '':
1266          prov = 'CMIP5, endorsed MIPs'
1267        desc = ''
1268        dims = tt[0]
1269        if tdim != '':
1270          dims += '|' + tdim
1271        if strdd.has_key( (dims,cmet,cmea,'','') ) and crd == '':
1272          u = strdd[ (dims,cmet,cmea,'','') ]
1273          print 'INFO.zzz03: ',tt, tdim
1274        elif ee1.has_key( (tmid, spid, odim, cmet, cmea, crd) ):
1275          u = ee1[(tmid, spid, odim, cmet, cmea, crd)]
1276          print 'INFO.zzz04: ', tt, tdim
1277        else:
1278          print 'INFO.zzz02: ',tt, tdim
1279          u = lls.add( [u,label,spid,tmid, odim, crd, cmet, cmea, '', '', desc, proc, prov]  )
1280          ##nt =  nt_dims._make( [u,label,spid,tmid, odim, crd, cmet, cmea, '', '', desc, proc, prov] )
1281          ##tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1282          ##if ee3.has_key( tt ):
1283            ##u = ee3[tt]
1284          ##else:
1285            ##ee3[tt] = u
1286            ##ll.append( nt )
1287           
1288          ee1[(tmid, spid, odim, cmet, cmea, crd)] = u
1289        if sty == u'Synoptic':
1290          print 'yyyy: ',(shp,lvls,sty,gr,tmsk,flgv,flgm)
1291        if "t2000" in shp:
1292          print 'CCCC: ',(shp,lvls,sty,gr,tmsk,flgv,flgm), u, (label,cmet,spid)
1293        strdd[(shp,lvls,sty,gr,tmsk,flgv,flgm)] = u
1294        self.structInfo[u] = (label,cmet,spid)
1295
1296    ##nt_dims = collections.namedtuple( 'dims', ['uid','label','spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','description','procNote','prov'] )
1297    cc = collections.defaultdict( list )
1298    for nt in lls.ll:
1299      tt = tuple( [nt.__dict__[k] for k in ['spid','tmid','odims','coords','cell_methods','cell_measures','flag_values','flag_meanings','procNote','prov']] )
1300      cc[tt].append( nt.uid )
1301    ks = [k for k in cc.keys() if len( cc[k] ) > 1]
1302    if len( ks ) > 0:
1303      print 'DUPLICATE STRUCTURES'
1304      for k in ks:
1305        print 'DUPLICATE: ',k,len(cc[k])
1306     
1307    self.structList = lls.ll
1308    self.strdd = strdd
1309    oo = open( 'test.csv', 'w' )
1310    for l in ll:
1311      assert l.uid in self.structInfo, 'SEVERE: structure uid not in lookup ... %s' %  str( l.__dict__)
1312      oo.write( '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,\n' % l )
1313    oo.close()
1314
1315  def cmvAudit(self,nn):
1316    nrep = []
1317    self.cmvByUid = {}
1318    for c in self.cmv:
1319      u,v,f,t,p,pn = (c[0],c[2],c[21],c[18],c[19],c[20])
1320      self.cmvUidByFL[f].a[v].append( u ) 
1321      self.cmvUidByTab[t].a[v].append( u ) 
1322      if v[0] != '-':
1323        if (t,v,p) in self.cmvUidByTVP:
1324          nrep.append( (t,v,p)  )
1325      self.cmvUidByTVP[ (t,v,p) ].append( u )
1326      self.cmvByLab[v][ u ]  = (f,t)
1327      self.cmvByUid[u] = c
1328    if len( nrep) > 0:
1329       print 'WARN.108.00088: unresolved .... %s' % len(nrep)
1330       for n in nrep:
1331         print n
1332
1333  def addAerChem(self):
1334    import importExtra
1335    lc = importExtra.loadAerChem()
1336    es = {}
1337    et = {}
1338    for l in self.dimsSpace.keys():
1339      print self.dimsSpace[l]
1340      assert self.dimsSpace[l][1] not in es, 'Duplicate spatial dimension label: %s' % self.dimsSpace[l][1]
1341      es[self.dimsSpace[l][1]] = l
1342    for l in self.dimsTime.keys():
1343      print self.dimsTime[l]
1344      assert self.dimsTime[l][1] not in et, 'Duplicate spatial dimension label: %s' % self.dimsTime[l][1]
1345      et[self.dimsTime[l][1]] = l
1346    nt_acv = collections.namedtuple( 'acv', ['sn','title','label', 'units', 'description', 'subsect', 'freq', 'splab', 'tm' ] )
1347    freq_map = {'hourly':'1hr', 'annual':'yr', 'daily':'day', 'fixed':'fx'} 
1348    for t in lc.cc2.keys():
1349      nn = 0
1350      for v in lc.cc2[t].a:
1351        v1 = v
1352        if v not in self.vars1:
1353          print 'INFO.kkkkk: AerChem Var missing: %s, %s' % (t,v)
1354          if string.replace( v, '_', '') in self.vars1:
1355            v1 = string.replace( v, '_', '')
1356            print 'INFO.kkkkk: AerChem %s found' % (v1)
1357            vid =  self.vars1[v1][0]
1358          else:
1359            vid = '__var_not_found__'
1360        else:
1361          vid =  self.vars1[v1][0]
1362          nn += 1
1363        tt = nt_acv._make( lc.cc2[t].a[v][0] )
1364        thisrealm = 'unset'
1365        freq = freq_map.get( tt.freq, tt.freq )
1366        ntab = 'aer%s' % freq
1367        thiscmv = (str(uuid.uuid1()), (tt.splab,tt.tm), tt.label, tt.title, tt.description, vid, '','','','','float','','','','',"aero",'','',ntab,'AerChemMIP','',freq, 0, '', 1, '')
1368        self.cmv.append( thiscmv )
1369      print 'INFO.kkkkk: AerChem Vars found: %s: %s' % (t,nn)
1370
1371  def dsort_u1(self,eed,sde):
1372        tdim = eed[2]
1373        sdim = eed[0]
1374        nl = sde[sdim]
1375        lfl = 'true'
1376        if nl == -1:
1377          lfl = 'false'
1378          nl = 0
1379        elif nl == -2:
1380          nl = 1
1381          pass
1382        return (tdim, (sdim,lfl,nl) )
1383
1384
1385  def dsort( self, dset, mode='ovar' ):
1386      """Sort the dimensions string into spatial, temporal and other sections,
1387       returns a dictionary of tuples: spatial dimensions, other, temporal, coords and a 2nd, keyyed on spatial dimensions with a level count indicator.  """
1388      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}
1389      odims = {'sza5','vegtype','scatratio','dbze','typepdec','vgidx','tau'}
1390      dl = sorted( list(dset) )
1391      if mode == 'ovar':
1392        eed = {}
1393        sss = [set(),set(),set(),set()]
1394        for s in dl:
1395          if s[:4] == 'time':
1396            bits = ['',s[4:]]
1397          else:
1398            bits = string.split(s, '|time', maxsplit=1 )
1399          if len(bits) == 1:
1400            ts = ''
1401          else:
1402            ts = 'time'
1403
1404          b0 = bits[0]
1405          b1 = ''
1406          bb = string.split(bits[0],'|')
1407          if bb[-1] in odims:
1408            if bb[-1] == 'tauxxx':
1409                b0 = bits[0][:-4]
1410                ts = 'tau|time'
1411            else:
1412              b0 = string.join( bb[:-1], '|' )
1413              b1 = bb[-1]
1414           
1415          if len(bits) == 1:
1416              tup = (b0,b1,'','')
1417          elif len(bits) == 2:
1418              b2 = string.split( bits[1], '|', maxsplit=1 )
1419              if len(b2) == 2:
1420                  tup = (b0,b1, ts + b2[0], b2[1])
1421              else:
1422                  tup = (b0,b1, ts + bits[1], '')
1423          eed[s] = tup
1424          for k in range(4):
1425            sss[k].add(tup[k])
1426
1427        lcount = {}
1428        for s in sss[0]:
1429          bits = string.split( s, '|' )
1430          nl = -2
1431          thisb = None
1432          for b in bits:
1433            if vdims.has_key(b):
1434              assert nl == -2, 'Duplicate vertical level count in %s' % s
1435              nl = vdims[b]
1436              thisb = b
1437          lcount[s] = nl
1438          if nl == -1 and s == 'latitude|basin':
1439            print 'SEVERE: error in level deduction'
1440            print s, bits, nl, thisb
1441            raise
1442      else:
1443        ## input is a set of tuples,  shape, levels, tstyle, o/a
1444        ## aim is to extract spatial, other, temporal dimensions + coords.
1445        sss = [set(),set(),set()]
1446        ttt = [ ('time1', u'Instantaneous (end of year)', 'instantaneous', 'point', 'Synoptic', u'synoptic', u'time: point'),
1447        ('time', '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'), (), ('',)]
1448        ttdd = {}
1449        kkk = ['time1','time','time2','']
1450        for i in range(4):
1451          for k in ttt[i]:
1452            ttdd[k] = kkk[i]
1453
1454        ##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',] }
1455        dds = {'2D':'XYT', 'XY':'XYT', '':'?', '2D ':'XYT', 'XYZ':'XYZT', } 
1456## 'K'?? 'XYK'
1457        dd = {'XKT':('latitude|basin','','time','',False), \
1458             'XYZKT':('longitude|latitude|%s','effectRad','time','',True), \
1459             'XYZT':('longitude|latitude|%s','','time','',True), \
1460             'XYZT*':('longitude|latitude|%st','','time','',True), \
1461              'KZT':('alevel','spectband','time','',False), \
1462              'XYT':('longitude|latitude','','time','',False), \
1463              'XYKT':('longitude|latitude','angle','time','',False), \
1464              'YZT':('latitude|%s','','time','',True), \
1465              'XYK':('longitude|latitude','snowband','time','',False), \
1466              'K':('sistraits','','time','',False), \
1467              'scalar':('','','time','',False), \
1468              '':('','','time','',False), \
1469              'sheet':('icesheet','','time','',False), \
1470              'ZST1':('alevel','site','time','',False), \
1471              'BasinYT':('latitude|basin','','time','',False), \
1472              '?':( '?', '?','?','?',False)
1473             }
1474             
1475        for d in dl:
1476          for k in range(3):
1477            sss[k].add( d[k] )
1478
1479        ls0 = set()
1480        ls1 = set()
1481##
1482## sort shapes
1483##
1484        for s0 in sss[0]:
1485          if string.find( s0, '|' ) != -1:
1486            s,crd0 = string.split( s0, '|' )
1487          else:
1488            s,crd0 = s0,None
1489
1490          if not dd.has_key( dds.get(s,s) ):
1491            print 'NO SOLUTION FOUND FOR SHAPE: "%s"' % s
1492          else:
1493            tt = dd[dds.get(s,s)]
1494            if tt[-1]:
1495                ls0.add( s0 )
1496##
1497## look at shapes which require additional information about vertical coord
1498##
1499        for d in dl:
1500          if d[0] in ls0:
1501             ls1.add( d[1] )
1502
1503        lset = {'soil levels':'sdepth', 'all model levels above 400hPa':'alevel'} 
1504        lsdd = {}
1505        print 'ls1....',ls1
1506        for l in ls1:
1507          ii = 0
1508          if l in ['all','all*','all model levels']:
1509            ii = -1
1510            this = '%slevel' 
1511          elif lset.has_key(l):
1512            ii = -1
1513            this = lset[l]
1514          elif l == '':
1515            ii = -2
1516            this = l
1517          elif l == '7h':
1518            ii = 7
1519            this = 'plev7h'
1520          else:
1521            ii = int( float(l) )
1522            if ii in [40,16]:
1523              this = 'alt%s' % ii
1524            elif ii > 1.5:
1525              if ii > 35:
1526                ii = 39
1527##
1528## merge 14 and 17 level specifications to a 19 level coordinate
1529##
1530              if ii in [14,17]:
1531                ii = 19
1532             
1533              this = 'plev%s' % ii
1534              if ii == 7:
1535                this += 'c'
1536
1537            else:
1538              this = ''
1539          lsdd[l] = (ii,this)
1540##['', 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]
1541             
1542        lcount = {}
1543        eed = {}
1544        for d in dl:
1545          s0 = d[0]
1546          if string.find( s0, '|' ) != -1:
1547            s,crd0 = string.split( s0, '|' )
1548          else:
1549            s,crd0 = s0,None
1550          if not dd.has_key( dds.get(s,s) ):
1551            print 'NO SOLUTION FOUND FOR SHAPE: "%s"' % s
1552          else:
1553            tt = dd[dds.get(s,s)]
1554            if tt[-1]:
1555              n,zz = lsdd[d[1]]
1556              if len(zz) > 0 and zz[0] == '%':
1557                zz = zz % d[3]
1558              sc = tt[0] % zz
1559              if sc[-1] == "|":
1560                print 'ERROR.080.05000: Bad dimension found %s [%s] %s %s' % (sc,str(tt), str((n,zz)), str(d)  )
1561            else:
1562              sc = tt[0]
1563              if (string.find( sc, 'alevel' ) != -1) or (string.find( sc, 'olevel' ) != -1):
1564                n = -1
1565              else:
1566                n = -2
1567
1568          lcount[sc] = n
1569          if n == -1 and sc == 'latitude|basin':
1570            print 'SEVERE [2]: error in level deduction'
1571            print sc, tt[0], tt[-1], n
1572            raise
1573          if crd0 != None:
1574            tt3 = tt[3] + crd0
1575          else:
1576            tt3 = tt[3]
1577         
1578          if d[2] == '' and tt[2] not in ['','?']:
1579            d2 = tt[2]
1580          else:
1581            d2 = d[2]
1582          print 'INFO:qqq05: ',d, sc, tt, ttdd[d2], tt3
1583          eed[d] = (sc,tt[1],ttdd[d2],tt3)
1584      self.dsortdd[mode] = (eed,lcount)
1585
1586  def run(self,rq):
1587
1588    xx = self.doc.getElementsByTagName( 'main' )
1589    assert len(xx) == 1, 'Expecting one element named "main", found %s' % len(xx)
1590    main = xx[0]
1591    ## main = self.doc.childNodes[0]
1592    xsn = []
1593    ff = {}
1594    for c in main.childNodes:
1595      tag = c.nodeName
1596      if tag != '#text':
1597        xsn.append(tag)
1598        il = []
1599        for i in c.childNodes:
1600          if i.nodeName == 'item':
1601            il.append(i)
1602        xx = dict( il[0].attributes.items() )
1603        ff[string.lower(tag)] = (c,xx)
1604   
1605    print xsn
1606    print ff.keys()
1607    self.ff = ff
1608    ##        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()]:
1609        ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'ref', 'refNote', 'refid']
1610        ##kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
1611        ##i = rq.rqvg[k]
1612       
1613        ##self.eern[i[ixrn]].append( i[0] )
1614        ##k2 = '%s__%s' % (i[ixrn-1],i[ixrn])
1615        ##if self.eern2.has_key( k2 ):
1616           ##dups.append( (k2,k,self.eern2[k2]) )
1617        ##self.eern2[k2] = i[0]
1618        ##assert i[0] == k, 'Bad key/uuid'
1619
1620    ##assert len( dups ) == 0, 'Duplicate refs: %s, %s' % (str(dups),str(map( lambda x: rq.rqvg[x[1]], dups )) )
1621       
1622## keys here match section element names in schema
1623    sectlist = [ 'experiment','exptgroup','objective','requestlink', 'requestitem','requestvargroup','tablesection' ]
1624    ## dec 2015 -- removing 'var' from this list
1625    if self.schemaMode != 'dreq2':
1626      sectlist = ['ovar','groupitem','revisedtabitem'] + sectlist
1627    else:
1628      sectlist.append( 'requestvar' )
1629
1630    for k in sectlist:
1631      thissh = self.skey[k]
1632## set labmod False for section in which label coercion is not wanted
1633      labmod = True
1634      lll = []
1635      for i in thissh.keys():
1636        if i[0] != '_':
1637          lll.append(i)
1638      idk = 0
1639      if len(lll) > 0:
1640##
1641## remove example items, xcept where this has been done in previous function
1642##
1643        if k not in ['xxxx']:
1644          dil = ff[k][0].getElementsByTagName('item')
1645          for d in dil:
1646            ff[k][0].removeChild(d)
1647
1648        vare = {}
1649        nfr = set()
1650        for i in lll:
1651          ll = map( uniCleanFunc, thissh[i] )
1652          assert len(ll) == len( thissh[i] ), 'Lost list elements after uniClean'
1653          idk += 1
1654#################################################################
1655######### NEED TO CLEAN THIS IF ITEMS FROM OTHER SECTIONS ARE FILTERED
1656#######################################################################
1657          dothis = True
1658          if k != 'var':
1659            item = self.doc.createElement( 'item' )
1660
1661          if k == 'objective':
1662 ## - mip; tab; expt; rlid; ny
1663            labmod = False
1664            kk = ['mip', 'label', 'title', 'description']
1665            ##thisl = string.replace(string.strip(str( ll[1] ) ), '-', ' ')
1666## camelcase this label.
1667            ##thisl = string.replace( string.capwords( thisl ), ' ', '' )
1668            thisl = mycc( ll[1] )
1669            mip = str( ll[0] )
1670            self.objectives[mip][thisl] = i
1671            for j in range(len(kk)):
1672                thisv = str( ll[j] )
1673                item.setAttribute( kk[j], thisv )
1674            item.setAttribute( 'uid', str(i) )
1675          elif k == 'experiment':
1676            labmod = False
1677            kk = ['uid','egid','label','description','mip','mcfg','tier','nstart','starty','endy','yps','ensz','ntot','comment']
1678            thisl = str( ll[2] )
1679            ## self.mips.add( str( ll[4] ) )
1680            for j in range(len(kk)):
1681                if kk[j] in ['tier','ensz']:
1682                  if type(ll[j]) == type( 1 ):
1683                    thisv = str( ll[j] )
1684                  else:
1685                    thisv = string.join( [str(x) for x in ll[j]] )
1686                else:
1687                  thisv = str( uniCleanFunc(ll[j]) )
1688                item.setAttribute( kk[j], thisv )
1689          elif k == 'exptgroup':
1690            labmod = False
1691            kk = ['uid','label','tierMin','ntot']
1692            thisl = str( ll[1] )
1693            ##self.exptGrpDict[thisl] = str( ll[1] )
1694            ##self.experimentGrp[thisl] = str( ll[0] )
1695            for j in range(len(kk)):
1696                thisv = str( ll[j] )
1697                item.setAttribute( kk[j], thisv )
1698          elif k == 'var':
1699##- sn; units; description; procnote; procComment; prov
1700##['label', 'title', 'sn', 'units', 'description', 'procnote', 'procComment', 'prov', 'priority0']
1701            thisl = string.replace(string.strip(str( ll[0] ) ), '_', '-' )
1702            thisuuid = str(i)
1703            if not ( self.replItems.has_key( str(i) ) or self.remo.has_key(str(i)) ):
1704              item = self.doc.createElement( 'item' )
1705              item.setAttribute( 'id', 'tmpid.%4.4i' % idk )
1706              item.setAttribute( 'uid', str(i) )
1707              item.setAttribute( 'title', str(ll[1]) )
1708              item.setAttribute( 'sn', str(ll[2]) )
1709              item.setAttribute( 'units', str(ll[3]) )
1710              item.setAttribute( 'description', str(ll[4]) )
1711              item.setAttribute( 'procnote', str(ll[5]) )
1712              item.setAttribute( 'procComment', str(ll[6]) )
1713              item.setAttribute( 'prov', str(ll[7]) )
1714              vare[ll[3]] =  ll[1]
1715              if self.upda.has_key( thisuuid ):
1716                for tag in self.upda[thisuuid]['tags']:
1717                  if tag == 'label':
1718                    thisl = self.upda[thisuuid][tag]
1719                  else:
1720                    item.setAttribute( tag, self.upda[thisuuid][tag] )
1721              if thisl in self.fix.d1:
1722                thisr = self.fix.d1[thisl]
1723                if len(thisr) > 2 and thisr[2] != '':
1724                  item.setAttribute( 'title', str( thisr[2] ) )
1725                if len(thisr) > 3 and thisr[3] != '':
1726                  item.setAttribute( 'description', str( thisr[3] ) )
1727                if thisr[0] != thisl:
1728                  item.setAttribute( 'label', str( thisr[0] ) )
1729                  thisl = str( thisr[0] )
1730                if len(thisr) > 6 and thisr[6] != '':
1731                  item.setAttribute( 'units', str( thisr[6] ) )
1732                print 'INFO.qqq13: updating title and desc %s' % str( thisr )
1733            else: 
1734              print 'Omitting: ',ll
1735              dothis = False
1736          elif k == 'ovar':
1737## 
1738            tab2freqxxx = {u'CMIP5_cfOff':'subhr', u'CORDEX_mon':'mon', u'SPECS_day':'day', u'CMIP5_day':'day', \
1739       u'PMIP3_OImon':'mon', u'CORDEX_day':'day', u'CMIP5_LImon':'mon', u'CMIP5_OImon':'mon', \
1740       u'CMIP5_Lmon':'mon', u'CMIP5_3hr':'3hr', u'CMIP5_Omon':'mon', u'PMIP3_OIclim':'monClim', \
1741       u'PMIP3_fx':'fx', u'CORDEX_fx':'fx', u'PMIP3_LImon':'mon', u'CMIP5_6hrPlev':'6hr', u'PMIP3_Lmon':'mon', \
1742       u'PMIP3_Amon':'mon', u'SPECS_Omon':'mon', u'CCMI1_fixed':'fx', u'PMIP3_Aclim':'monClim', u'CMIP5_6hrLev':'6hr', \
1743       u'CMIP5_Oclim':'monClim', u'PMIP3_LIclim':'monClim', u'CCMI1_monthly':'mon', u'CMIP5_fx':'fx', \
1744       u'CMIP5_cfDay':'day', u'CORDEX_6h':'6hr', u'PMIP3_day':'day', u'SPECS_OImon':'mon', u'CMIP5_cfMon':'mon', \
1745       u'CORDEX_sem':'monClim', u'SPECS_6hr':'6hr', u'CMIP5_cfSites':'subhr', u'CCMI1_hourly':'hr', u'CMIP5_aero':'mon', \
1746       u'CMIP5_Amon':'mon', u'PMIP3_Omon':'mon', u'CCMI1_daily':'day', u'SPECS_fx':'fx', u'PMIP3_Lclim':'monClim', \
1747       u'PMIP3_Oclim':'monClim', u'SPECS_Amon':'mon', u'SPECS_Lmon':'mon', u'CMIP5_cf3hr':'3hr', u'CORDEX_3h':'3hr', \
1748       u'CCMI1_annual':'yr', u'CMIP5_Oyr':'yr'}
1749            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']
1750## 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
1751            ix_gpid = kk.index( 'gpid' )
1752
1753            thisl = string.strip( str( ll[21] ) )
1754            for j in range( min(len(kk),len(ll)) ):
1755              if kk[j] == 'priority':
1756                ll[j] = int(ll[j])
1757               
1758              if j != 21:
1759                item.setAttribute( kk[j], str( ll[j] ) )
1760
1761            if len(ll) < len(kk):
1762              print 'ERROR.015.0001: record length short %s (%s):: %s' % (len(ll),len(kk),ll)
1763
1764            if ll[22][-3:] in ['mon','day','3hr']:
1765              fr = ll[22][-3:]
1766            elif ll[22][-2:] in [ 'yr','fx']:
1767              fr = ll[22][-2:]
1768            else:
1769              fr = tab2freq[ll[22]]
1770   
1771            item.setAttribute( 'frequency', fr )
1772            thisuuid = ll[0]
1773            if self.repl.has_key( thisuuid ):
1774              for tag,old,new in self.repl[thisuuid]:
1775                thisold = item.getAttribute( tag )
1776                assert thisold == old, 'Attempt to replace value which is not present'
1777                item.setAttribute( tag, new )
1778          elif k == 'groupitem':
1779            kk = ['group', 'var', 'table', 'freq', 'descriptionEx', 'shape', 'levels', 'tstyle', 'mask', 'misc', 'mip', 'uid', 'new', 'gpid', 'vkey', 'vid']
1780            assert len(kk) == len(ll), 'length mismatch, %s  %s' % (len(kk),len(ll))
1781# - group;  table; freq; descriptionEx; shape; levels; tstyle; mask; mip; mip2; uuid; new; vid
1782            ix_gpid = kk.index( 'gpid' )
1783            thisl = string.strip(str( ll[1] ) )
1784            for j in range(len(kk)):
1785              if j != 1:
1786                ##item.setAttribute( kk[j], str( ll[j] ) )
1787                if kk[j] == 'misc':
1788                  item.setAttribute( 'priority', str( ll[j] ) )
1789                else:
1790                  item.setAttribute( kk[j], str( ll[j] ) )
1791            item.setAttribute( 'title', thisl )
1792            if string.find(thisl, ' ') != -1:
1793              thisl = string.split(thisl)[0]
1794            thisuuid = ll[11]
1795
1796            gpid = str(ll[ix_gpid])
1797            if not rq.rqvg.has_key(gpid):
1798              print 'ERROR.015.0010: gpid not found %s' % str(ll)
1799              self.e15_10 += 1
1800            if self.repl.has_key( thisuuid ):
1801              for tag,old,new in self.repl[thisuuid]:
1802                thisold = item.getAttribute( tag )
1803                assert thisold == old, 'Attempt to replace value which is not present'
1804                item.setAttribute( tag, new )
1805##################################
1806          elif k in ['revisedtabitem','requestvar']:
1807#### need to fill gaps in variable groups --- or do better job upstream ##########  !!!!!!!!!!!!!!!!
1808## - table; mip; uuid; priority
1809##
1810## variable group ids pulled through via mapping above .. very messy
1811## still missing some OMIP matches .... OMIP revised tables are not explicitly requested anywhere.
1812##
1813            kk = ['var', 'table', 'mip', 'vid', 'priority']
1814    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
1815
1816            vgid = self.prqv.rqv_vg['%s.%s.%s' % (ll[2],ll[1],ll[0])]
1817            thisuuid = str( uuid.uuid1() )
1818            thisl = string.strip(str( ll[0] ) )
1819            thisd = {}
1820            for j in range(len(kk)):
1821              if j != 0 and kk[j] != 'table':
1822                item.setAttribute( kk[j], str( ll[j] ) )
1823                thisd[kk[j]] = str( ll[j] )
1824            if thisl == 'clic':
1825              print 'INFO.clic.00001: ',ll, k
1826            elif thisl == 'rhopoto':
1827              print 'INFO.rhopoto.00001: ',ll, k
1828
1829            item.setAttribute( 'title', thisl + ' ((isd.005))' )
1830            item.setAttribute( 'uid', thisuuid )
1831            item.setAttribute( 'vgid', vgid )
1832
1833            thisd['title'] = thisl + ' ((isd.005))'
1834            thisd['uid'] = thisuuid
1835            thisd['vgid'] = vgid
1836
1837            vid = str( ll[3] )
1838            if self.insert.has_key(thisl) and vid == '__new__':
1839                vid = self.insert[thisl]
1840                print 'info.xxxx.0001',thisl,
1841                item.setAttribute( 'vid', vid )
1842                thisd['vid'] = vid
1843            if vid[0] == '_':
1844              f = {'6hrPlev':'6hr','Omon':'mon','Amon':'mon'}.get( ll[1], '__' )
1845              if f in self.cmvUidByFL and ll[0] in self.cmvUidByFL[f].a:
1846                if len( self.cmvUidByFL[f].a[ll[0]] ) == 1:
1847                  vid = self.cmvUidByFL[f].a[ll[0]][0]
1848                  item.setAttribute( 'vid', vid )
1849                  thisd['vid'] = vid
1850                  print 'INFO.090.08801: variable link corrected, %s' % len( self.cmvUidByFL[f].a[ll[0]] )
1851                else:
1852                  print 'WARN.090.08801: multiple options found, %s' % len( self.cmvUidByFL[f].a[ll[0]] )
1853            if vid[0] == '_':
1854              print 'ERROR.090.08801: bad variable ref [%s]' % vid,ll
1855
1856            if vid in self.fix.fixcmv:
1857               if self.fix.fixcmv[vid][3] == u'replace':
1858                 vid = str( self.fix.fixcmv[vid][4] )
1859                 item.setAttribute( 'vid', vid )
1860                 thisd['vid'] = vid
1861                 print 'INFO.qqq11: replacing link in requestVar  %s' % str(ll), vid
1862               else:
1863                 print 'INFO.qqq22: not replacing link in requestVar  %s' % str(ll)
1864
1865
1866            newd = None
1867            if vid in self.importWbMods.mmsi.ss:
1868              print 'INFO.046.0001: mip map found: ', self.importWbMods.mmsi.ss[vid]
1869##
1870## awkward logic here to deal with changing references ... i.e. variable names etc.
1871##
1872              mm = self.importWbMods.mmsi.ss[vid]
1873              t = mm[0].table
1874              v = mm[0].lab2
1875              if t in self.cmvUidByTab and v in self.cmvUidByTab[t].a:
1876                uuu = self.cmvUidByTab[t].a[v]
1877                uu = set( uuu )
1878                if len( uu ) > 1:
1879                  f = mm[0].freq
1880                  uuf = set( self.cmvUidByFL[f].a[v] )
1881                  uub = {u for u in uu if u in uuf}
1882                  assert len(uub) == 1, 'Cannot resolve ambiguity in variable mapping'
1883                  vid = list( uub )[0]
1884                else:
1885                  vid = list( uu )[0]
1886              else:
1887                print 'ERROR:qqqqqqq: %s, %s not found ... ' % (t,v)
1888              newd = self._editRequestVar01( item, mm, ll, thisd, vid=vid )
1889
1890            if vid not in self.cmvs:
1891              l,t = (ll[0],ll[1])
1892              if t in tab2freq:
1893                frq = tab2freq[t]
1894              else:
1895                nfr.add(t)
1896
1897              if t in self.cmvUidByTab and l in self.cmvUidByTab[t].a:
1898                if len( self.cmvUidByTab[t].a[l] ) == 1:
1899                  print 'ERROR.090.09011a: vid not found (option found)',ll
1900                else:
1901                  print 'ERROR.090.09011b: vid not found (OPTIONS found)',ll
1902              elif l in self.cmvByLab:
1903#  cmvByLab contains, for each uid, a (frequency,table) tuple
1904                thisll = []
1905                thislll = []
1906                thisllp = []
1907                for u in self.cmvByLab[l]:
1908                  if t in freq2tab[ self.cmvByLab[l][u][0] ]:
1909                    thisll.append( u )
1910                if len(thisll) == 1:
1911                    print 'INFO.090.09011x: vid reset',ll, vid
1912                    vid = thisll[0]
1913                    item.setAttribute( 'vid', str( vid ) )
1914                    thisd['vid'] = vid
1915                elif len(thisll) > 1:
1916                  for u in thisll:
1917                    if string.find(self.cmvByLab[l][u][1], 'SPECS') == -1:
1918                      thislll.append( u )
1919                    if string.find(self.cmvByLab[l][u][1], 'OMIP') != -1:
1920                      thisllp.append( u )
1921                  if len( thislll ) == 1:
1922                    print 'INFO.090.09011y: vid reset',ll, vid
1923                    vid = thislll[0]
1924                    item.setAttribute( 'vid', str( vid ) )
1925                    thisd['vid'] = str(vid)
1926                  elif len( thisllp ) == 1:
1927                    print 'INFO.090.09011z: vid reset',ll, vid
1928                    vid = thisllp[0]
1929                    item.setAttribute( 'vid', str( vid ) )
1930                    thisd['vid'] = str(vid)
1931                  else:
1932                    print 'ERROR.090.09011c: vid not found (options found by lab)',ll, [self.cmvByLab[l][u] for u in thisll]
1933                else:
1934                  print 'ERROR.090.09011d: vid not found (no options at matching frequency)',ll
1935              else:
1936                print 'ERROR.090.09011: vid not found',ll
1937                if t in self.cmvUidByFL and l in self.cmvUidByFL[t].a:
1938                  print 'INFO.090.09011: found ---- ', l,t
1939                print 'INFO.090.09011: ',l,t,self.cmvUidByTab.keys()
1940               
1941            vid = item.getAttribute( 'vid' )
1942            if vid in self.rep['cmv'].items:
1943              vid1 = vid
1944              vid = self.rep['cmv'].items[vid]
1945              print 'INFO.090.09901a: vid updated :',vid,ll
1946              item.setAttribute( 'vid', vid )
1947              thisd['vid'] = str(vid)
1948            ooo = []
1949            for tag in self.rqvinfo:
1950               ooo.append( item.getAttribute( tag ) )
1951            print 'INFO.ooo: ',ooo
1952            did = '%s__%s' % (vid,vgid)
1953            if self.vgcheck.has_key(did) and did[0] != '_':
1954              print 'ERROR.090.09001: Duplicate request ....: ',ll,self.vgcheck[did]
1955              dothis = False
1956            else:
1957              self.vgcheck[did] = ll
1958            self.rqvList.append( (thisd,'run:thisd') )
1959            if newd != None:
1960              self.rqvList.append( (newd, 'run:newd') )
1961
1962##################################
1963          elif k == 'requestlink':
1964 ## - uuid; mip; tab; objective; grid; gridreq; comment
1965            kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt', 'opar', 'preset', 'ref', 'refNote', 'refid']
1966            ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','ref', 'refNote', 'refid']
1967            emap = {'uid':'uid'}
1968            mip = string.strip(str( ll[1] ) )
1969            obj = string.strip(str( ll[3] ) )
1970            if mip == "GMMIP":
1971              bits = [ mycc(x) for x in string.split( obj, ' ' ) ]
1972            else:
1973              bits = [ mycc(x) for x in string.split( obj, ',' ) ]
1974            for b in bits:
1975              self.objectiveLinks[mip].a[b].append( str( ll[0] ) )
1976            self.requestlinkuid.add( str(ll[0] ) )
1977            self.rqlPreset[str(ll[0])] = ll[9]
1978            dothis = False
1979       
1980 ##           thisl = string.strip(str( ll[2] ) )
1981##################################
1982          elif k == 'requestitem':
1983 ## - mip; tab; expt; rlid; ny
1984## defer so that cross-check of "expt" can be done .. or scan this earlier ....
1985              kk = ['mip', 'tab', 'expt', 'rlid', 'ny', 'nexmax', 'nenmax', 'nymax','treset','info']
1986              thisl = mycc( '%s %s' % (ll[0],ll[1]) )
1987              if str( ll[3] ) not in self.rqlPreset:
1988                 print 'ERROR.090.02000: requestlink not found .. ',ll
1989                 preset = '-99'
1990              else:
1991                 preset = str( self.rqlPreset[ str( ll[3] ) ] )
1992              if str( ll[3] ) not in self.requestlinkuid:
1993                print 'SEVERE.005.00005: rlid not found: %s' % str(ll)
1994              for j in range(len(kk)-1):
1995                if kk[j] == 'ny':
1996                  if ll[j] == '':
1997                    thisv = 0
1998                  else:
1999                    try:
2000                      thisv = str( int(ll[j]) )
2001                    except:
2002                      print 'SEVERE: failed to set "ny": %s' % str(ll)
2003                      thisv = 999
2004                else:
2005                  thisv = str( ll[j] )
2006                if not (kk[j] == 'treset' and thisv in ['None','']):
2007                  item.setAttribute( kk[j], thisv )
2008              item.setAttribute( 'title', '%s, %s, %s' % (ll[0],ll[1],ll[2]) )
2009              item.setAttribute( 'uid', str(i) )
2010              item.setAttribute( 'preset', preset )
2011              ku = str(ll[2])
2012              item.setAttribute( 'esid', self.exptPntUid[ku][0] )
2013              item.setAttribute( 'esidComment', str(self.exptPntUid[ku]) )
2014              if ll[0] in self.tsliceMap:
2015                if type(ll[-1]) in [type(''), type(u'')]:
2016                  kkk = string.strip( ll[-1] )
2017                  if kkk in self.tsliceMap[ll[0]]:
2018                    v = self.tsliceMap[ll[0]][kkk]
2019                    if v != None:
2020                      item.setAttribute( 'tslice', '_slice_%s' % v )
2021##################################
2022          elif k in ['requestvargroup','tablesection']:
2023            if k == 'requestvargroup':
2024              kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
2025            else:
2026              kk = ['uid', 'gpid', 'mip', 'label', 'title', 'ref', 'refNote']
2027            thisl = string.replace( str( ll[2] ), '.', '-' )
2028            if str(ll[0]) not in self.varGroupUids:
2029              print 'WARN.077.07707: uid not traced: ',ll
2030            else:
2031              print 'INFO.077.07707: uid traced: ',ll
2032            omitrvg = {'C4MIP-Omon','C4MIP-Oclim','HighResMIP-OImon','HighResMIP-Oclim'}
2033            if thisl in omitrvg:
2034              dothis = False
2035            else:
2036              thisd = {}
2037              for j in range(len(kk)):
2038                item.setAttribute( kk[j], str( ll[j] ) )
2039                thisd[kk[j]] = str( ll[j] )
2040####
2041          if dothis:
2042            if labmod:
2043              if string.find( thisl, '_' ) != -1:
2044                thisl = string.replace( thisl, '_', '-' )
2045              if string.find( thisl, '*' ) != -1:
2046                thisl = string.replace( thisl, '*', '-' )
2047              if string.find( thisl, '!' ) != -1:
2048                thisl = string.replace( thisl, '!', '-' )
2049              if string.find( thisl, ' ' ) != -1:
2050                thisl = string.replace( thisl, ' ', '-' )
2051              if string.find( thisl, ':' ) != -1:
2052                thisl = string.replace( thisl, ':', '-' )
2053            item.setAttribute( 'label', thisl )
2054            ff[k][0].appendChild( item )
2055            if k in ['requestvargroup','tablesection']:
2056              thisd['label'] = thisl
2057              self.rqvgList.append( thisd )
2058        if len(nfr) > 0:
2059              print 'ERROR:nfr: ',nfr
2060             
2061           
2062  def write2(self):
2063    """write sections for cmor variable, request variable, structure, spatial and temporal dimensions"""
2064    spsResets = collections.defaultdict(list)
2065    self.spLab2Uid = {}
2066    self.tmLab2Uid = {}
2067    self.tmsp2str = {}
2068    for ksect in [ u'spatialshape', u'temporalshape', u'structure', u'cmorvar', u'requestvar', u'requestlink']:
2069    ##for ksect in [ u'cmorvar',  u'spatialshape', u'temporalshape', u'structure']:
2070        dil = self.ff[ksect][0].getElementsByTagName('item')
2071        if ksect == 'requestvar':
2072          for item in dil:
2073            vid = item.getAttribute( 'vid' )
2074            if vid in self.fix.fixcmv:
2075               if self.fix.fixcmv[vid][3] == u'replace':
2076                 item.setAttribute( 'vid', str( self.fix.fixcmv[vid][4] ) )
2077                 print 'INFO.qqq12x: replacing link in requestVar  %s' % item.getAttribute( 'uid' )
2078        else:
2079          for d in dil:
2080            self.ff[ksect][0].removeChild(d)
2081
2082        if ksect == u'cmorvar':
2083          ktable = self.cmvinfo.index('mipTable')
2084          kfreq = self.cmvinfo.index('frequency')
2085          kstr = self.cmvinfo.index('stid')
2086            ##self.spatialDims[rr[0]] = rr[3]
2087          s1 = set()
2088          for r in self.cmv:
2089           if r[0] in self.rep['cmv'].items:
2090             print 'INFO.090.09099: detected cmv replace request: ',r
2091           else:
2092            if r[0] in s1:
2093              print 'ERROR.090.09005: duplicate key at ',r
2094            s1.add( r[0] )
2095            if len( r[1] ) == 2:
2096              spid = self.spLab2Uid[r[1][0]]
2097              if r[1][1] == 'mean':
2098                tmid = self.tmLab2Uid['time-mean']
2099              else:
2100                tmid = self.tmLab2Uid['time-point']
2101
2102              if (tmid,spid) in self.tmsp2str:
2103                stid = self.tmsp2str[ (tmid,spid) ]
2104              else:
2105                print 'ERROR.stid.0001: no structure record for ',tmid,spid
2106                stid = '__not_found__'
2107              print 'INFO.klklkl: AerChemMIP structure .... ',r[1], spid
2108            else:
2109              try:
2110                stid = self.strdd[r[1]]
2111              except:
2112                print 'ERROR.999.00099: strdd key not found: %s' % str(r[1])
2113                for k in self.strdd.keys():
2114                  if k[0] == r[1][0]:
2115                    print '*** ',k
2116                raise
2117
2118            stinfo = self.structInfo.get( stid, ['','',''] )
2119            spinfo = self.spidInfo.get( stinfo[2]  , ['','','','',''] )
2120            if "plev7h" in spinfo[3]:
2121              lsfx = '7h'
2122            elif "plev4" in spinfo[3]:
2123              lsfx = '4'
2124              ##print 'plev7h found',r,spinfo
2125            else:
2126              lsfx = ''
2127
2128             
2129            if r[0] in self.fix.fixcmv:
2130              print 'INFO.qqq10: omitting record %s, %s' % (str( self.fix.fixcmv[r[0]] ), r[0])
2131            else:
2132              item = self.doc.createElement( 'item' )
2133              for k in range(len(self.cmvinfo)):
2134                n = self.cmvinfo[k]
2135                if n in self.cmvinfo2:
2136                  if n == 'mipTable' and str(r[k]) == 'CMIP5_Oyr':
2137                    print 'ERROR.047.0002: ',r
2138                  if n == "vid":
2139                    if str(r[k]) == '__var_not_found_012__':
2140                      print 'ERROR.099.00202: bad vid string: %s [%s]' % (r[k],str(r[:3]))
2141                    vid = str(r[k])
2142                    if vid in self.importWbMods.vars.vmap:
2143                      ov = vid
2144                      vid = self.importWbMods.vars.vmap[vid]
2145                      print 'INFO.040.04444: mapping',ov,vid
2146
2147                  if n == "rowIndex":
2148                    ix = str(r[k])
2149                  if n == "defaultPriority":
2150                    priority = str(r[k])
2151                  if n == "title":
2152                    title = str(r[k])
2153
2154                  if n == "stid":
2155                    item.setAttribute( n, stid )
2156                  elif n == "mipTableSection":
2157                    if str(r[k]) != '':
2158                      item.setAttribute( n, str(r[k]) )
2159                  elif n == "label":
2160                    thisl = string.replace( r[k], '_', '' )
2161                    if len(lsfx) > 0:
2162                      if thisl[ - len( lsfx): ] != lsfx:
2163                        thisl += lsfx
2164                    item.setAttribute( n, thisl )
2165                  elif n in ["valid_min","valid_max","ok_max_mean_abs","ok_min_mean_abs"]:
2166                    if str(r[k]) != "" and r[k] not in [None, 'None']:
2167                      if str(r[k]) == "None":
2168                        print 'ERROR.8888.00008: bad valid min/max: ',r[k]
2169                      item.setAttribute( n, str(r[k]) )
2170                  elif n == "frequency":
2171                    fr = freqmap.get( str(r[k]), str(r[k]) )
2172                    item.setAttribute( n, fr )
2173                  elif n == "mipTable":
2174                    tn = tableNameMap.get( str(r[k]), str(r[k]) )
2175                    if tn == 'em6hr':
2176                      if 'alev' in spinfo[3]:
2177                        tn = '6hrLev'
2178                      else:
2179                        tn = '6hrPlev'
2180                    item.setAttribute( n, tn )
2181                  else:
2182                    item.setAttribute( n, str(r[k]) )
2183
2184### reset table name for OImon ... correcting for frequency as well
2185###
2186              mtable = r[ktable]
2187              if r[ktable] == 'OImon':
2188                if r[kfreq] == 'mon':
2189                    mtable = 'SImon'
2190                    #item.setAttribute( 'mipTable', 'SImon' )
2191                else:
2192                    mtable = 'SIday'
2193                    #item.setAttribute( 'mipTable', 'SIday' )
2194              elif r[ktable] in ['em6hr','em3hr','emDay']:
2195                if stid in self.structInfo:
2196                  if string.find( self.structInfo[stid][1], 'time: point' ) != -1:
2197                    mtable += 'pt'
2198                  if string.find( self.spatialDims[ self.structInfo[stid][2] ], 'longitude' ) == -1:
2199                    mtable += 'Z'
2200                else:
2201                    print 'WARN.090.09999: structure uid not found',stid, r
2202              if mtable != r[ktable]:
2203                item.setAttribute( 'mipTable', mtable )
2204
2205              thisuid = r[0]
2206              if tableUtils.getSubGroup(spinfo[3],mtable,thisl,ix,title,thisuid,priority):
2207                item.setAttribute( 'subGroup', tableUtils.subGroup )
2208
2209              if str(vid) not in self.importWbMods.vars.d1:
2210 
2211                  if thisl in self.importWbMods.vars.c1 or (thisl[-2:] in ['17','23','27'] and thisl[:-2] in self.importWbMods.vars.c1):
2212                    if thisl in self.importWbMods.vars.c1:
2213                      thisn = thisl
2214                    else:
2215                      thisn = thisl[:-2]
2216
2217                    if len( self.importWbMods.vars.c1[ thisn ] ) == 1:
2218                      newvid = self.importWbMods.vars.c1[ thisn ][0]
2219                      item.setAttribute( 'vid', newvid )
2220                      print 'INFO.099.00110: bad vid string replaced: %s [%s]' % (newvid,thisl)
2221                    else:
2222                      print 'ERROR.099.00111: ambiguous bad vid string: %s [%s]' % (vid,thisl)
2223                  else:
2224                    print 'ERROR.099.00112: bad vid string: %s [%s]' % (vid,thisl)
2225              if self.repl.has_key( thisuid ):
2226                for tag,old,new in self.repl[thisuid]:
2227                  thisold = item.getAttribute( tag )
2228                  if thisold != old:
2229                     ##print 'WARN.yyy: Attempt to replace value which is not present'
2230                    print 'WARN.050.00051: Failed attempt to replace values in cmv: %s old:%s new:%s' % (tag,old,new)
2231                  else:
2232                    if tag == 'vid' and new not in self.importWbMods.vars.d1:
2233                        print 'ERROR.050.00052: Attempt to replave values in cmv with invalid vid: %s old:%s new:%s' % (tag,old,new)
2234                    else:
2235                      item.setAttribute( tag, new )
2236                      print 'INFO.050.00050: replacing values in cmv: %s old:%s new:%s' % (tag,old,new)
2237              self.ff[ksect][0].appendChild( item )
2238          assert tableUtils.subGroupCheck(), 'Failed to identify expected table sub-groups'
2239          ##print 'INFO.sgsg.00001: sub groups: ',tableUtils.sgset
2240        elif ksect == u'structure':
2241          ers = {}
2242          for kk in spsResets:
2243            if len( spsResets[kk] ) > 0:
2244              utarg = spsResets[kk][0][0]
2245              for r in spsResets[kk][1:]:
2246                ers[r[0]] = utarg
2247          flds = self.structList[0]._fields
2248          for nt in self.structList:
2249            item = self.doc.createElement( 'item' )
2250            for f in flds:
2251              if f == 'spid' and nt.__dict__[f] in ers:
2252                item.setAttribute( f, ers[ nt.__dict__[f] ] )
2253                print 'INFO.801.00011: updating target spid .... '
2254              elif f == 'coords' and 't2000' in nt.__dict__[f]:
2255                item.setAttribute( f, str( nt.__dict__[f] ) )
2256                print 'INFO.801.00012: updating target spid .... ',nt
2257              else:
2258                item.setAttribute( f, str( nt.__dict__[f] ) )
2259            self.ff[ksect][0].appendChild( item )
2260            self.tmsp2str[ (item.getAttribute( 'tmid' ),item.getAttribute( 'spid' )) ] = item.getAttribute( 'uid' )
2261        elif ksect == u'spatialshape':
2262
2263     ##    self.dimsSpaceInfo = ['uid','label','title','dimensions','levelFlag','levels']
2264          self.spatialDims = {}
2265          for k in self.dimsSpace.keys():
2266            rr = self.dimsSpace[k]
2267            kk = rr[3]
2268            if kk == 'scalar':
2269              kk = ''
2270              rr = list(rr)
2271              rr[3] = ''
2272            elif kk == 'longitude|latitude|plev':
2273              kk = 'longitude|latitude|plev4'
2274              rr = list(rr)
2275              rr[3] = kk
2276            self.spatialDims[rr[0]] = rr[3]
2277            if kk not in spsResets:
2278              item = self.doc.createElement( 'item' )
2279              for i in range(len(self.dimsSpaceInfo)):
2280                item.setAttribute( self.dimsSpaceInfo[i], str( rr[i] ) )
2281              if rr[3] in self.spsh.ss:
2282                lab,ttl,lf,li = self.spsh.ss[rr[3]]
2283                if trace.SPATIALSHAPE_01:
2284                  print 'INFO.035.0001: new spatial shape label: %s, %s' % (lab, ttl)
2285                if ttl[:4] != 'ssd.':
2286                  item.setAttribute( 'title', ttl )
2287                if len(lab) < 4 or lab[:4] != 'ssd-':
2288                  item.setAttribute( 'label', lab )
2289                item.setAttribute( 'levels', li )
2290                item.setAttribute( 'levelFlag', string.lower(lf) )
2291              else:
2292                print 'ERROR.055.00001: spatial shape record not recognised: %s' % str(rr)
2293              print 'INFO.801.00120: new shape for %s' % str(rr)
2294              thisl = item.getAttribute( 'label' )
2295              assert thisl not in self.spLab2Uid.keys(), 'Duplicate spatial shape label: %s' % thisl
2296              self.spLab2Uid[thisl] = item.getAttribute( 'uid' )
2297              self.ff[ksect][0].appendChild( item )
2298            else:
2299              print 'INFO.801.00121: duplicate shape for %s' % str(rr)
2300            spsResets[kk].append( rr )
2301
2302        elif ksect == u'temporalshape':
2303          for k in self.dimsTime.keys():
2304            rr = self.dimsTime[k]
2305            item = self.doc.createElement( 'item' )
2306            for i in range(len(self.dimsTimeInfo)):
2307              item.setAttribute( self.dimsTimeInfo[i], str( rr[i] ) )
2308            self.ff[ksect][0].appendChild( item )
2309            self.tmLab2Uid[ item.getAttribute( 'label' ) ] = item.getAttribute( 'uid' )
2310        elif ksect == u'requestvar':
2311          ##kk = ['var', 'table', 'mip', 'vid', 'priority']
2312          kk = ['label', 'table', 'mip', 'vid', 'priority','vgid','title','uid']
2313          kktr = {'vgid':'gpid', 'title':'label'}
2314    ##self.rqvinfo = ('uid','label','vid','gpid','priority','mip','table' )
2315          kkf = 0
2316          for t in self.rqv:
2317            item = self.doc.createElement( 'item' )
2318            ###assert len(t) == len(kk), 'BAD request variable line: %s' % str(t)
2319            for i in range(len(kk)):
2320              k = kktr.get( kk[i], kk[i] )
2321              v = t[  self.rqvinfo.index(k) ]
2322              if k == 'priority':
2323                item.setAttribute( kk[i], str( int(v) ) )
2324              elif kk[i] == 'label':
2325                thisl = string.replace( v, '_', '' )
2326                item.setAttribute( kk[i], thisl )
2327              elif kk[i] == 'title':
2328                if str(v) == 'bsi':
2329                  print 'INFO.999.09900: ',t
2330                item.setAttribute( kk[i], str( v ) + ' ((isd.006))' )
2331              elif kk[i] == 'table':
2332                pass
2333              else:
2334                item.setAttribute( kk[i], str( v ) )
2335
2336            if t[1] == 'cfadLidarsr532':
2337              print 'INFO.wwwww.00002: ',t
2338            vid = str( t[2] )
2339            if vid in self.fix.fixcmv:
2340               if self.fix.fixcmv[vid][3] == u'replace':
2341                 item.setAttribute( 'vid', str( self.fix.fixcmv[vid][4] ) )
2342                 print 'INFO.qqq12: replacing link in requestVar  %s' % str(t)
2343            newd = None
2344            if vid in self.importWbMods.mmsi.ss:
2345              print 'INFO.046.0002: mip map found: ', self.importWbMods.mmsi.ss[vid]
2346              mm = self.importWbMods.mmsi.ss[vid]
2347              newd = self._editRequestVar01( item, mm, t, {} )
2348              ##item.setAttribute( 'vid', mm[0].vid2 )
2349              ##if len( mm ) > 1:
2350                ##assert len( mm ) < 3, 'Unable to deal with triple clone'
2351                ##cln = item.cloneNode(True)
2352                ##cln.setAttribute( 'uid', str( uuid.uuid1() ) )
2353                ##cln.setAttribute( 'vid', mm[1].vid2 )
2354                ##self.ff[ksect][0].appendChild( cln )
2355                ##print 'INFO.046.0003: request variable split:', t[1]
2356
2357            if vid in self.rep['cmv'].items:
2358              vid1 = vid
2359              vid = self.rep['cmv'].items[vid]
2360              print 'INFO.090.09901b: vid updated :',vid,t
2361              item.setAttribute( 'vid', vid )
2362             
2363            did = '%s__%s' % (t[2],t[3])
2364            if self.vgcheck.has_key(did):
2365              print 'ERROR.090.09002: Duplicate request ....: ',t,self.vgcheck[did]
2366            else:
2367              self.vgcheck[did] = t
2368              self.ff[ksect][0].appendChild( item )
2369              assert len( self.rqvClone.keys() ) > 5, 'rqvClone does not appear to be initialied: %s' % len( self.rqvClone.keys() )
2370              if self.rqvClone.has_key(t[0]):
2371                kkf += 1
2372                for id in self.rqvClone[t[0]]:
2373                  cln = item.cloneNode(True)
2374                  cln.setAttribute( 'vgid', id )
2375                  cln.setAttribute( 'uid', str( uuid.uuid1() ) )
2376                  self.ff[ksect][0].appendChild( cln )
2377                  print 'INFO.090.01010: request variable cloned:', t[1]
2378##
2379######################################################################################
2380##
2381        elif ksect == u'requestlink':
2382 ## - uuid; mip; tab; objective; grid; gridreq; comment
2383            kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt', 'opar', 'preset', 'ref', 'refNote', 'refid']
2384            ##kk = ['uid', 'mip', 'tab', 'objective', 'grid', 'gridreq', 'comment', 'opt','opar','ref', 'refNote', 'refid']
2385       
2386            thissh = self.skey['requestlink']
2387            for k in thissh:
2388              if k[0] != '_':
2389                ll = thissh[k][:]
2390                thisl = string.strip(str( ll[2] ) )
2391                uid = string.strip(str( ll[0] ) )
2392                item = self.doc.createElement( 'item' )
2393                for j in range(len(kk)):
2394                  thiskk = kk[j]
2395## preset mover to request item .... so it can also be used on a per-experiment basis
2396                  if thiskk != 'preset':
2397                    try:
2398                      if kk[j] == 'comment':
2399                        v = utils_wb.uniCleanFunc( v )
2400                      else:
2401                        v = str( ll[j] )
2402                    except:
2403                      print thisl, kk[j]
2404                      print 'ERROR.099.0001: Failed to convert string '
2405                      print ll
2406                      v = '__error_99_1__'
2407
2408### redirect to new variable group if specified in mappings
2409##
2410                    if kk[j] == 'refid' and self.rvgUidMapping.has_key(v):
2411                        v = self.rvgUidMapping[v]
2412                        print 'INFO.090.00200: variable group reference reset in %s [%s]' % (thisl,uid)
2413
2414                    item.setAttribute( thiskk, v )
2415
2416                item.setAttribute( 'title', thisl )
2417                if self.rqlRedirect.has_key( ll[0] ):
2418                   print 'INFO.088.02020: redirect detected ',ll
2419                   item.setAttribute( 'refid', self.rqlRedirect[ ll[0] ] )
2420                self.ff[ksect][0].appendChild( item )
2421##################################
2422
2423  def _editRequestVar01( self, item, mm, t, thisd, vid=None ):
2424              if vid == None:
2425                vid = mm[0].vid2
2426              item.setAttribute( 'vid', vid )
2427              item.setAttribute( 'label', mm[0].lab2 )
2428              thisd['vid'] = vid
2429              thisd['label'] = mm[0].lab2
2430              print 'INFO.fffff.00001:', mm[0].lab2, mm[0].vid2
2431              othd = None
2432              if len( mm ) > 1:
2433                othd = thisd.copy()
2434                assert len( mm ) < 3, 'Unable to deal with triple clone'
2435                cln = item.cloneNode(True)
2436                uid = str( uuid.uuid1() )
2437                cln.setAttribute( 'uid', uid )
2438                cln.setAttribute( 'label', mm[1].lab2 )
2439                othd['uid'] = uid
2440                othd['label'] = mm[1].lab2
2441                self.ff['requestvar'][0].appendChild( cln )
2442
2443                print 'INFO.046.0003: request variable split:', t[1]
2444
2445  def finishExptGrp(self):
2446    """finish exptGroup section and create exptgrouplink section"""
2447    this = self.doc.getElementsByTagName('exptGroup')[0]
2448            ### kk = ['uid','label','tierMin','ntot']
2449    for k in self.exptPntUid.keys():
2450      u,typ = self.exptPntUid[k]
2451##      if not isg:
2452        ##item = self.doc.createElement( 'item' )
2453        ##item.setAttribute( uid, u )
2454    ##this = self.doc.getElementsByTagName('exptGroupLink')[0]
2455    ##dil = this.getElementsByTagName('item')
2456    ##for d in dil:
2457          ##this.removeChild(d)
2458    ##this.appendChild( item )
2459
2460  def reviewExpt(self):
2461    """Prepare cross-linking information to populate requestitem, exptgroup and exptgrouplink"""
2462    sh = shelve.open( '../framework/sh_links/exptMappings', 'r' )
2463    extraMappings={ 'LS3MIP-1, LS3MIP-2':['LmipH', 'LmipF'], \
2464                    'LULCC_hist, CPL_1pctDF, LND_DF, ATM_DF, CPL_DF, CPL_noLULCC_hist_conc (LUMIP)':['LULCC_hist', 'CPL_1pctDF', 'LND_DF', 'ATM_DF', 'CPL_DF', 'CPL_noLULCC_hist_conc'] \
2465                 }
2466    ks = sorted( self.exptPnt.keys() )
2467    self.exptPntMap = collections.defaultdict( list )
2468    self.exptPntUid = {}
2469    ner = 0
2470    ngr = 0
2471    nmr = 0
2472    nuns = 0
2473    nls = 0
2474    for k0 in ks:
2475      k = string.replace( string.replace( k0, '\n', ' ' ), '  ', ' ')
2476      thisl = None
2477      if sh.has_key(k):
2478        thisl = sh[k]
2479      elif extraMappings.has_key(k):
2480        thisl = extraMappings[k]
2481      elif self.experiments.has_key(k):
2482        thisl = [k,]
2483      else:
2484        print 'ERROR.080.00010: no mapping founds for experiment %s' % k
2485     
2486
2487      if thisl != None:
2488        thisu = None
2489        thisls = set( thisl )
2490        linkType = None
2491        for k2 in thisls:
2492          ok = True
2493          if self.experiments.has_key(k2):
2494            ner += 1
2495            linkType = 'expt'
2496            thisu = self.experiments[k2]
2497          elif self.experimentGrp.has_key(k2):
2498            ngr += 1
2499            thisu = self.experimentGrp[k2]
2500            linkType = 'grp'
2501          elif k2 in self.mips:
2502            nmr += 1
2503            thisu = k2
2504            linkType = 'mip'
2505          else:
2506            ok = False
2507            print 'ERROR.080.00999: target experiment not found: %s [%s]' % (k2,k)
2508          if not ok:
2509            self.exptPntMap[k].append( k2 )
2510##
2511## store uid of expt group to be pointed at.
2512##
2513        if len(thisls) == 1 and thisu != None:
2514          self.exptPntUid[k0] = (thisu, linkType, thisls)
2515        else:
2516          self.exptPntUid[k0] = (str( uuid.uuid1() ), 'list', thisls )
2517          nls += 1
2518      else:
2519          nuns += 1
2520          self.exptPntUid[k0] = (None,None)
2521     
2522    sh.close()
2523    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)
2524
2525  def reviewObj(self):
2526## review objectives
2527##
2528    ol = []
2529    fnd1 = set()
2530    for m in self.objectives.keys():
2531      not_used = []
2532      used = set()
2533      not_found = []
2534      found = []
2535      alist = ['All','All?','all']
2536      aaa = [self.objectiveLinks[m].a.has_key(x) for x in ['All','All?','all'] ]
2537      us1 = set()
2538      for k in self.objectiveLinks[m].a:
2539        x = None
2540        if k == 'AllExceptPaleorcms':
2541          x = self.objectives[m].keys()
2542          x.pop( x.index( 'Paleorcms' ) )
2543        elif k == 'AllExceptNaturalVariability':
2544          x = self.objectives[m].keys()
2545          x.pop( x.index( 'NaturalVariability' ) )
2546
2547        if x != None:
2548          fnd1.add(k)
2549          for i in x:
2550            used.add(i)
2551            us1.add(i)
2552            for u in self.objectiveLinks[m].a[k]:
2553              ol.append( (m,self.objectives[m][i], u ) )
2554         
2555      allused = (m != 'GMMIP') and any( aaa )
2556      for o in self.objectives[m].keys():
2557        if allused or self.objectiveLinks[m].a.has_key(o):
2558          used.add(o)
2559          for u in self.objectiveLinks[m].a[o]:
2560            ol.append( (m,self.objectives[m][o], u ) )
2561          for k in alist:
2562            if self.objectiveLinks[m].a.has_key(k):
2563              for u in self.objectiveLinks[m].a[k]:
2564                ol.append( (m,self.objectives[m][o], u ) )
2565        elif o not in us1:
2566          not_used.append(o)
2567
2568      for o in self.objectiveLinks[m].a.keys():
2569        if (o in {'All','All?'} and len(self.objectives[m].keys()) > 0 ) or self.objectives[m].has_key(o) or o in fnd1:
2570          found.append(o)
2571        else:
2572          not_found.append(o)
2573      if len(not_used) > 0 or len(not_found) > 0:
2574        print 'WARN.080.00002: %s: OK %s: unused: %s: not found:%s' % (m,str(used),str(not_used),str(not_found))
2575      else:
2576        print 'INFO.080.00002: %s: all objectives matched' % m
2577    self.objList = ol
2578
2579
2580  def finish(self):
2581## varChoice section
2582    self.choices()
2583##
2584    self.reviewObj()
2585##
2586##
2587    if len( self.prqv.addExrqvg )  > 0:
2588      this = self.doc.getElementsByTagName('requestVarGroup')[0]
2589      kk = ['uid', 'mip', 'label', 'title', 'ref', 'refNote']
2590      for k in self.prqv.addExrqvg:
2591         item = self.doc.createElement( 'item' )
2592         ll = self.prqv.exrqvg[k]
2593         thisl = string.replace( str( ll[2] ), '.', '-' )
2594         ll[2] = thisl
2595         thisd = {}
2596         for j in range(len(kk)):
2597              if kk[j] == 'refNote':
2598                item.setAttribute( kk[j], str( ll[j] ) + '((isd.004))' )
2599                thisd[kk[j]] = str( ll[j] ) + '((isd.004))'
2600              else:
2601                item.setAttribute( kk[j], str( ll[j] ) )
2602                thisd[kk[j]] = str( ll[j] )
2603         this.appendChild( item )
2604         self.rqvgList.append( thisd )
2605    d1 = {}
2606    for i in self.rqvgList:
2607      d1[i['uid']] = i
2608    this = self.doc.getElementsByTagName('requestVarGroup')[0]
2609    dil = this.getElementsByTagName('item')
2610    kkk = 0
2611    kk0 = []
2612    ss = {}
2613    for item in dil:
2614      uid = item.getAttribute( 'uid' )
2615      refn = item.getAttribute( 'refNote' )
2616      bits = string.split( refn, '_' )
2617      if len(bits) == 2:
2618        if string.find(bits[0], '.' ) != -1:
2619          bits[0] = string.split( bits[0], '.')[-1]
2620        ss[ tuple( bits ) ] = uid
2621      if uid not in d1:
2622        kk0.append( 'Record for uid %s not found' % uid )
2623      else:
2624        lab = item.getAttribute( 'label' )
2625        if d1[uid]['label'] == lab:
2626          kkk += 1
2627        else:
2628      ##assert d1[uid]['label'] == lab, 'Mismatch in label for %s' % uid
2629          kk0.append( 'Mismatch in label for %s' % uid )
2630    print 'INFO.rvg.00001: %s records checked OK; %s failed' % (kkk,len(kk0))
2631    notNeeded = ( ('Oyr','3dtr'), ('Amon','2d'), ('cf3hr','grid'))
2632    nnf = 0
2633    dt1 = {}
2634    for s in tableUtils.sgset:
2635      a,b = string.split( s, '_' )
2636      if (a,b) not in notNeeded:
2637        if (a,b) in ss:
2638##
2639## create lookup --- dt1[<sub-group id>] = <requestVarGroup uid>
2640##
2641          dt1[s] = ss[(a,b)]
2642        else:
2643          print 'WARN.rvg.00002: %s %s not found' % (a,b)
2644          nnf += 1
2645
2646    assert nnf == 0, 'Not all sub-groups found'
2647###
2648### read through request vars ... and look to see how many refer to subgroups identiifed in dt1:
2649### how many of these are identified in tableUtils, how many in tableUtils are missing?
2650###
2651
2652    dt1vs =  {}
2653    for s in dt1:
2654      dt1vs[ dt1[s] ] = s
2655
2656    ##print 'INFO.rvg.00009: dt1vs: %s' % str(dt1vs)
2657    this = self.doc.getElementsByTagName('requestVar')[0]
2658    dil = this.getElementsByTagName('item')
2659    nf0 = 0
2660    nf1 = 0
2661    nf2 = 0
2662    ss0 = set()
2663    sn0 = collections.defaultdict( int )
2664    sn1 = collections.defaultdict( int )
2665    sn2 = collections.defaultdict( int )
2666    for item in dil:
2667      ##uid = item.getAttribute( 'uid' )
2668      vgid = item.getAttribute( 'vgid' )
2669      if vgid in dt1vs:
2670        s = dt1vs[vgid]
2671        nf0 += 1
2672        sn0[s] += 1
2673        vid = item.getAttribute( 'vid' )
2674        ss0.add( vid )
2675        if vid in tableUtils.vdict:
2676          nf1 += 1
2677          sn1[s] += 1
2678        else:
2679          this.removeChild(item)
2680
2681    for vid in tableUtils.vdict:
2682      if vid not in ss0:
2683        var,ttl,mip,tab,sg,priority = tableUtils.vdict[vid]
2684        a,b = string.split( sg, '_' )
2685        if (a,b) not in notNeeded:
2686          nf2 += 1
2687          sn2[ tableUtils.vdict[vid][4] ] += 1
2688          assert sg in dt1, 'Cannot locate requestVarGroupd for %s: %s' % (sg,str(dt1.keys()))
2689          vgid = dt1[sg]
2690          item = self.doc.createElement( 'item' )
2691          item.setAttribute( 'uid', str(uuid.uuid1()) )
2692          item.setAttribute( 'vid', vid )
2693          item.setAttribute( 'vgid', vgid )
2694          item.setAttribute( 'title', '%s ((isd.009))' % var )
2695          item.setAttribute( 'label', var )
2696          item.setAttribute( 'mip', mip )
2697          item.setAttribute( 'priority', priority )
2698          this.appendChild( item )
2699
2700    print 'INFO.rvg.00010: variables found in sg rvgs: %s' % nf0
2701    print 'INFO.rvg.00011: of these, number in tableUtils: %s' % nf1
2702    print 'INFO.rvg.00012: variables in tableUtils not in sg rvgs: %s [from %s]' % (nf2,len(tableUtils.vdict.keys()))
2703    for k in sorted( sn0.keys() ):
2704      print 'INFO.rvg.00020: # in tableUtils [%s] %s [from %s]' % (k,sn0[k],sn1[k])
2705    for k in sorted( sn2.keys() ):
2706      print 'INFO.rvg.00021: # in tableUtils [%s] not found %s' % (k,sn2[k])
2707##
2708##  objectiveLink
2709##
2710    this = self.doc.getElementsByTagName('objectiveLink')[0]
2711    dil = this.getElementsByTagName('item')
2712    for d in dil:
2713          this.removeChild(d)
2714    for t in self.objList:
2715       item = self.doc.createElement( 'item' )
2716       item.setAttribute( 'label', t[0] )
2717       item.setAttribute( 'oid', t[1] )
2718       item.setAttribute( 'rid', t[2] )
2719       thisuuid = str( uuid.uuid1() )
2720       item.setAttribute( 'uid', thisuuid )
2721       this.appendChild( item )
2722##
2723## remarks
2724##
2725    this = self.doc.getElementsByTagName('remarks')[0]
2726    dil = this.getElementsByTagName('item')
2727    for d in dil:
2728          this.removeChild(d)
2729
2730    txt = self.doc.toprettyxml(indent='\t', newl='\n', encoding=None)
2731    if self.schemaMode == 'dreq2':
2732      ofn = 'trial2_20150831.xml'
2733    else:
2734      ofn = 'trial_20150831.xml'
2735    oo = open( ofn, 'w' )
2736    lines = string.split( txt, '\n' )
2737    for line in lines:
2738      l = utils_wb.uniCleanFunc( string.strip(line) )
2739      if empty.match(l):
2740        continue
2741      else: 
2742        oo.write(l + '\n')
2743    oo.close()
2744
2745  def choices(self):
2746    """Populate the 'varChoice' section, using the information in the 'choices' dictionary in 'choicecfg'"""
2747
2748    ccfg = choiceCfg.choices( self )
2749    self.ccfg = ccfg
2750##
2751##  choices
2752##
2753    this = self.doc.getElementsByTagName('varChoice')[0]
2754    dil = this.getElementsByTagName('item')
2755    for d in dil:
2756          this.removeChild(d)
2757    for k in ccfg.choices.keys():
2758       item = self.doc.createElement( 'item' )
2759       cc = ccfg.choices[k]
2760       for kk in cc.keys():
2761         item.setAttribute( kk, cc[kk] )
2762       this.appendChild( item )
2763       print 'INFO.zzz.00008: Appending ',cc[kk]
2764
2765    this = self.doc.getElementsByTagName('varChoiceLinkR')[0]
2766    dil = this.getElementsByTagName('item')
2767    for d in dil:
2768          this.removeChild(d)
2769    for cc in ccfg.varChoiceLnk:
2770       item = self.doc.createElement( 'item' )
2771       print 'INFO.zzz', cc
2772       for i in range( len( ccfg.varChoiceLnkInfo ) ):
2773         item.setAttribute( ccfg.varChoiceLnkInfo[i], cc[i] )
2774       this.appendChild( item )
2775
2776    this = self.doc.getElementsByTagName('varChoiceLinkC')[0]
2777    dil = this.getElementsByTagName('item')
2778    for d in dil:
2779          this.removeChild(d)
2780    for cc in ccfg.varChoiceLnkCfg:
2781       item = self.doc.createElement( 'item' )
2782       for i in range( len( ccfg.varChoiceLnkCfgInfo ) ):
2783         item.setAttribute( ccfg.varChoiceLnkCfgInfo[i], cc[i] )
2784       this.appendChild( item )
2785
2786    ##self.varChoiceLnkCfgInfo = [ 'uid', 'label', 'title', 'vid', 'cid', 'cfgid', 'cfg'
2787
2788  def importRepl(self,rfile='uuidreplace.csv',mode='var'):
2789    for l in open(rfile).readlines():
2790      bits = string.split( string.strip(l), '\t' )
2791      assert len(bits) == 7, 'Could not parse item replacement file'
2792      if mode == 'var':
2793        self.repl[ bits[3] ].append( (bits[2],bits[0],bits[1] ) )
2794        self.replItems[bits[0]] = bits[1]
2795      elif mode == 'cmv':
2796        self.rep['cmv'].v[ bits[3] ].append( (bits[2],bits[0],bits[1] ) )
2797        self.rep['cmv'].items[bits[0]] = bits[1]
2798     
2799
2800  def importRemove(self,rfile='uuidremove.csv'):
2801    for l in open(rfile).readlines():
2802      self.remo[ string.strip(l) ] = 1
2803
2804  def importUpdate(self,rfile='uuidupdate.csv'):
2805    for l in open(rfile).readlines():
2806      bits = string.split( string.strip(l), '\t' )
2807      tgs = string.strip( bits[2] )
2808      if string.find( tgs, ' ' ) == -1:
2809        tags = [tgs,]
2810      else:
2811        tags = string.split( tgs )
2812      self.upda[ bits[0] ] =  {'comment':bits[1], 'tags':tags, 'label':bits[3], 'title':bits[4] }
2813
2814  def importInsert(self,rfile='uuidinsert.csv'):
2815    for l in open(rfile).readlines():
2816      bits = string.split( string.strip(l), '\t' )
2817      if bits[0] == 'unique':
2818         self.insert[bits[1]] = bits[3]
2819
2820mode = 'dreq2'
2821sampleXml = '../framework/out/%sSample.xml' % mode
2822from scansh import rq
2823
2824##cmip5GrpLk = collections.defaultdict( dict )
2825##for k in rq.cmip5Grps.keys():
2826  ##bits = string.split(k,'_')
2827  ##tab = bits[0]
2828  ##for v in rq.cmip5Grps[k]:
2829    ##cmip5GrpLk[tab][v] = k
2830
2831m = main(sampleXml, rq,run=True, schemaMode=mode, doRepl=True)
2832
2833ks = m.prqv.err0010.keys()
2834ks.sort()
2835for k in ks:
2836    print 'ERROR.001.0010: variable group not identified: %s [%s]' % (k,m.prqv.err0010[k])
2837ks = m.prqv.err0020.keys()
2838ks.sort()
2839for k in ks:
2840    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.