source: CMIP6dreqbuild/trunk/srcMisc/dreq_consol_tables.py @ 352

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/srcMisc/dreq_consol_tables.py@354
Revision 352, 19.9 KB checked in by mjuckes, 5 years ago (diff)

update

Line 
1"""Parsing adjusted CMIP5 tables.
2"""
3import string, shelve, uuid
4from fcc_utils2 import snlist
5import xlrd, string, shelve, os, re, sys
6import collections
7import xlutils, xlwt
8import xlutils.copy
9####
10import dreq_cfg
11from utils_wb import wbcp, workbook, uniCleanFunc
12
13nt__deckrq = collections.namedtuple( 'dckrq', ['control','AMIP','abrupt4xCO2','rq_1pctCO2','historical'] )
14nt__grptbl = collections.namedtuple( 'grptbl', ['grp','var','srcTable','freq','description','shape','levels','timeProc','mask','priority','mip','id'] )
15nt__newtbl = collections.namedtuple( 'newtbl', ['var','sn','stat','grid','units','long_name','description','priority','obs','mip','id'] )
16dd_rq = collections.defaultdict( dict )
17dd_tbl = collections.defaultdict( int )
18
19class tupsort:
20   def __init__(self,k=0):
21     self.k = k
22   def cmp(self,x,y):
23     return cmp( x[self.k], y[self.k] )
24
25def uniquify( ll ):
26  ll.sort()
27  l0 = [ll[0],]
28  for l in ll[1:]:
29    if l != l0[-1]:
30      l0.append(l)
31  return l0
32
33def getRowValues( ll, minLen=0 ):
34  oo = []
35  for i in ll:
36    oo.append( i.value )
37  if len(oo) >= minLen:
38    return oo[:minLen]
39  for i in range(minLen+1):
40    if len(oo) == minLen:
41      return oo
42    oo.append( '' )
43  return oo
44
45
46clabs = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
47def clab(n):
48  i = n/26
49  assert i < 26, 'Not ready for row number greater than 26*26'
50  if i == 0:
51    return clabs[n]
52  else:
53    return clabs[i-1] + clabs[ n - i*26]
54
55def getRow(sht):
56  ee = {}
57  for i in range(sht.nrows):
58    if sht.row(i)[0].ctype == 2 and str( sht.row(i)[0].value ) != '0.0':
59      l = map( lambda x: str( x.value ), sht.row(i) )
60      k = l[5]
61      try:
62        ee[k] = l
63      except:
64        print l
65        raise
66  return ee
67   
68def outvSer( ov ):
69  ll = []
70  for i in ov:
71    ll.append( '%s|%s|%s' % tuple( map( str, i) ) )
72  return string.join(ll, '; ' )
73def joinRec( rl, tab='\t', omit=[],lmax=None ):
74    l1 = len(rl)
75    if lmax != None and l1 > lmax:
76      l1 = lmax
77    rl0 = []
78    for i in range(l1):
79      if i not in omit:
80        rl0.append(string.strip(str(rl[i])))
81    return string.join( map( str, rl0), tab )
82 
83
84def lennbl(ll):
85  i = 0
86  ii = 0
87  for l in ll:
88    i+= 1
89    if l != '':
90      ii = i
91  return ii
92
93def  matchVals( thisv, valset ):
94  ll1 = []
95  ll2 = []
96  lk0 = []
97  kk = 0
98  for vals in valset:
99    l1 = min( [lennbl(thisv), lennbl(vals)] )
100    l2 = max( [lennbl(thisv), lennbl(vals)] )
101    ll = []
102    for i in range(l1):
103      ll.append( vals[i] == thisv[i] )
104    for i in range(l2-l1):
105      ll.append(False)
106    if all(ll):
107      return ll
108    k = 0
109    for l in ll:
110      if l:
111        k+=1
112    if ll[0]:
113      lk0.append( kk )
114     
115    ll1.append(k)
116    ll2.append(ll)
117    kk += 1
118  k0 = max( ll1 )
119  if len(lk0) > 0:
120    k0 = lk0[0]
121    return ll2[ k0 ]
122  return ll2[ ll1.index(k0) ]
123   
124class mipTable(object):
125
126  def __init__(self,id):
127     self.vars = collections.defaultdict( list )
128
129class rqsummary(object):
130  __doc__ = """Create a request summary table, by MIP and variable table.
131Creates a list of default dictionaries, one for each table. An entry for each MIP in each dictionary.
132"""
133
134  def __init__(self,exptInfo=None):
135    self.tablist = []
136    self.tabindx = {}
137    self.mips = collections.defaultdict( int )
138    self.vars = collections.defaultdict( list )
139    self.t = {}
140    self.records = []
141    self.exptInfo = exptInfo
142
143  def addTab(self,tab):
144    self.t[tab] = mipTable( tab )
145
146  def add(self,mip,path,tab):
147    self.tab = tab
148## rq will add a reference to parent
149    print '######',mip, path, tab
150    return rq(mip,path,parent=self,tab=tab)
151
152  def addItem( self, mip, tab, nn ):
153    if not self.tabindx.has_key( tab ):
154      self.tabindx[tab] = len(self.tablist)
155      self.tablist.append( collections.defaultdict( int ) )
156    ix = self.tabindx[tab]
157    self.tablist[ix][mip] = nn
158    self.mips[mip] += 1
159
160  def checkVars(self):
161    keys = self.vars.keys()
162    keys.sort()
163    for k in keys:
164      if len( self.vars[k] ) == 1:
165        print k, 'singleton'
166      else:
167        li = self.vars[k]
168## getting a bit intricate here -- 3rd element is index of record row
169        ll = [self.records[li[0][2]], ]
170        aa = collections.defaultdict( list )
171        aa[0].append[0]
172       
173  def prep(self,mode='vars',tab=None):
174    if tab != None:
175      self.tab = tab
176    kk = 0
177    mips = self.mips.keys()
178    mips.sort()
179    keys = self.tabindx.keys()
180    keys.sort()
181    self.oorecs = []
182    if mode == 'vars':
183      keys = self.t[self.tab].vars.keys()
184      keys.sort()
185      for k in keys:
186        rec = [k,]
187        ee1 = collections.defaultdict( list )
188        ee2 = {}
189        for t in self.t[self.tab].vars[k]:
190          k0 = joinRec( self.records[t[2]], tab=',', omit=[7,16,23] )
191          ee1[k0].append( t )
192        if len(ee1.keys()) > 1:
193          for k1 in ee1.keys():
194              for t in ee1[k1]:
195                ee2[t[0]] = k1
196          k1 = ee1.keys()
197          ee3 = collections.defaultdict( list )
198          for t in self.t[self.tab].vars[k]:
199            ee3[k1.index( ee2[t[0]] ) ].append( '%s[%s]' % (t[0],t[1]) )
200            rec.append( '%s[%s]{%s}' % (t[0],t[1],k1.index( ee2[t[0]]) ) )
201          ##self.oorecs.append(rec)
202          for kkk in k1:
203            ix = ee1[kkk][0][2]
204            ik = k1.index(kkk)
205            rec = [k, string.join(ee3[ik],';'),]   + list(self.records[ix])
206            self.oorecs.append(rec)
207           
208  def showXls(self,wb,r0=3,offset=0):
209    r = r0
210    thisStj = 2
211    for rec in self.oorecs:
212      i = offset
213      for item in rec:
214        wb.putValue2( r,i, item )
215        i+= 1
216      thisStj = 5 - thisStj
217      r+= 1
218   
219  def show(self,oo,mode='vars',tab=None):
220    if tab != None:
221      self.tab = tab
222    kk = 0
223    mips = self.mips.keys()
224    mips.sort()
225    keys = self.tabindx.keys()
226    keys.sort()
227    if mode == 'vars':
228      for rec in self.oorecs:
229            srec = joinRec( rec) + '\t' 
230            oo.write( srec + '\n' )
231
232    elif mode == 'oldvars':
233      keys = self.t[self.tab].vars.keys()
234      keys.sort()
235      for k in keys:
236        rec = '%s\t' % k
237        ee1 = collections.defaultdict( list )
238        ee2 = {}
239        for t in self.t[self.tab].vars[k]:
240          k0 = joinRec( self.records[t[2]], tab=',', omit=[7,16,23] )
241          ee1[k0].append( t )
242        if len(ee1.keys()) > 1:
243          for k1 in ee1.keys():
244              for t in ee1[k1]:
245                ee2[t[0]] = k1
246          k1 = ee1.keys()
247          for t in self.t[self.tab].vars[k]:
248            rec += '%s[%s]{%s}\t' % (t[0],t[1],k1.index( ee2[t[0]]) )
249          oo.write( rec + '\n' )
250          for kkk in k1:
251            ix = ee1[kkk][0][2]
252            rec = '--%s--\t' % k1.index(kkk) + joinRec( self.records[ix] ) + '\t' 
253            oo.write( rec + '\n' )
254    else:
255     oo.write( ',' + string.join(mips, ',') + ',\n' )
256     for k in keys:
257      r = []
258      ix = self.tabindx[k]
259      for m in mips:
260        r.append( self.tablist[ix][m] )
261      if max(r) > 0:
262        rec = '%s,' % k
263        for i in r:
264          rec += '%s,' %  i
265        oo.write( rec + '\n' )
266
267
268#dd_rq = collections.defaultdict( dict )
269#dd_tbl = collections.defaultdict( int )
270class rq(object):
271
272  def __init__(self, mip,path, parent=None,tab=u'Omon' ):
273
274    self.mip = mip
275    self.nn = 0
276    self.wk1 = wbcp( inbook=path )
277    if tab in  self.wk1.sns:
278      self.tab = tab
279      if mip == 'CMIP5':
280            self.tabid = tab
281      else:
282            self.tabid = '%s.%s' %  (mip,tab)
283      self.wk1.focus( tab)
284      self.parent = parent
285      if not self.parent.t.has_key(self.tabid):
286        self.parent.addTab(self.tabid)
287      self.ok = self.parse01()
288    else:
289      self.ok = False
290
291  def parse01(self):
292
293    ee1 = collections.defaultdict( list )
294    for j in range(3,self.wk1.currentSi.nrows):
295      if self.wk1.currentSi.row(j)[0].ctype == 2:
296        v = string.strip( str( self.wk1.currentSi.row(j)[5].value ) )
297        ee1[v].append(j)
298    for j in range(3,self.wk1.currentSi.nrows):
299      rv = map( lambda x: x.value, self.wk1.currentSi.row(j) )
300      lr0 = len(rv)
301      for i in range(10):
302        if len(rv) < 26:
303           rv.append('')
304      if self.wk1.currentSi.row(j)[0].ctype == 2:
305        v = string.strip( str( self.wk1.currentSi.row(j)[5].value ) )
306        if v not in ['0.0','']:
307          if len(ee1[v]) > 1:
308             v += '__%s' % ['a','b'][ee1[v].index(j)]
309          ixr = len(self.parent.records )
310          self.parent.records.append( tuple(rv[1:]) )
311          p = int( rv[0] + 0.001 )
312          if lr0 > 24:
313            if self.wk1.currentSi.row(j)[24].ctype == 2:
314              yv = int( rv[24] + 0.001 )
315              assert yv in [0,1,2], 'Invalid value in column Y, j=%s,v=%s' % (j,v)
316              if yv == 0:
317                p = None
318              elif yv == 2:
319                p = 1
320            elif rv[24] != '':
321              print 'WARNING[1]:', self.mip, v, p, rv[24]
322         
323          if p != None:
324            self.parent.t[self.tabid].vars[v].append( (self.mip,p,ixr) ) 
325            self.nn += 1
326
327    return True
328
329class main(object):
330  def __init__(self):
331    kk=3
332    self.idx = 0
333    self.sh = shelve.open( 'dreq_consol_tables_shelve_v20150714', 'n' )
334    self.shnv = shelve.open( 'dreq_consol_tables_nv_shelve_v20150714', 'n' )
335    self.shold = shelve.open( 'dreq_consol_tables_old_shelve_v20150714', 'n' )
336
337    base = '/home/martin/2014/wip/dreq/'
338    self.dir0 = '/home/martin/2014/wip/dreq/input/'
339    file = 'PMIP/CMIP6DataRequestCompilationTemplate_20141218_PMIP_v150228_final.xls'
340    file = 'C4MIP/CMIP6DataRequestCompilationTemplate_C4MIP_06March2015_submitted.xls'
341    fileTmpl = 'CMIP6DataRequestCompilationTemplate_20141218.xls'
342    self.newVars = 'CMIP6DataRequest_ConsolidatedNewVariables_20150708.xls'
343    self.nvd = {}
344
345    wk0 = wbcp( inbook=base+fileTmpl )
346    self.cfg = dreq_cfg.rqcfg()
347    wk0.focus( u'Experiments')
348    mlist = collections.defaultdict( list )
349    for i in range(2,wk0.currentSi.nrows):
350      mip = str(wk0.currentSi.row(i)[3].value)
351      vals = map( lambda x: x.value, wk0.currentSi.row(i) )
352      if mip != '':
353        mlist[mip].append( vals )
354   
355    self.mips = mlist.keys()
356    self.mips.sort()
357   
358    mipTrans ={ 'geoMIP':'GeoMIP' }
359    diagMips = ['DynVar','SIMIP']
360    k2 = self.cfg.ff.keys()
361    k2.sort()
362    nn = 0
363    for k in k2:
364      k = mipTrans.get( k,k)
365      if k not in self.mips and k not in diagMips:
366         print '%s not found' % k
367         nn += 1
368    assert nn == 0, 'MIP naming error?'
369
370    exptList = '/home/martin/Documents/CMIP6_ExpermentList_draft01April2015.xls'
371    wke = wbcp( exptList )
372    wke.focus( 'Experiments' )
373    expgs = collections.defaultdict( int )
374    expgsEns = collections.defaultdict( int )
375    expgsYpe = collections.defaultdict( int )
376    for k in range(2,wke.currentSi.nrows):
377      vals = map( lambda x: x.value, wke.currentSi.row(k) )
378      g = string.strip( vals[1] )
379      if g[:5] == 'DAMIP':
380        print '######',g,vals[12],vals[13]
381      expgs[g] += vals[13]
382      expgsEns[g] = vals[12]
383
384    for k in expgs.keys():
385      if expgsEns[k] == 0:
386        expgsYpe[k] = 0
387      else:
388        try:
389          expgsYpe[k] = expgs[k]/expgsEns[k]
390        except:
391          print k, expgs[k], expgsEns[k]
392          raise
393   
394    self.rqs= rqsummary(exptInfo=(expgs,expgsEns,expgsYpe))
395    self.exptInfo=(expgs,expgsEns,expgsYpe)
396
397  def loadNewVars(self):
398    assert os.path.isfile( self.newVars ), '%s not found' % self.newVars
399    wb = workbook(self.newVars)
400    sh = wb.book.sheet_by_name( 'New variables' )
401    oo = open( '/tmp/newvars.txt', 'w' )
402    for i in range(3,sh.nrows):
403      r = map( lambda x: x.value, sh.row(i) )
404      try:
405        oo.write( string.join(map(str,r) ) + '\n' )
406      except:
407        oo.write( r[0] + '  --- rest missing --- \n' )
408      if r[0] != '' and r[4] != '':
409        v = string.strip( str( r[4] ) )
410        if v[0] != '#':
411          bits = string.split(v,' ')
412          if len(bits) == 1:
413            m = str( r[0] )
414            p = 0
415            try:
416              if m == 'LUMIP':
417                p = int( r[12] )
418              else:
419                p = int( r[11] )
420            except:
421              print '!!!!!! Failed to read priority: ',v,m
422            if v[-2:] == '**':
423               v = v[:-2]
424            elif v[-1] == '!':
425               v = v[:-1]
426            if self.nvd.has_key(v):
427              print '#########',v,self.nvd[v],m,p
428            self.nvd[v] = [p,] + r
429    for v in self.nvd.keys():
430        k = str( uuid.uuid1() )
431        self.shnv[k] = self.nvd[v][:] + [k,]
432    oo.close()
433
434  def groups(self, vl3=None):
435    print self.cfg.ee.keys()
436    omit = ['ALL VARIABLES', 'Objectives','Experiments','Experiment Groups','Request scoping','New variables','__lists__']
437    keys = self.cfg.ee.keys()
438    keys.sort()
439    ee = {}
440    self.glist = []
441    for k in keys:
442        fn = self.cfg.ee[k]
443        path = '%s%s/%s' % (self.dir0,k,fn)
444        wb = workbook( path )
445        ss = []
446        for s in wb.sns:
447          if s not in omit:
448            ss.append(s)
449        for s in ss:
450          e1 = collections.defaultdict( int )
451          if s[:5] != 'CMIP5':
452           sh = wb.book.sheet_by_name( s ) 
453           ll = []
454           for i in range(sh.nrows):
455             thisr = sh.row(i)
456             tv = thisr[0].value
457             if tv[:10] == 'Short name':
458               ll.append(i)
459           assert len(ll) in [1,2], 'Could not parse sheet  %s, %s, %s' % (path,k,s)
460           if len(ll) == 1:
461## nt__grptbl = collections.namedtuple( 'grptbl', ['grp','var','srcTable','freq','description','shape','levels','timeProc','mask'] )
462             iv = 1
463             it = 0
464           else:
465             print '*************',k,s
466             iv = 0
467             it = -1
468             tv = sh.row(2)[1].value
469           irsh = 5
470           for i in range(ll[-1]+1,sh.nrows):
471             thisr = sh.row(i)
472             if iv == 1:
473                 ##self.ntr = nt__grptbl._make( getRowValues( thisr, minLen=9 ) + [105,k,''] )
474                lll = getRowValues( thisr, minLen=9 ) + [105,k,'']
475             else:
476                lll = getRowValues( thisr, minLen=10 ) + [k,'']
477                lll[1] = lll[0]
478                lll[0] = tv
479             if it >= 0:
480               tv = thisr[it].value
481             v = thisr[iv].value
482             bits = string.split(v, ' ')
483             if len(bits) > 1:
484               v = bits[0]
485             t = thisr[2].value
486             if t[:6] == "CMIP5_":
487               t = t[6:]
488             if len(string.split(t, ' ')) > 1:
489               t2 = string.split(t, ' ')[1]
490               t = string.split(t, ' ')[0]
491             else: 
492               t2 = None
493             if t in ['OImon','day','Omon'] and t2 != None:
494               v2 = string.strip(t2)[1:-1]
495             else:
496               v2 = None
497
498             if v == '*':
499               if t in self.cmip5sns:
500                 print 'INFO[1a]: bulk copy of external sheet %s' % t
501               elif t in ss:
502                 print 'INFO[1b]: bulk copy of internal sheet %s' % t
503
504             elif len(v) == 0 or v[0] == '#':
505               pass
506             else:
507
508               if vl3 != None:
509                 if vl3.has_key(v):
510                   id = vl3[v][7]
511                 elif v2 != None and vl3.has_key(v2):
512                   id = vl3[v2][7]
513                 else:
514                   id = None
515
516               if t in self.cmip5sns:
517                 p = 9
518                 if self.rqs.t.has_key(t):
519                   if self.rqs.t[t].vars.has_key(v):
520                     p = self.rqs.t[t].vars[v][0][1]
521                   elif v2 != None and self.rqs.t[t].vars.has_key(v2):
522                     p = self.rqs.t[t].vars[v2][0][1]
523                     ##print '%s old name for %s' % (v2,v)
524                   else:
525                     p = 8
526                 
527               else:
528                 if string.lower(t)[:3] == 'new' or t == '':
529                   p = self.nvd.get( v, [0,7] )[1]
530                   if p == 7:
531                     p = self.nvd.get( v + '!', [0,7] )[1]
532                   if p != 7:
533                     self.idx += 1
534                     id = 'mv.010.%4.4i' % self.idx
535               if id == None and p < 7:
536                  print 'WARNING[1]: no id for %s' % v
537               elif id == None:
538                  print 'WARNING[2]: no id, no variable defn for %s' % v
539               elif p > 6:
540                  print 'WARNING[3.%s]: no variable defn for %s ' % (p,v)
541               ts = string.strip(thisr[irsh].value)
542               if string.strip(tv) != '':
543                 e1['%s:%s' % (ts,p)] += 1
544
545### complete ntr and save to shelf.
546             lll[9] = p
547             self.ntr = nt__grptbl._make( lll )
548             ku = str( uuid.uuid1() )
549             lll[11] = ku
550             self.sh[ku] = tuple( lll )
551###   MIP, group, size, dictionary -- # items in each shape.
552           self.glist.append( (k, s, ll, e1) )
553
554  def run1(self,nmip=0,kmip=0,clear=False):
555    if clear:
556      self.rqs.t = {}
557    self.cfg.ff['CMIP5'] = ['/data/work/documents/CMIP5_standard_output.xls']
558    wb = workbook( self.cfg.ff['CMIP5'][0] )
559    wb.sns.sort()
560    omit1 = [u'dims', u'general', u'other output',u'CFMIP output']
561    sns = []
562    for s in wb.sns:
563      if s not in omit1:
564        sns.append(s)
565
566    self.cmip5sns = sns[:]
567    k2 = self.cfg.ff.keys()
568    k2.sort()
569    k2.append( 'CMIP5' )
570
571    amips = ['CMIP5'] + self.mips
572    if nmip > 0:
573       amips = amips[kmip:kmip+nmip]
574    for s in sns:
575     for k in amips:
576      if k in k2:
577        for fn in self.cfg.ff[k]:
578          if k == 'CMIP5':
579            path = fn
580          else:
581            path = '%s%s/%s' % (self.dir0,k,fn)
582          thisrq = self.rqs.add( k, path,s )
583          if thisrq.ok:
584            print k,path,s,thisrq.ok, thisrq.nn
585          else:
586            print k,path,s,thisrq.ok
587
588  def run2(self):
589    init=False
590    if init:
591      wbx = wbcp( '/home/martin/Documents/MIPTableSheetTemplate.xls' )
592    else:
593      wbx = wbcp( 'CMIP6_DataRequest_CMIP5changes_blank.xls' )
594
595    print self.rqs.t.keys()
596    for s in wbx.sns:
597     if s != u'Template':
598      keys = self.rqs.t[s].vars.keys()
599      keys.sort()
600      ##for k in keys:
601         ##print k, self.rqs.t[s].vars[k]
602      self.rqs.prep( tab=s )
603      print s, len(self.rqs.oorecs)
604      if len(self.rqs.oorecs) > 0:
605         if init:
606           wbx.copy_sheet( 0, s )
607           wbx.focus( s, old='Template' )
608         else:
609           wbx.focus( s )
610           self.rqs.showXls(wbx,r0=2,offset=0)
611   
612         for i in range( min( 5, len( self.rqs.oorecs) ) ):
613           print self.rqs.oorecs[i]
614   
615         oo = open( 'dreq2/request2_%s.csv' % s, 'w' )
616         self.rqs.show( oo, tab=s )
617         oo.close()
618
619    wbx.write( 'CMIP6_DataRequest_CMIP5changes.xls' )
620
621vl3 = {}
622wb3 = workbook( 'vlsc5b_v20150714.xls' )
623sh = wb3.book.sheet_by_name( 'Sheet1' )
624m = main()
625
626opt = 1
627if opt == 1:
628  for i in range(sh.nrows):
629    r = map( lambda x: string.strip(str(uniCleanFunc(x.value))), sh.row(i) )
630    if len(r) < 9 or r[8] == '':
631      vl3[r[1]] = tuple( r[:8] )
632    m.shold[r[0]] = r
633
634
635  m.run1(nmip=1)
636  m.loadNewVars()
637  m.groups( vl3=vl3)
638  k = m.sh.keys()[4]
639  print '##############################################'
640  print k
641  print m.sh[k]
642  m.sh.close()
643  m.shnv.close()
644  m.shold.close()
645 
646  m.run1( clear=True)
647  keys = sorted( m.rqs.t )
648  sh = shelve.open( 'dreq_consol_tables_reviewed_a_v20150708', 'n' )
649  sh['records'] = m.rqs.records[:] 
650  sh.close()
651  sh = shelve.open( 'dreq_consol_tables_reviewed_b_v20150708', 'n' )
652  sh['__keys__'] = map( str, keys[:] )
653  for k in keys:
654    vs = sorted( m.rqs.t[k].vars)
655    ee = {}
656    print '#############',k,len(vs),'#################'
657    m.rqs.vn = {}
658    for v in vs:
659      for mip,p,ix in m.rqs.t[k].vars[v]:
660        this = m.rqs.records[ix]
661        if this[16] in ['','0.0',0.0]:
662          vn = this[4]
663        else:
664          vn = this[16]
665        if ee.has_key(vn):
666          print '***********************DUPLICATE',vn
667          print m.rqs.t[k].vars[v]
668          print m.rqs.records[ee[vn][0]]
669          print m.rqs.records[ix]
670        ee[vn] = (ix,p)
671    k2 = str(k)
672    m.rqs.vn[k2] = ee
673    sh[k2] = ee.copy()
674  sh.close()
675   
676  print m.idx
677elif opt == 2:
678  m.run1( clear=True)
679  m.run2()
Note: See TracBrowser for help on using the repository browser.