source: CMIP6dreqbuild/trunk/src/framework/dreqPy/scope.py @ 558

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreqbuild/trunk/src/framework/dreqPy/scope.py@558
Revision 558, 25.1 KB checked in by mjuckes, 5 years ago (diff)

Adding hdldemo

Line 
1"""Date Request Scoping module
2---------------------------
3The scope.py module contains the dreqQuery class and a set of ancilliary functions. The dreqQuery class contains methods for analysing the data request.
4"""
5try:
6  import dreq
7  from utilities import cmvFilter
8except:
9  import dreqPy.dreq
10  from dreqPy.utilities import cmvFilter
11
12import collections, string, operator
13import sys
14
15python2 = True
16if sys.version_info[0] == 3:
17  python2 = False
18  from functools import reduce
19  try: 
20    from utilP3 import mlog3
21  except:
22    from dreqPy.utilP3 import mlog3
23  mlg = mlog3()
24else:
25  from utilP2 import mlog
26  mlg = mlog()
27
28class baseException(Exception):
29  """Basic exception for general use in code."""
30
31  def __init__(self,msg):
32    self.msg = 'scope:: %s' % msg
33
34  def __str__(self):
35    return repr( self.msg )
36
37  def __repr__(self):
38    return self.msg
39
40nt_mcfg = collections.namedtuple( 'mcfg', ['nho','nlo','nha','nla','nlas','nls','nh1'] )
41class cmpd(object):
42  def __init__(self,dct):
43    self.d = dct
44  def cmp(self,x,y,):
45    return cmp( self.d[x], self.d[y] )
46
47    self.default_mcfg = nt_mcfg._make( [259200,60,64800,40,20,5,100] )
48
49def filter1( a, b ):
50  if b < 0:
51    return a
52  else:
53    return min( [a,b] )
54
55def filter2( a, b, tt, tm ):
56## largest tier less than or equal to tm
57  t1 = [t for t in tt if t <= tm][-1]
58  it1 = tt.index(t1)
59  aa = a[it1]
60  if b < 0:
61    return aa
62  else:
63    return min( [aa,b] )
64
65npy = {'daily':365, u'Annual':1, u'fx':0.01, u'1hr':24*365, u'3hr':8*365, u'monClim':12, u'Timestep':100, u'6hr':4*365, u'day':365, u'1day':365, u'mon':12, u'yr':1, u'1mon':12, 'month':12, 'year':1, 'monthly':12, 'hr':24*365, 'other':24*365, 'subhr':24*365, 'Day':365, '6h':4*365,
66'3 hourly':8*365, '':1 }
67## There are 4 cmor variables with blank frequency ....
68
69def vol01( sz, v, npy, freq, inx ):
70  n1 = npy[freq]
71  s = sz[inx.uid[v].stid]
72  assert type(s) == type(1), 'Non-integer size found for %s' % v
73  assert type(n1) in (type(1),type(0.)), 'Non-number "npy" found for %s, [%s]' % (v,freq)
74  return s*n1
75
76class col_list(object):
77  def __init__(self):
78    self.a = collections.defaultdict(list)
79
80class col_count(object):
81  def __init__(self):
82    self.a = collections.defaultdict(int)
83
84class dreqQuery(object):
85  __doc__ = """Methods to analyse the data request, including data volume estimates"""
86  def __init__(self,dq=None,tierMax=1):
87    if dq == None:
88      self.dq = dreq.loadDreq()
89    else:
90      self.dq=dq
91    self.rlu = {}
92    for i in self.dq.coll['objective'].items:
93      k = '%s.%s' % (i.mip,i.label)
94      assert not k in self.rlu, 'Duplicate label in objectives: %s' % k
95      self.rlu[k] = i.uid
96
97    self.cmvFilter = cmvFilter( self )
98    self.tierMax = tierMax
99
100    self.mips = set( [x.label for x in self.dq.coll['mip'].items ] )
101    self.mipls = sorted( list( self.mips ) )
102
103    self.default_mcfg = nt_mcfg._make( [259200,60,64800,40,20,5,100] )
104    self.mcfg = self.default_mcfg._asdict()
105    ##for k in self.default_mcfg.__dict__.keys():
106      ##self.mcfg[k] = self.default_mcfg.__dict__[k]
107    self.szcfg()
108    self.requestItemExpAll(  )
109
110  def szcfg(self):
111    self.szss = {}
112    self.sz = {}
113    for i in self.dq.coll['spatialShape'].items:
114      type = 'a'
115      if i.levelFlag == False:
116        ds =  i.dimensions.split( '|' )
117        if ds[-1] in ['site', 'basin']:
118          vd = ds[-2]
119        else:
120          vd = ds[-1]
121 
122        if vd[:4] == 'olev' or vd == 'rho':
123          type = 'o'
124          nz = self.mcfg['nlo']
125        elif vd[:4] == 'alev':
126          nz = self.mcfg['nla']
127        elif vd in ['slevel','sdepth']:
128          nz = self.mcfg['nls']
129        elif vd == 'aslevel':
130          nz = self.mcfg['nlas']
131        else:
132          mlg.prnt( 'Failed to parse dimensions %s' % i.dimensions )
133          raise
134      else:
135        nz = i.levels
136
137      dims = set( i.dimensions.split( '|' ) )
138      if 'latitude' in dims and 'longitude' in dims:
139        if type == 'o':
140          nh = self.mcfg['nho']
141        else:
142          nh = self.mcfg['nha']
143      else:
144        nh = 10
145
146      self.szss[i.uid] = nh*nz
147    for i in self.dq.coll['structure'].items:
148      s = self.szss[i.spid]
149      if i.odims != '':
150        s = s*5
151      self.sz[i.uid] = s
152
153  def getRequestLinkByMip( self, mipSel ):
154    """Return the set of request links which are associated with specified MIP"""
155    if type(mipSel) == type(''):
156      t1 = lambda x: x == mipSel
157    elif type(mipSel) == type(set()):
158      t1 = lambda x: x in mipSel
159
160    s = set()
161    for i in self.dq.coll['objectiveLink'].items:
162      if t1(i.label):
163        s.add( self.dq.inx.uid[i.rid] )
164    ##self.rqs = list({self.dq.inx.uid[i.rid] for i in self.dq.coll['objectiveLink'].items if t1(i.label) })
165    self.rqs = list( s )
166    return self.rqs
167
168  def getRequestLinkByObjective( self, objSel ):
169    """Return the set of request links which are associated with specified objectives"""
170    if type(objSel) == type(''):
171      t1 = lambda x: x == self.rlu[objSel]
172    elif type(objSel) == type(set()):
173      t1 = lambda x: x in [self.rlu[i] for i in objSel]
174
175    s = set()
176    for i in self.dq.coll['objectiveLink'].items:
177      if t1(i.label):
178        s.add( self.dq.inx.uid[i.oid] )
179##
180    self.rqs = list( s )
181    ##self.rqs = list({self.dq.inx.uid[i.rid] for i in self.dq.coll['objectiveLink'].items if t1(i.oid) })
182    return self.rqs
183
184  def varGroupXexpt(self, rqList ):
185    """For a list of request links, return a list of variable group IDs for each experiment"""
186    self.cc = collections.defaultdict( list )
187    ## dummy = {self.cc[i.expt].append(i.rlid) for i in self.dq.coll['requestItem'].items if i.rlid in {j.uid for j in rqList} }
188    return self.cc
189
190  def yearsInRequest(self, rql ):
191    self.ntot = sum( [i.ny for i in self.dq.coll['requestItem'].items if i.rlid == rql.uid] )
192    return self.ntot
193
194  def rqlByExpt( self, l1, ex, pmax=2, expFullEx=False ):
195    """rqlByExpt: return a set of request links for an experiment"""
196##
197    inx = self.dq.inx
198   
199    exi = self.dq.inx.uid[ex]
200    if exi._h.label == 'experiment':
201      exset = set( [ex,exi.egid,exi.mip] )
202    else:
203      exset = set( self.esid_to_exptList(ex,deref=False,full=expFullEx) )
204##
205## rql is the set of all request links which are associated with a request item for this experiment set
206##
207    l1p = set()
208    for i in l1:
209      if i.preset < 0 or i.preset <= pmax:
210        if i.esid in exset:
211          l1p.add(i)
212
213    rql0 = set()
214    for i in l1p:
215       rql0.add(i.rlid)
216
217    rqlInv = set()
218    for u in rql0:
219      if inx.uid[u]._h.label == 'remarks':
220        rqlInv.add( u )
221    if len(rqlInv) != 0:
222      mlg.prnt ( 'WARNING.001.00002: %s invalid request links from request items ...' % len(rqlInv) )
223    rql = set()
224    for u in rql0:
225       if inx.uid[u]._h.label != 'remarks':
226         rql.add( u ) 
227
228    return rql, l1p, exset
229
230  def varsByRql( self, rql, pmax=2, intersection=False): 
231      """The complete set of variables associated with a set of rquest links."""
232      inx = self.dq.inx
233      cc1 = collections.defaultdict( set )
234      for i in rql:
235        o = inx.uid[i]
236        if o.opt == 'priority':
237          p = int( float( o.opar ) )
238          assert p in [1,2,3], 'Priority incorrectly set .. %s, %s, %s' % (o.label,o.title, o.uid)
239          cc1[inx.uid[i].mip].add( (inx.uid[i].refid,p) )
240        else:
241          cc1[inx.uid[i].mip].add( inx.uid[i].refid )
242
243      if intersection:
244        ccv = {}
245#
246# set of request variables for each MIP
247#
248        for k in cc1:
249          thisc = reduce( operator.or_, [set( inx.iref_by_sect[vg].a['requestVar'] ) for vg in cc1[k] ] )
250          rqvgs = collections.defaultdict( set )
251          for x in cc1[k]:
252            if type(x) == type( () ):
253              rqvgs[x[0]].add( x[1] )
254            else:
255              rqvgs[x].add( 3 )
256         
257          s = set()
258          for vg in rqvgs:
259            for l in inx.iref_by_sect[vg].a['requestVar']:
260              if inx.uid[l].priority <= min(pmax,max(rqvgs[vg])):
261                s.add( inx.uid[l].vid )
262          ccv[k] = s
263
264        if len( ccv.keys() ) < len( list(imips) ):
265          vars = set()
266        else:
267          vars =  reduce( operator.and_, [ccv[k] for k in ccv] )
268      else:
269        rqvgs = collections.defaultdict( set )
270        for k in cc1:
271          for x in cc1[k]:
272            if type(x) == type( () ):
273              rqvgs[x[0]].add( x[1] )
274            else:
275              rqvgs[x].add( 3 )
276         
277###To obtain a set of variables associated with this collection of variable groups:
278
279        vars = set()
280        for vg in rqvgs:
281          for l in inx.iref_by_sect[vg].a['requestVar']:
282            if inx.uid[l].priority <= min(pmax,max(rqvgs[vg])):
283               vars.add(inx.uid[l].vid)
284        ##col1 = reduce( operator.or_, [set( inx.iref_by_sect[vg].a['requestVar'] ) for vg in rqvg ] )
285
286### filter out cases where the request does not point to a CMOR variable.
287    ##vars = {vid for vid in vars if inx.uid[vid][0] == u'CMORvar'}
288      thisvars = set()
289      for vid in vars:
290         if inx.uid[vid]._h.label == u'CMORvar':
291             thisvars.add(vid)
292
293      return thisvars
294
295  def volByExpt( self, l1, ex, pmax=1, cc=None, retainRedundantRank=False, intersection=False,expFullEx=False, adsCount=False ):
296    """volByExpt: calculates the total data volume associated with an experiment/experiment group and a list of request items.
297          The calculation has some approximations concerning the number of years in each experiment group.
298          cc: an optional collector, to accumulate indexed volumes. """
299##
300    inx = self.dq.inx
301    imips = set()
302    for i in l1:
303      imips.add(i.mip)
304    ##imips = {i.mip for i in l1}
305   
306    rql, l1p, exset = self.rqlByExpt( l1, ex, pmax=pmax, expFullEx=expFullEx )
307    dn = False
308    if dn:
309      exi = self.dq.inx.uid[ex]
310      if exi._h.label == 'experiment':
311        exset = set( [ex,exi.egid,exi.mip] )
312      else:
313        exset = set( self.esid_to_exptList(ex,deref=False,full=expFullEx) )
314##
315## rql is the set of all request links which are associated with a request item for this experiment set
316##
317      l1p = set()
318      for i in l1:
319        if i.preset < 0 or i.preset <= pmax:
320          if i.esid in exset:
321            l1p.add(i)
322 
323      rql0 = set()
324      for i in l1p:
325         rql0.add(i.rlid)
326 
327      rqlInv = set()
328      for u in rql0:
329        if inx.uid[u]._h.label == 'remarks':
330          rqlInv.add( u )
331      if len(rqlInv) != 0:
332        mlg.prnt ( 'WARNING.001.00002: %s invalid request links from request items ...' % len(rqlInv) )
333      rql = set()
334      for u in rql0:
335         if inx.uid[u]._h.label != 'remarks':
336           rql.add( u ) 
337    else:
338      exi = self.dq.inx.uid[ex]
339      if exi._h.label == 'experiment':
340        exset = set( [ex,exi.egid,exi.mip] )
341
342#####
343    if len( rql ) == 0:
344      self.vars = set()
345      return (0,{},{} )
346
347## The complete set of variables associated with these requests:
348    vars = self.varsByRql( rql, pmax=pmax, intersection=intersection) 
349    tm = 3
350    if tm == 0:
351      s = set()
352      for i in rql:
353        s.add( inx.uid[i].refid )
354      rqvg = list( s )
355    elif tm == 1:
356      cc1 = collections.defaultdict( set )
357      for i in rql:
358        o = inx.uid[i]
359        if o.opt == 'priority':
360          p = int( float( o.opar ) )
361          assert p in [1,2,3], 'Priority incorrectly set .. %s, %s, %s' % (o.label,o.title, o.uid)
362          cc1[inx.uid[i].mip].add( (inx.uid[i].refid,p) )
363        else:
364          cc1[inx.uid[i].mip].add( inx.uid[i].refid )
365
366      if intersection:
367        ccv = {}
368#
369# set of request variables for each MIP
370#
371        for k in cc1:
372          thisc = reduce( operator.or_, [set( inx.iref_by_sect[vg].a['requestVar'] ) for vg in cc1[k] ] )
373          rqvgs = collections.defaultdict( set )
374          for x in cc1[k]:
375            if type(x) == type( () ):
376              rqvgs[x[0]].add( x[1] )
377            else:
378              rqvgs[x].add( 3 )
379         
380          s = set()
381          for vg in rqvgs:
382            for l in inx.iref_by_sect[vg].a['requestVar']:
383              if inx.uid[l].priority <= min(pmax,max(rqvgs[vg])):
384                s.add( inx.uid[l].vid )
385          ccv[k] = s
386
387        if len( ccv.keys() ) < len( list(imips) ):
388          vars = set()
389        else:
390          vars =  reduce( operator.and_, [ccv[k] for k in ccv] )
391      else:
392        rqvgs = collections.defaultdict( set )
393        for k in cc1:
394          for x in cc1[k]:
395            if type(x) == type( () ):
396              rqvgs[x[0]].add( x[1] )
397            else:
398              rqvgs[x].add( 3 )
399         
400###To obtain a set of variables associated with this collection of variable groups:
401
402        vars = set()
403        for vg in rqvgs:
404          for l in inx.iref_by_sect[vg].a['requestVar']:
405            if inx.uid[l].priority <= min(pmax,max(rqvgs[vg])):
406               vars.add(inx.uid[l].vid)
407        ##col1 = reduce( operator.or_, [set( inx.iref_by_sect[vg].a['requestVar'] ) for vg in rqvg ] )
408
409### filter out cases where the request does not point to a CMOR variable.
410    ##vars = {vid for vid in vars if inx.uid[vid][0] == u'CMORvar'}
411      thisvars = set()
412      for vid in vars:
413         if inx.uid[vid]._h.label == u'CMORvar':
414             thisvars.add(vid)
415      vars = thisvars
416##
417## filter by configuration option and rank
418##
419    if not retainRedundantRank:
420      len1 = len(vars)
421      cmv = self.cmvFilter.filterByChoiceRank(cmv=vars)
422
423      vars = cmv
424   
425    self.vars = vars
426
427    e = {}
428    for u in rql:
429### for request variables which reference the variable group attached to the link, add the associate CMOR variables, subject to priority
430      i = inx.uid[u]
431      e[i.uid] = set()
432      for x in inx.iref_by_sect[i.refid].a['requestVar']:
433           if inx.uid[x].priority <= pmax:
434              e[i.uid].add( inx.uid[x].vid )
435#
436# for each variable, calculate the maximum number of years across all the request links which reference that variable.
437##
438## for each request item we have nymax, nenmax, nexmax.
439##
440    nym = {}
441
442##
443## if dataset count rather than volume is wanted, use item 3 from rqiExp tuple.
444    if adsCount:
445      irqi = 3
446    else:
447      irqi = 2
448
449    for v in vars:
450      s = set()
451      cc2 = collections.defaultdict( set )
452      for i in l1p:
453##################
454        if i.esid in exset and v in e[i.rlid]:
455          ix = inx.uid[i.esid]
456          if exi._h.label == 'experiment':
457            if ex in self.rqiExp[i.uid][1]:
458              this = self.rqiExp[i.uid][1][ex]
459              cc2[i.esid].add( this[-1]*this[-2] )
460          elif ix._h.label == 'experiment':
461            cc2[i.esid].add( self.rqiExp[i.uid][irqi] )
462          else:
463            if 'experiment' in inx.iref_by_sect[i.esid].a:
464              for u in inx.iref_by_sect[i.esid].a['experiment']:
465                if u in self.rqiExp[i.uid][1]:
466                  this = self.rqiExp[i.uid][1][u]
467                  cc2[u].add( this[-1]*this[-2] )
468                ###cc2[u].add( self.rqiExp[i.uid][irqi] )
469            ##else:
470              ##print 'WARNING .... empty experiment set'
471          s.add( self.rqiExp[i.uid][irqi] )
472      ##nym[v] = max( {self.rqiExp[i.uid][2] for i in l1p if i.esid == ex and v in e[i.rlid]} )
473      if len(s) == 0:
474        nym[v] = 0
475      else:
476        ##print 'debug2:: ',v,cc2
477        nym[v] = sum( [max( cc2[k] ) for k in cc2] )
478
479    szv = {}
480    ov = []
481    for v in vars:
482      szv[v] = self.sz[inx.uid[v].stid]*npy[inx.uid[v].frequency]
483      ov.append( self.dq.inx.uid[v] )
484    ee = self.listIndexDual( ov, 'mipTable', 'label', acount=None, alist=None, cdict=szv, cc=cc )
485    ff = {}
486    for v in vars:
487      if adsCount:
488        ff[v] = nym[v]
489      else:
490        ff[v] = self.sz[ inx.uid[v].stid ] * npy[inx.uid[v].frequency] * nym[v]
491    self.ngptot = sum( [  ff[v]  for v in vars] )
492    return (self.ngptot, ee, ff )
493
494  def esid_to_exptList(self,esid,deref=False,full=False):
495    if not esid in self.dq.inx.uid:
496      mlg.prnt ( 'Attempt to dereferece invalid uid: %s' % esid )
497      raise
498
499    if self.dq.inx.uid[esid]._h.label == 'experiment':
500      expts = [esid,]
501    elif self.dq.inx.uid[esid]._h.label != 'remarks':
502      if esid in self.dq.inx.iref_by_sect and 'experiment' in self.dq.inx.iref_by_sect[esid].a:
503        expts = list( self.dq.inx.iref_by_sect[esid].a['experiment'][:] )
504      else:
505        expts = []
506
507## add in groups and mips for completeness
508##
509      if full:
510        if self.dq.inx.uid[esid]._h.label == 'mip':
511          s = set()
512          for e in expts:
513            if self.dq.inx.uid[e]._h.label != 'experiment':
514              mlg.prnt ( 'ERROR: %s, %s, %s ' % (esid,e, self.dq.inx.uid[e].title ) )
515            s.add( self.dq.inx.uid[e].egid )
516          for i in s:
517            expts.append( i )
518        expts.append( esid )
519    else:
520      ##print ( 'WARNING: request link not associated with valid experiment group' )
521      ##raise
522      return None
523
524
525    if self.tierMax > 0:
526      expts1 = []
527      for i in expts:
528        if self.dq.inx.uid[i]._h.label == 'experiment':
529          if self.dq.inx.uid[i].tier[0] <= self.tierMax:
530            expts1.append( i )
531        elif self.dq.inx.uid[i]._h.label == 'exptgroup':
532          if self.dq.inx.uid[i].tierMin <= self.tierMax:
533            expts1.append( i )
534        else:
535            expts1.append( i )
536    else:
537      expts1 = expts
538
539    if deref:
540      return [self.dq.inx.uid[e] for e in expts1]
541    else:
542      return expts1
543 
544##
545## need to call this on load
546## then use instead of i.ny etc below
547##
548  def requestItemExpAll( self ):
549    self.rqiExp = {}
550    for rqi in self.dq.coll['requestItem'].items:
551      a,b,c,d = self.requestItemExp( rqi )
552      if a != None:
553        self.rqiExp[rqi.uid] = (a,b,c,d)
554
555  def requestItemExp( self, rqi ):
556    assert rqi._h.label == "requestItem", 'Argument to requestItemExp must be a requestItem'
557    u = rqi.esid
558    if self.dq.inx.uid[u]._h.label == 'experiment':
559      expts = [u,]
560    elif self.dq.inx.uid[u]._h.label != 'remarks':
561      if u in self.dq.inx.iref_by_sect and 'experiment' in self.dq.inx.iref_by_sect[u].a:
562        expts = self.dq.inx.iref_by_sect[u].a['experiment']
563      else:
564        expts = []
565    else:
566      # print ( 'WARNING: request link not associated with valid experiment group'  )
567      ##rqi.__info__()
568      ##raise
569      return (None, None, None, None)
570
571    if self.tierMax > 0:
572      expts = [i for i in expts if self.dq.inx.uid[i].tier[0] <= self.tierMax]
573
574    self.multiTierOnly = False
575    if self.multiTierOnly:
576      expts = [i for i in expts if len(self.dq.inx.uid[i].tier) > 1]
577      print ('Len expts: %s' % len(expts) )
578
579    if len(expts) > 0:
580      e = [self.dq.inx.uid[i] for i in expts]
581      for i in e:
582        if i._h.label != 'experiment':
583          mlg.prnt ( 'ERROR: %s, %s, %s ' % ( u,i._h.label, i.label, i.title ) )
584      ##dat = [ (i.ntot, i.yps, i.ensz, i.tier, i.nstart, filter1(i.yps,rqi.nymax), filter2(i.ensz,rqi.nenmax,i.tier,self.tierMax) ) for i in e]
585      dat2 = {}
586      for i in e:
587        dat2[i.uid] = (i.ntot, i.yps, i.ensz, i.tier, i.nstart, filter1(i.yps,rqi.nymax), filter2(i.ensz,rqi.nenmax,i.tier,self.tierMax) )
588      ### number of
589      nytot = sum( [dat2[x][-2]*dat2[x][-3] for x in dat2 ] )
590      netot = sum( [dat2[x][-1] for x in dat2 ] )
591      ##print 'debug1:: ',dat, nytot, netot
592    else:
593      dat2 = {}
594      nytot = 0
595      netot = 0
596   
597    return (expts, dat2, nytot, netot )
598
599  def setTierMax( self, tierMax ):
600    """Set the maxium tier and recompute request sizes"""
601    if tierMax != self.tierMax:
602      self.tierMax = tierMax
603      self.requestItemExpAll(  )
604
605  def summaryByMip( self, pmax=1 ):
606    bytesPerFloat = 2.
607    for m in self.mipls:
608      v = self.volByMip( m, pmax=pmax )
609      mlg.prnt ( '%12.12s: %6.2fTb' % (m,v*bytesPerFloat*1.e-12) )
610
611  def rqiByMip( self, mip):
612
613    if type(mip) in [type( '' ),type( u'') ]:
614      if mip not in self.mips:
615        mlg.prnt ( self.mips )
616        raise baseException( 'rqiByMip: Name of mip not recognised: %s' % mip )
617      l1 = [i for i in  self.dq.coll['requestItem'].items if i.mip == mip]
618    elif type(mip) == type( set()):
619      nf = [ m for m in mip if m not in self.mips]
620      if len(nf) > 0:
621        raise baseException( 'rqiByMip: Name of mip(s) not recognised: %s' % str(nf) )
622      l1 = [i for i in  self.dq.coll['requestItem'].items if i.mip in mip]
623    else:
624      raise baseException( 'rqiByMip: "mip" (1st explicit argument) should be type string or set: %s -- %s' % (mip, type(mip))   )
625    return l1
626     
627  def volByMip( self, mip, pmax=2, retainRedundantRank=False, intersection=False, adsCount=False, exptid=None):
628
629    l1 = self.rqiByMip( mip )
630     
631    #### The set of experiments/experiment groups:
632    if exptid == None:
633      exps = self.mips
634    else:
635      exps = set( [exptid,] )
636      ##print exptid, exps
637    self.volByE = {}
638    vtot = 0
639    cc = collections.defaultdict( col_count )
640    self.allVars = set()
641    for e in exps:
642      expts = self.esid_to_exptList(e,deref=True,full=False)
643      if expts != None:
644        self.volByE[e] = self.volByExpt( l1, e, pmax=pmax, cc=cc, retainRedundantRank=retainRedundantRank, intersection=intersection, adsCount=adsCount )
645        vtot += self.volByE[e][0]
646        self.allVars = self.allVars.union( self.vars )
647    self.indexedVol = cc
648
649    return vtot
650
651  def listIndexDual(self, ll, a1, a2, acount=None, alist=None, cdict=None, cc=None ):
652    do_count = acount != None
653    do_list = alist != None
654    assert not (do_count and do_list), 'It is an error to request both list and count'
655    if not (do_count or do_list):
656      acount = '__number__'
657      do_count = True
658
659    if cc == None:
660      if do_count:
661        cc = collections.defaultdict( col_count )
662      elif do_list:
663        cc = collections.defaultdict( col_list )
664
665    if do_count:
666      for l in ll:
667        if cdict != None:
668          v = cdict[l.uid]
669        elif acount == '__number__':
670          v = 1
671        else:
672          v = l.__dict__[acount]
673
674        cc[ l.__dict__[a1] ].a[ l.__dict__[a2] ] += v
675    elif do_list:
676      for l in ll:
677        if cdict != None:
678          v = cdict[l.uid]
679        elif alist == '__item__':
680          v = l
681        else:
682          v = l.__dict__[alist]
683        cc[ l.__dict__[a1] ].a[ l.__dict__[a2] ].append( v )
684
685    od = {}
686    for k in cc.keys():
687      d2 = {}
688      for k2 in cc[k].a.keys():
689        d2[k2] = cc[k].a[k2]
690      od[k] = d2
691    return od
692
693class dreqUI(object):
694  """Data Request Command line.
695-------------------------
696      -v : print version and exit;
697      --unitTest : run some simple tests;
698      -m <mip>:  MIP of list of MIPs (comma separated);
699      -h :       help: print help text;
700      -e <expt>: experiment;
701      -t <tier> maxmum tier;
702      -p <priority>  maximum priority;
703      --printLinesMax <n>: Maximum number of lines to be printed
704      --printVars  : If present, a summary of the variables fitting the selection options will be printed
705      --intersection : Analyse the intersection of requests rather than union.
706"""
707  def __init__(self,args):
708    self.adict = {}
709    self.knownargs = {'-m':('m',True), '-p':('p',True), '-e':('e',True), '-t':('t',True), '-h':('h',False), '--printLinesMax':('plm',True), '--printVars':('vars',False), '--intersection':('intersection',False),'--count':('count',False)} 
710    aa = args[:]
711    while len(aa) > 0:
712      a = aa.pop(0)
713      if a in self.knownargs:
714        b = self.knownargs[a][0]
715        if self.knownargs[a][1]:
716          v = aa.pop(0)
717          self.adict[b] = v
718        else:
719          self.adict[b] = True
720
721    if 'm' in self.adict:
722      self.adict['m'] = set(self.adict['m'].split(',') )
723
724    integerArgs = set( ['p','t','plm'] )
725    for i in integerArgs.intersection( self.adict ):
726      self.adict[i] = int( self.adict[i] )
727
728    self.intersection = self.adict.get( 'intersection', False )
729
730  def run(self, dq=None):
731    if 'h' in self.adict:
732      mlg.prnt ( self.__doc__ )
733      return
734
735    if not 'm' in self.adict:
736      mlg.prnt ( 'Current version requires -m argument'  )
737      mlg.prnt ( self.__doc__ )
738      sys.exit(0)
739
740    if dq == None:
741      self.dq = dreq.loadDreq()
742    else:
743      self.dq = None
744
745    sc = dreqQuery( dq=self.dq )
746
747    ok = True
748    for i in self.adict['m']:
749        if i not in sc.mips:
750          ok = False
751          mlg.prnt ( 'NOT FOUND: %s' % i )
752
753    eid = None
754    if self.adict.has_key('e'):
755      for i in self.dq.coll['experiment'].items:
756        if i.label == self.adict['e']:
757          eid = i.uid
758      assert eid != None, 'Experiment %s not found' % self.adict['e']
759    print ( 'eid=%s' % eid )
760    assert ok,'Available MIPs: %s' % str(sc.mips)
761    adsCount = self.adict.get( 'count', False )
762
763    tierMax = self.adict.get( 't', 1 )
764    sc.setTierMax(  tierMax )
765    pmax = self.adict.get( 'p', 1 )
766    v0 = sc.volByMip( self.adict['m'], pmax=pmax, intersection=self.intersection, adsCount=adsCount, exptid=eid )
767    #mlg.prnt ( '%7.2fTb' % (v0*2.*1.e-12) )
768    mlg.prnt ( '%s' % v0 )
769    cc = collections.defaultdict( int )
770    for e in sc.volByE:
771      for v in sc.volByE[e][2]:
772          cc[v] += sc.volByE[e][2][v]
773    x = 0
774    for v in cc:
775      x += cc[v]
776   
777    if python2:
778      vl = sorted( cc.keys(), cmp=cmpd(cc).cmp, reverse=True )
779    else:
780      vl = sorted( cc.keys(), key=lambda x: cc[x], reverse=True )
781    if self.adict.get( 'vars', False ):
782      printLinesMax = self.adict.get( 'plm', 20 )
783      if printLinesMax > 0:
784        mx = min( [printLinesMax,len(vl)] )
785      else:
786        mx = len(vl)
787
788      for v in vl[:mx]:
789        mlg.prnt ( self.dq.inx.uid[v].label, '%7.2fTb' % (cc[v]*2.*1.e-12) )
Note: See TracBrowser for help on using the repository browser.