source: CMIP6dreqbuild/trunk/src/framework/dreqPy/overviewTabs.py @ 861

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

candidate

Line 
1
2import collections, string
3import xlsxwriter
4
5try:
6  import dreq
7except:
8  import dreqPy.dreq as dreq
9
10jsh='''
11<link type="text/css" href="/css/dreq.css" rel="Stylesheet" />
12'''
13
14def vfmt( x ):
15            if x < 1.e9:
16              s = '%sM' % int( x*1.e-6 )
17            elif x < 1.e12:
18              s = '%sG' % int( x*1.e-9 )
19            elif x < 1.e13:
20              s = '%3.1fT' % ( x*1.e-12 )
21            elif x < 1.e15:
22              s = '%3iT' % int( x*1.e-12 )
23            elif x < 1.e18:
24              s = '%3iP' % int( x*1.e-15 )
25            else:
26              s = '{:,.2f}'.format( x*1.e-9 ) 
27            return s
28
29class c1(object):
30  def __init__(self):
31    self.a = collections.defaultdict( int )
32
33class c2(object):
34  def __init__(self):
35    self.a = collections.defaultdict( list )
36
37hmap0 = {'CMIP6':'Historical'}
38class r1(object):
39  def __init__(self,sc,mt_tables,tiermax=1,pmax=1,only=False,vols=None,fnm='new'):
40    self.mt_tables = mt_tables
41
42    self.fnm = fnm
43    assert vols == None or type(vols) == type( () ), 'vols argument must be none or tuple of length 2: %s' % type(vols)
44    self.dq = sc.dq
45    self.mips = ['CMIP','AerChemMIP', 'C4MIP', 'CFMIP', 'DAMIP', 'DCPP', 'FAFMIP', 'GeoMIP', 'GMMIP', 'HighResMIP', 'ISMIP6', 'LS3MIP', 'LUMIP', 'OMIP', 'PMIP', 'RFMIP', 'ScenarioMIP', 'VolMIP', 'CORDEX', 'DynVar', 'SIMIP', 'VIACSAB']
46    self.mipsp = self.mips[:-4]
47    self.sc = sc
48    self.pmax=pmax
49    self.efnsfx = ''
50    if sc.gridPolicyDefaultNative:
51        self.efnsfx = '_dn'
52    self.cc = collections.defaultdict( c1 )
53    self.ee = {}
54    for m2 in self.mipsp + ['TOTAL',]:
55        xx = [i for i in self.dq.coll['experiment'].items if i.mip == m2]
56        self.ee[m2] = xx
57
58    if vols != None:
59      assert len(vols) == 4, 'vols must be a tuple of length 4 (containing dictionaries ...): %s' % len(vols)
60      self.tiermax = sc.tierMax
61      vmm, vme, vmmt, vue = vols
62      for m in vmm:
63        for m2 in vmm[m]:
64          self.cc[m].a[m2] = vmm[m][m2]
65          if m2 != 'Unique':
66            self.cc[m].a['TOTAL'] += vmm[m][m2]
67
68      for m in vme:
69        for e in vme[m]:
70          i = sc.dq.inx.uid[e]
71          if i._h.label == 'experiment':
72            self.cc[m].a[i.label] = vme[m][e]
73
74      for m in vue:
75        for e in vue[m]:
76          i = sc.dq.inx.uid[e]
77          if i._h.label == 'experiment':
78            self.cc['_%s' % m].a[i.label] = vue[m][e]
79
80      for m in vmmt:
81        for m2,t in vmmt[m]: 
82           self.cc['_%s_%s' % (m,m2)].a[t] = vmmt[m][(m2,t)]
83           if m2 != 'Unique':
84             self.cc['_%s_%s' % (m,'TOTAL')].a[t] += vmmt[m][(m2,t)]
85           self.makeMMhtml(m,m2)
86        self.makeMMhtml(m,'TOTAL')
87
88      self.writeMips(True)
89      return
90    self.mode = 'def'
91
92    self.tiermax=tiermax
93    sc.setTierMax( tiermax )
94    tabs = self.mt_tables( sc )
95
96    mipsToDo = self.mips + ['TOTAL',]
97    assert 'SolarMIP' not in mipsToDo, 'SolarMIP error: %s ' % str(mipsToDo)
98    assert 'SolarMIP' not in self.mipsp, 'SolarMIP error: %s ' % str(self.mipsp)
99    if only != False:
100      mipsToDo = [only,]
101    for m in mipsToDo:
102      if m == 'TOTAL':
103        l1 = sc.rqiByMip( set( self.mips ) )
104      else:
105        l1 = sc.rqiByMip( m )
106
107      self.cc[m].dd = {}
108      tabs.accReset()
109##
110## need to check this option, and add a template for a view summarising the experiments for each mip-mip combinations
111##
112## sss=True not yet tested
113##
114      for m2 in self.mipsp + ['TOTAL',]:
115        sss = True
116        if sss:
117          for i in xx:
118            tabs.doTable(m,l1,i.uid,pmax,self.cc,acc=False)
119          tabs.doTable(m,l1,m2,pmax,self.cc)
120          if only == False:
121            self.makeMMhtml(m,m2)
122        else:
123          tabs.doTable(m,l1,m2,pmax,self.cc)
124
125    if only == False:
126      self.writeMips(sss)
127
128  def makeMMhtml(self,m,m2):
129    """Make a html page for data requested by MIP 'm' from MIP 'm2' experiments"""
130    if self.fnm == 'new':
131      fss = 'expt_%s_%s_%s_%s%s.html' % (m,m2,self.tiermax, self.pmax,self.efnsfx)
132    else:
133      fss = '%s-%s_%s_%s.html' % (m,m2,self.tiermax, self.pmax)
134    kc = '_%s_%s' % (m,m2)
135    print ('INFO.mmhtml.00001: %s, %s' % (kc,len( self.cc[kc].a.keys() ) ) )
136    if len( self.cc[kc].a.keys() ) == 0:
137      return
138    oo = open( 'tabs03/%s' % fss, 'w' )
139    ttl = 'Date requested by %s from %s experiments (tier %s, priority %s)' % (m,m2,self.tiermax,self.pmax)
140    jsh = ''
141    pream = '<h1>%s</h1>\n' % ttl
142    if self.efnsfx == '_dn':
143      pream += '<p>Using the native ocean grid when no explicit preference is specified in the request.</p>\n'
144    if self.fnm == 'new':
145      pream += '<p>All variables in one <a href="../data/tabs02/cmvmm_%s_%s_%s_%s%s.xlsx">Excel file</a></p>\n' % (m,m2,self.tiermax, self.pmax,self.efnsfx)
146    else:
147      pream += '<p>All variables in one <a href="../data/tabs02/%s-%s_%s_%s.xlsx">Excel file</a></p>\n' % (m,m2,self.tiermax, self.pmax)
148    pream += '<ul>'
149    kc = '_%s_%s' % (m,m2)
150    for k in sorted( self.cc[kc].a.keys() ):
151      pream += '<li>%s: %s</li>\n' % (k,vfmt(self.cc[kc].a[k]*2.) )
152    pream += '</ul>'
153
154    bdy = pream + '<table>\n'
155    bdy += '<tr><th>Experiment</th><th>Volume (and link to variable lists)</th></tr>\n'
156    thisee = self.cc[m].a
157    pref = 'cmvme'
158    if  m2 in ['TOTAL']:
159      labs = sorted( [x for x in self.cc[m].a.keys() if x in self.sc.exptByLabel] )
160    elif m2 in ['Unique']:
161      labs = sorted( [x for x in self.cc['_%s' % m ].a.keys() if x in self.sc.exptByLabel] )
162      thisee = self.cc['_%s' % m].a
163      pref = 'cmvume'
164    else:
165      labs = sorted( [i.label for i in self.ee[m2] if (i.label in self.cc[m].a and i._h.label == 'experiment')] )
166
167    for ilab in labs:
168        x = thisee[ilab]*2.
169        if x > 0:
170          s = vfmt( x )
171          if self.fnm == 'new':
172            bdy += '<tr><td>%s</td><td><a href="../data/tabs02/%s_%s_%s_%s_%s%s.xlsx">%s</a></td></tr>\n' % (ilab,pref,m,ilab,self.tiermax, self.pmax,self.efnsfx,s)
173          else:
174            bdy += '<tr><td>%s</td><td><a href="../data/tabs02/%s-%s_%s_%s.xlsx">%s</a></td></tr>\n' % (ilab,m,ilab,self.tiermax, self.pmax,s)
175
176    bdy += '</table>\n'
177
178    oo.write( self.dq.pageTmpl % (ttl, jsh, '../', '../index.html', bdy ) )
179    oo.close()
180   
181  def writeMips(self,sss=False):
182
183    oo = open( 'tab01_%s_%s.texfrag' % (self.tiermax,self.pmax), 'w' )
184    mmh = []
185    mhdr = [ '\\rot{80}{%s}' % hmap0.get(m,m) for m in self.mipsp + ['TOTAL',]]
186    mhdrh = [ '<th><div><span>%s</span></div></th>' % hmap0.get(m,m) for m in self.mipsp + ['TOTAL','Unique','CALC']]
187    oo.write( string.join(['',] + mhdr, ' & ' ) + '\\\\ \n\\hline\n' )
188    mmh.append( '<table>\n<tr class="rotate">' + string.join(['<th></th>',] + mhdrh ) + '</tr>\n' )
189    htmltmpl_head = '<html><body>\n' 
190
191##
192## the "oo1" tables need a little more work to be useful
193## not supported by the "vols" entry option of this class
194##
195    doOo1 = False
196
197    for m in self.mips + ['TOTAL',]:
198      ll = [m,]
199      llh = [m,]
200      ttl = 0.
201      cct = collections.defaultdict( int )
202      xt = 0.
203      for m2 in self.mipsp + ['TOTAL','Unique']:
204       if doOo1:
205         if m2 in self.cc[m].dd:
206           oo1 = open( 'html/tt/rq-%s-expt-%s.html' % (m,m2), 'w' )
207           oo1.write( htmltmpl_head  )
208           oo1.write( '''<div class="demo">\n<div id="tabs">\n<ul>''' )
209           ks = sorted( self.cc[m].dd[m2].keys() )
210           for t in ks:
211              this1 = '<li><a href="#tabs-%s">%s</a></li>' % (t,t )
212              oo1.write( this1 )
213           oo1.write( '</ul>' )
214           for k in ks:
215               oo1.write( '<div id="tabs-%s">\n' % k )
216               oo1.write( '<table><tr>' )
217               for h in ['Frequency','Table','Label','Title','Description','UID' ]:
218                 oo1.write( '<td>%s</td>' % h )
219               for t in self.cc[m].dd[m2][k]:
220                 oo1.write( '\n</tr><tr>\n' )
221                 oo1.write( string.join( ['<td>%s</td>' % x for x in t ] ) + '\n' )
222               oo1.write( '</tr></table></div>\n' )
223   
224           oo1.write( '</body></html>' )
225           oo1.close()
226       
227       if self.cc[m].a[m2] == 0:
228          ll.append( '' )
229          llh.append( '' )
230       else:
231          try:
232            if m2 == 'TOTAL':
233              x = xt
234            else:
235              x = self.cc[m].a[m2]*2.
236              xt += x
237
238            s = vfmt( x )
239            kc = '_%s_%s' % (m,m2)
240            if m2 == 'TOTAL':
241              sm = string.join( ['%s: %s' % (k,vfmt(cct[k]*2.)) for k in sorted( cct ) ], '; ' )
242              print ( '%s, %s' % (m,cct) )
243              s1 = '<b><span title="%s">%s</span></b>' % (sm,s)
244              s = '<b>%s</b>' % s
245            else:
246               for k in self.cc[kc].a.keys():
247                cct[k] += self.cc[kc].a[k]
248            ll.append( s )
249            sm = string.join( ['%s: %s' % (k,vfmt(self.cc[kc].a[k]*2.)) for k in sorted( self.cc[kc].a.keys() ) ], '; ' )
250
251            if sss:
252              if self.fnm == 'new':
253                fss = 'expt_%s_%s_%s_%s%s.html' % (m,m2,self.tiermax, self.pmax,self.efnsfx)
254              else:
255                fss = '%s-%s_%s_%s.html' % (m,m2,self.tiermax, self.pmax)
256              llh.append( '<a title="By table: %s" href="tabs03/%s">%s</a>' % (sm,fss,s) )
257            else:
258              llh.append( '<a title="By table: %s" href="data/tabs02/%s">%s</a>' % (sm,fn,s) )
259          except:
260            print ( 'Failed to compute element: %s,%s  %s' % (m,m2, str(self.cc[m].a[m2]) ) )
261            raise
262      oo.write( string.join(ll, ' & ' ) + '\\\\ \n\\hline\n' )
263      llh.append( '<a href="data/tabs02/requestVol_%s_%s_%s.xlsx">Workings</a>' % (m,self.tiermax, self.pmax) )
264      mmh.append( '<tr>' + string.join(['<td>%s</td>' % x for x in llh] ) + '</tr>\n' )
265    mmh.append( '</table>' )
266    ttl = 'Data volume overview, upto tier %s and priority %s -- provisional' % (self.tiermax, self.pmax) 
267    if self.sc.gridPolicyDefaultNative:
268      defNat = 'For volume estimation, ocean data is assumed to be on the model native grid unless specifically requested on an interpolated grid'
269    else:
270      defNat = 'For volume estimation, ocean data is assumed to be on a regular 1-degree grid unless specifically requested on another grid (e.g. the native model grid)'
271    bdy = '''<h1>%(ttl)s</h1>
272<p>Data volumes are estimated for nominal model with 1 degree resolution and 40 levels in the atmosphere and 0.5 degrees with 60 levels in the ocean.  The "Requesting MIP" (rows) is the MIP specifying the data required to meet their scientific objectives. The "designing MIP" (columns) is the MIP specifying the experimental design. %(defNat)s <b>The figures below represent work in progress: there are still omissions and flaws, more details are on the
273<a href="https://earthsystemcog.org/projects/wip/CMIP6DataRequest" title="Data Request CoG page">Data Request home page</a>.</b></p>
274''' % {'ttl':ttl, 'defNat':defNat }
275    bdy += string.join( mmh, '\n' )
276    ooh = open( 'tab01_%s_%s%s.html' % (self.tiermax,self.pmax,self.efnsfx), 'w' )
277    ooh.write( self.dq.pageTmpl % (ttl, jsh, './', './index.html', bdy ) )
278    ooh.close()
279    oo.close()
280
281
282if __name__ == "__main__":
283  try:
284    import makeTables
285    import scope
286  except:
287    import dreqPy.scope as scope
288    import dreqPy.makeTables as makeTables
289  sc = scope.dreqQuery()
290  r = r1( sc, makeTables.tables, tiermax=1, pmax=1 )
291  r = r1( sc, makeTables.tables, tiermax=3, pmax=3 )
Note: See TracBrowser for help on using the repository browser.