source: CMIP6dreq/trunk/dreqPy/scope.py @ 570

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreq/trunk/dreqPy/scope.py@570
Revision 570, 25.1 KB checked in by mjuckes, 4 years ago (diff)

candidate

RevLine 
[394]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"""
[570]5try:
6  import dreq
7  from utilities import cmvFilter
8except:
9  import dreqPy.dreq
10  from dreqPy.utilities import cmvFilter
11
[432]12import collections, string, operator
13import sys
[388]14
[435]15python2 = True
[489]16if sys.version_info[0] == 3:
[435]17  python2 = False
18  from functools import reduce
[570]19  try: 
20    from utilP3 import mlog3
21  except:
22    from dreqPy.utilP3 import mlog3
[540]23  mlg = mlog3()
24else:
25  from utilP2 import mlog
26  mlg = mlog()
[435]27
[388]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'] )
[432]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] )
[388]46
[432]47    self.default_mcfg = nt_mcfg._make( [259200,60,64800,40,20,5,100] )
48
[400]49def filter1( a, b ):
50  if b < 0:
51    return a
52  else:
53    return min( [a,b] )
54
[570]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
[388]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]
[394]71  s = sz[inx.uid[v].stid]
[388]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):
[394]85  __doc__ = """Methods to analyse the data request, including data volume estimates"""
[540]86  def __init__(self,dq=None,tierMax=1):
[388]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)
[412]94      assert not k in self.rlu, 'Duplicate label in objectives: %s' % k
[388]95      self.rlu[k] = i.uid
96
[425]97    self.cmvFilter = cmvFilter( self )
[400]98    self.tierMax = tierMax
[487]99
[540]100    self.mips = set( [x.label for x in self.dq.coll['mip'].items ] )
[388]101    self.mipls = sorted( list( self.mips ) )
102
103    self.default_mcfg = nt_mcfg._make( [259200,60,64800,40,20,5,100] )
[487]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]
[388]107    self.szcfg()
[400]108    self.requestItemExpAll(  )
[388]109
110  def szcfg(self):
111    self.szss = {}
112    self.sz = {}
113    for i in self.dq.coll['spatialShape'].items:
114      type = 'a'
[432]115      if i.levelFlag == False:
[412]116        ds =  i.dimensions.split( '|' )
[388]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:
[540]132          mlg.prnt( 'Failed to parse dimensions %s' % i.dimensions )
[388]133          raise
134      else:
135        nz = i.levels
136
[412]137      dims = set( i.dimensions.split( '|' ) )
[388]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
[487]157    elif type(mipSel) == type(set()):
[388]158      t1 = lambda x: x in mipSel
[488]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 )
[388]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]
[487]172    elif type(objSel) == type(set()):
[488]173      t1 = lambda x: x in [self.rlu[i] for i in objSel]
[388]174
[487]175    s = set()
176    for i in self.dq.coll['objectiveLink'].items:
177      if t1(i.label):
[488]178        s.add( self.dq.inx.uid[i.oid] )
[487]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) })
[388]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 )
[488]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} }
[388]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
[540]194  def rqlByExpt( self, l1, ex, pmax=2, expFullEx=False ):
195    """rqlByExpt: return a set of request links for an experiment"""
[388]196##
197    inx = self.dq.inx
[540]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) )
[400]204##
205## rql is the set of all request links which are associated with a request item for this experiment set
206##
[488]207    l1p = set()
208    for i in l1:
[540]209      if i.preset < 0 or i.preset <= pmax:
210        if i.esid in exset:
211          l1p.add(i)
[460]212
[488]213    rql0 = set()
214    for i in l1p:
215       rql0.add(i.rlid)
[460]216
[488]217    rqlInv = set()
218    for u in rql0:
219      if inx.uid[u]._h.label == 'remarks':
220        rqlInv.add( u )
[400]221    if len(rqlInv) != 0:
[540]222      mlg.prnt ( 'WARNING.001.00002: %s invalid request links from request items ...' % len(rqlInv) )
[489]223    rql = set()
224    for u in rql0:
225       if inx.uid[u]._h.label != 'remarks':
[490]226         rql.add( u ) 
[489]227
[540]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
[570]295  def volByExpt( self, l1, ex, pmax=1, cc=None, retainRedundantRank=False, intersection=False,expFullEx=False, adsCount=False ):
[540]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 ) 
[570]337    else:
338      exi = self.dq.inx.uid[ex]
339      if exi._h.label == 'experiment':
340        exset = set( [ex,exi.egid,exi.mip] )
[540]341
342#####
[460]343    if len( rql ) == 0:
344      self.vars = set()
345      return (0,{},{} )
[388]346
347## The complete set of variables associated with these requests:
[540]348    vars = self.varsByRql( rql, pmax=pmax, intersection=intersection) 
349    tm = 3
[432]350    if tm == 0:
[489]351      s = set()
352      for i in rql:
353        s.add( inx.uid[i].refid )
354      rqvg = list( s )
[540]355    elif tm == 1:
[432]356      cc1 = collections.defaultdict( set )
357      for i in rql:
[513]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 )
[388]365
[432]366      if intersection:
367        ccv = {}
368#
369# set of request variables for each MIP
[513]370#
[432]371        for k in cc1:
372          thisc = reduce( operator.or_, [set( inx.iref_by_sect[vg].a['requestVar'] ) for vg in cc1[k] ] )
[513]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         
[489]380          s = set()
[513]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 )
[489]385          ccv[k] = s
[432]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:
[513]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         
[388]400###To obtain a set of variables associated with this collection of variable groups:
[432]401
[513]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 ] )
[432]408
[388]409### filter out cases where the request does not point to a CMOR variable.
[394]410    ##vars = {vid for vid in vars if inx.uid[vid][0] == u'CMORvar'}
[540]411      thisvars = set()
412      for vid in vars:
413         if inx.uid[vid]._h.label == u'CMORvar':
[489]414             thisvars.add(vid)
[540]415      vars = thisvars
[425]416##
417## filter by configuration option and rank
418##
419    if not retainRedundantRank:
420      len1 = len(vars)
421      cmv = self.cmvFilter.filterByChoiceRank(cmv=vars)
[388]422
[425]423      vars = cmv
424   
425    self.vars = vars
426
[388]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
[394]430      i = inx.uid[u]
[489]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 )
[388]435#
436# for each variable, calculate the maximum number of years across all the request links which reference that variable.
[400]437##
438## for each request item we have nymax, nenmax, nexmax.
439##
[388]440    nym = {}
[570]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
[388]449    for v in vars:
[489]450      s = set()
[570]451      cc2 = collections.defaultdict( set )
[489]452      for i in l1p:
[570]453##################
[540]454        if i.esid in exset and v in e[i.rlid]:
[570]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] )
[489]472      ##nym[v] = max( {self.rqiExp[i.uid][2] for i in l1p if i.esid == ex and v in e[i.rlid]} )
[540]473      if len(s) == 0:
[570]474        nym[v] = 0
[540]475      else:
[570]476        ##print 'debug2:: ',v,cc2
477        nym[v] = sum( [max( cc2[k] ) for k in cc2] )
[388]478
479    szv = {}
480    ov = []
481    for v in vars:
[394]482      szv[v] = self.sz[inx.uid[v].stid]*npy[inx.uid[v].frequency]
483      ov.append( self.dq.inx.uid[v] )
[513]484    ee = self.listIndexDual( ov, 'mipTable', 'label', acount=None, alist=None, cdict=szv, cc=cc )
[432]485    ff = {}
486    for v in vars:
[570]487      if adsCount:
488        ff[v] = 1
489      else:
490        ff[v] = self.sz[ inx.uid[v].stid ] * npy[inx.uid[v].frequency]
491        if inx.uid[v].frequency != 'monClim':
492          ff[v] = ff[v]*nym[v]
[432]493    self.ngptot = sum( [  ff[v]  for v in vars] )
494    return (self.ngptot, ee, ff )
[388]495
[540]496  def esid_to_exptList(self,esid,deref=False,full=False):
[412]497    if not esid in self.dq.inx.uid:
[540]498      mlg.prnt ( 'Attempt to dereferece invalid uid: %s' % esid )
[400]499      raise
500
501    if self.dq.inx.uid[esid]._h.label == 'experiment':
502      expts = [esid,]
503    elif self.dq.inx.uid[esid]._h.label != 'remarks':
[412]504      if esid in self.dq.inx.iref_by_sect and 'experiment' in self.dq.inx.iref_by_sect[esid].a:
[540]505        expts = list( self.dq.inx.iref_by_sect[esid].a['experiment'][:] )
[400]506      else:
507        expts = []
[540]508
509## add in groups and mips for completeness
510##
511      if full:
512        if self.dq.inx.uid[esid]._h.label == 'mip':
513          s = set()
514          for e in expts:
515            if self.dq.inx.uid[e]._h.label != 'experiment':
516              mlg.prnt ( 'ERROR: %s, %s, %s ' % (esid,e, self.dq.inx.uid[e].title ) )
517            s.add( self.dq.inx.uid[e].egid )
518          for i in s:
519            expts.append( i )
520        expts.append( esid )
[400]521    else:
[460]522      ##print ( 'WARNING: request link not associated with valid experiment group' )
523      ##raise
524      return None
[400]525
[540]526
[400]527    if self.tierMax > 0:
[540]528      expts1 = []
529      for i in expts:
530        if self.dq.inx.uid[i]._h.label == 'experiment':
[558]531          if self.dq.inx.uid[i].tier[0] <= self.tierMax:
[540]532            expts1.append( i )
533        elif self.dq.inx.uid[i]._h.label == 'exptgroup':
534          if self.dq.inx.uid[i].tierMin <= self.tierMax:
535            expts1.append( i )
536        else:
537            expts1.append( i )
538    else:
539      expts1 = expts
[400]540
541    if deref:
[540]542      return [self.dq.inx.uid[e] for e in expts1]
[400]543    else:
[540]544      return expts1
[400]545 
546##
547## need to call this on load
548## then use instead of i.ny etc below
549##
550  def requestItemExpAll( self ):
551    self.rqiExp = {}
552    for rqi in self.dq.coll['requestItem'].items:
[570]553      a,b,c,d = self.requestItemExp( rqi )
[460]554      if a != None:
[570]555        self.rqiExp[rqi.uid] = (a,b,c,d)
[400]556
557  def requestItemExp( self, rqi ):
558    assert rqi._h.label == "requestItem", 'Argument to requestItemExp must be a requestItem'
559    u = rqi.esid
560    if self.dq.inx.uid[u]._h.label == 'experiment':
561      expts = [u,]
562    elif self.dq.inx.uid[u]._h.label != 'remarks':
[412]563      if u in self.dq.inx.iref_by_sect and 'experiment' in self.dq.inx.iref_by_sect[u].a:
[400]564        expts = self.dq.inx.iref_by_sect[u].a['experiment']
565      else:
566        expts = []
567    else:
[460]568      # print ( 'WARNING: request link not associated with valid experiment group'  )
569      ##rqi.__info__()
570      ##raise
[570]571      return (None, None, None, None)
[400]572
573    if self.tierMax > 0:
[558]574      expts = [i for i in expts if self.dq.inx.uid[i].tier[0] <= self.tierMax]
[400]575
[570]576    self.multiTierOnly = False
577    if self.multiTierOnly:
578      expts = [i for i in expts if len(self.dq.inx.uid[i].tier) > 1]
579      print ('Len expts: %s' % len(expts) )
580
[400]581    if len(expts) > 0:
582      e = [self.dq.inx.uid[i] for i in expts]
[540]583      for i in e:
584        if i._h.label != 'experiment':
585          mlg.prnt ( 'ERROR: %s, %s, %s ' % ( u,i._h.label, i.label, i.title ) )
[570]586      ##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]
587      dat2 = {}
588      for i in e:
589        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) )
590      ### number of
591      nytot = sum( [dat2[x][-2]*dat2[x][-3] for x in dat2 ] )
592      netot = sum( [dat2[x][-1] for x in dat2 ] )
593      ##print 'debug1:: ',dat, nytot, netot
[400]594    else:
[570]595      dat2 = {}
[400]596      nytot = 0
[570]597      netot = 0
[400]598   
[570]599    return (expts, dat2, nytot, netot )
[400]600
601  def setTierMax( self, tierMax ):
602    """Set the maxium tier and recompute request sizes"""
603    if tierMax != self.tierMax:
604      self.tierMax = tierMax
605      self.requestItemExpAll(  )
606
[388]607  def summaryByMip( self, pmax=1 ):
608    bytesPerFloat = 2.
609    for m in self.mipls:
610      v = self.volByMip( m, pmax=pmax )
[540]611      mlg.prnt ( '%12.12s: %6.2fTb' % (m,v*bytesPerFloat*1.e-12) )
[388]612
[540]613  def rqiByMip( self, mip):
[388]614
[489]615    if type(mip) in [type( '' ),type( u'') ]:
[388]616      if mip not in self.mips:
[540]617        mlg.prnt ( self.mips )
618        raise baseException( 'rqiByMip: Name of mip not recognised: %s' % mip )
[388]619      l1 = [i for i in  self.dq.coll['requestItem'].items if i.mip == mip]
620    elif type(mip) == type( set()):
621      nf = [ m for m in mip if m not in self.mips]
622      if len(nf) > 0:
[540]623        raise baseException( 'rqiByMip: Name of mip(s) not recognised: %s' % str(nf) )
[388]624      l1 = [i for i in  self.dq.coll['requestItem'].items if i.mip in mip]
625    else:
[540]626      raise baseException( 'rqiByMip: "mip" (1st explicit argument) should be type string or set: %s -- %s' % (mip, type(mip))   )
627    return l1
[388]628     
[570]629  def volByMip( self, mip, pmax=2, retainRedundantRank=False, intersection=False, adsCount=False, exptid=None):
[540]630
631    l1 = self.rqiByMip( mip )
632     
[388]633    #### The set of experiments/experiment groups:
[570]634    if exptid == None:
635      exps = self.mips
636    else:
637      exps = set( [exptid,] )
638      ##print exptid, exps
[388]639    self.volByE = {}
640    vtot = 0
641    cc = collections.defaultdict( col_count )
[425]642    self.allVars = set()
[388]643    for e in exps:
[540]644      expts = self.esid_to_exptList(e,deref=True,full=False)
[460]645      if expts != None:
[570]646        self.volByE[e] = self.volByExpt( l1, e, pmax=pmax, cc=cc, retainRedundantRank=retainRedundantRank, intersection=intersection, adsCount=adsCount )
[460]647        vtot += self.volByE[e][0]
648        self.allVars = self.allVars.union( self.vars )
[388]649    self.indexedVol = cc
650
651    return vtot
652
653  def listIndexDual(self, ll, a1, a2, acount=None, alist=None, cdict=None, cc=None ):
654    do_count = acount != None
655    do_list = alist != None
656    assert not (do_count and do_list), 'It is an error to request both list and count'
657    if not (do_count or do_list):
658      acount = '__number__'
659      do_count = True
660
661    if cc == None:
662      if do_count:
663        cc = collections.defaultdict( col_count )
664      elif do_list:
665        cc = collections.defaultdict( col_list )
666
667    if do_count:
668      for l in ll:
669        if cdict != None:
670          v = cdict[l.uid]
671        elif acount == '__number__':
672          v = 1
673        else:
674          v = l.__dict__[acount]
675
676        cc[ l.__dict__[a1] ].a[ l.__dict__[a2] ] += v
677    elif do_list:
678      for l in ll:
679        if cdict != None:
680          v = cdict[l.uid]
681        elif alist == '__item__':
682          v = l
683        else:
684          v = l.__dict__[alist]
685        cc[ l.__dict__[a1] ].a[ l.__dict__[a2] ].append( v )
686
687    od = {}
688    for k in cc.keys():
689      d2 = {}
690      for k2 in cc[k].a.keys():
691        d2[k2] = cc[k].a[k2]
692      od[k] = d2
693    return od
[432]694
695class dreqUI(object):
696  """Data Request Command line.
697-------------------------
[435]698      -v : print version and exit;
699      --unitTest : run some simple tests;
[432]700      -m <mip>:  MIP of list of MIPs (comma separated);
701      -h :       help: print help text;
[570]702      -e <expt>: experiment;
[432]703      -t <tier> maxmum tier;
704      -p <priority>  maximum priority;
705      --printLinesMax <n>: Maximum number of lines to be printed
706      --printVars  : If present, a summary of the variables fitting the selection options will be printed
[513]707      --intersection : Analyse the intersection of requests rather than union.
[432]708"""
709  def __init__(self,args):
710    self.adict = {}
[570]711    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)} 
[432]712    aa = args[:]
713    while len(aa) > 0:
714      a = aa.pop(0)
715      if a in self.knownargs:
716        b = self.knownargs[a][0]
717        if self.knownargs[a][1]:
718          v = aa.pop(0)
719          self.adict[b] = v
720        else:
721          self.adict[b] = True
722
723    if 'm' in self.adict:
724      self.adict['m'] = set(self.adict['m'].split(',') )
725
[489]726    integerArgs = set( ['p','t','plm'] )
[432]727    for i in integerArgs.intersection( self.adict ):
728      self.adict[i] = int( self.adict[i] )
729
[513]730    self.intersection = self.adict.get( 'intersection', False )
731
[432]732  def run(self, dq=None):
733    if 'h' in self.adict:
[540]734      mlg.prnt ( self.__doc__ )
[432]735      return
736
737    if not 'm' in self.adict:
[540]738      mlg.prnt ( 'Current version requires -m argument'  )
739      mlg.prnt ( self.__doc__ )
[432]740      sys.exit(0)
741
742    if dq == None:
743      self.dq = dreq.loadDreq()
744    else:
745      self.dq = None
746
747    sc = dreqQuery( dq=self.dq )
748
749    ok = True
750    for i in self.adict['m']:
751        if i not in sc.mips:
752          ok = False
[570]753          mlg.prnt ( 'NOT FOUND: %s' % i )
754
755    eid = None
756    if self.adict.has_key('e'):
757      for i in self.dq.coll['experiment'].items:
758        if i.label == self.adict['e']:
759          eid = i.uid
760      assert eid != None, 'Experiment %s not found' % self.adict['e']
761    print ( 'eid=%s' % eid )
[432]762    assert ok,'Available MIPs: %s' % str(sc.mips)
[570]763    adsCount = self.adict.get( 'count', False )
[432]764
[570]765    tierMax = self.adict.get( 't', 1 )
[432]766    sc.setTierMax(  tierMax )
[570]767    pmax = self.adict.get( 'p', 1 )
768    v0 = sc.volByMip( self.adict['m'], pmax=pmax, intersection=self.intersection, adsCount=adsCount, exptid=eid )
769    #mlg.prnt ( '%7.2fTb' % (v0*2.*1.e-12) )
770    mlg.prnt ( '%s' % v0 )
[432]771    cc = collections.defaultdict( int )
772    for e in sc.volByE:
773      for v in sc.volByE[e][2]:
774          cc[v] += sc.volByE[e][2][v]
775    x = 0
776    for v in cc:
777      x += cc[v]
778   
[435]779    if python2:
780      vl = sorted( cc.keys(), cmp=cmpd(cc).cmp, reverse=True )
781    else:
782      vl = sorted( cc.keys(), key=lambda x: cc[x], reverse=True )
[432]783    if self.adict.get( 'vars', False ):
784      printLinesMax = self.adict.get( 'plm', 20 )
785      if printLinesMax > 0:
786        mx = min( [printLinesMax,len(vl)] )
787      else:
788        mx = len(vl)
789
790      for v in vl[:mx]:
[540]791        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.