source: CMIP6dreq/trunk/dreqPy/overviewTabs.py @ 880

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreq/trunk/dreqPy/overviewTabs.py@880
Revision 880, 11.3 KB checked in by mjuckes, 3 years ago (diff)

Updated setup for tag 01.beta.43

Line 
1
2import collections, string, os
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    if not os.path.isdir( 'tabs03' ):
139      print ( 'WARNING.makeMMhtml: creating directory for html files: tabs03' )
140      os.mkdir( 'tabs03' )
141    oo = open( 'tabs03/%s' % fss, 'w' )
142    ttl = 'Date requested by %s from %s experiments (tier %s, priority %s)' % (m,m2,self.tiermax,self.pmax)
143    jsh = ''
144    pream = '<h1>%s</h1>\n' % ttl
145    if self.efnsfx == '_dn':
146      pream += '<p>Using the native ocean grid when no explicit preference is specified in the request.</p>\n'
147    if self.fnm == 'new':
148      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)
149    else:
150      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)
151    pream += '<ul>'
152    kc = '_%s_%s' % (m,m2)
153    for k in sorted( self.cc[kc].a.keys() ):
154      pream += '<li>%s: %s</li>\n' % (k,vfmt(self.cc[kc].a[k]*2.) )
155    pream += '</ul>'
156
157    bdy = pream + '<table>\n'
158    bdy += '<tr><th>Experiment</th><th>Volume (and link to variable lists)</th></tr>\n'
159    thisee = self.cc[m].a
160    pref = 'cmvme'
161    if  m2 in ['TOTAL']:
162      labs = sorted( [x for x in self.cc[m].a.keys() if x in self.sc.exptByLabel] )
163    elif m2 in ['Unique']:
164      labs = sorted( [x for x in self.cc['_%s' % m ].a.keys() if x in self.sc.exptByLabel] )
165      thisee = self.cc['_%s' % m].a
166      pref = 'cmvume'
167    else:
168      labs = sorted( [i.label for i in self.ee[m2] if (i.label in self.cc[m].a and i._h.label == 'experiment')] )
169
170    for ilab in labs:
171        x = thisee[ilab]*2.
172        if x > 0:
173          s = vfmt( x )
174          if self.fnm == 'new':
175            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)
176          else:
177            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)
178
179    bdy += '</table>\n'
180
181    oo.write( self.dq.pageTmpl % (ttl, jsh, '../', '../index.html', bdy ) )
182    oo.close()
183   
184  def writeMips(self,sss=False):
185
186    oo = open( 'tab01_%s_%s.texfrag' % (self.tiermax,self.pmax), 'w' )
187    mmh = []
188    mhdr = [ '\\rot{80}{%s}' % hmap0.get(m,m) for m in self.mipsp + ['TOTAL',]]
189    mhdrh = [ '<th><div><span>%s</span></div></th>' % hmap0.get(m,m) for m in self.mipsp + ['TOTAL','Unique','CALC']]
190    oo.write( string.join(['',] + mhdr, ' & ' ) + '\\\\ \n\\hline\n' )
191    mmh.append( '<table>\n<tr class="rotate">' + string.join(['<th></th>',] + mhdrh ) + '</tr>\n' )
192    htmltmpl_head = '<html><body>\n' 
193
194##
195## the "oo1" tables need a little more work to be useful
196## not supported by the "vols" entry option of this class
197##
198    doOo1 = False
199
200    for m in self.mips + ['TOTAL',]:
201      ll = [m,]
202      llh = [m,]
203      ttl = 0.
204      cct = collections.defaultdict( int )
205      xt = 0.
206      for m2 in self.mipsp + ['TOTAL','Unique']:
207       if doOo1:
208         if m2 in self.cc[m].dd:
209           oo1 = open( 'html/tt/rq-%s-expt-%s.html' % (m,m2), 'w' )
210           oo1.write( htmltmpl_head  )
211           oo1.write( '''<div class="demo">\n<div id="tabs">\n<ul>''' )
212           ks = sorted( self.cc[m].dd[m2].keys() )
213           for t in ks:
214              this1 = '<li><a href="#tabs-%s">%s</a></li>' % (t,t )
215              oo1.write( this1 )
216           oo1.write( '</ul>' )
217           for k in ks:
218               oo1.write( '<div id="tabs-%s">\n' % k )
219               oo1.write( '<table><tr>' )
220               for h in ['Frequency','Table','Label','Title','Description','UID' ]:
221                 oo1.write( '<td>%s</td>' % h )
222               for t in self.cc[m].dd[m2][k]:
223                 oo1.write( '\n</tr><tr>\n' )
224                 oo1.write( string.join( ['<td>%s</td>' % x for x in t ] ) + '\n' )
225               oo1.write( '</tr></table></div>\n' )
226   
227           oo1.write( '</body></html>' )
228           oo1.close()
229       
230       if self.cc[m].a[m2] == 0:
231          ll.append( '' )
232          llh.append( '' )
233       else:
234          try:
235            if m2 == 'TOTAL':
236              x = xt
237            else:
238              x = self.cc[m].a[m2]*2.
239              xt += x
240
241            s = vfmt( x )
242            kc = '_%s_%s' % (m,m2)
243            if m2 == 'TOTAL':
244              sm = string.join( ['%s: %s' % (k,vfmt(cct[k]*2.)) for k in sorted( cct ) ], '; ' )
245              print ( '%s, %s' % (m,cct) )
246              s1 = '<b><span title="%s">%s</span></b>' % (sm,s)
247              s = '<b>%s</b>' % s
248            else:
249               for k in self.cc[kc].a.keys():
250                cct[k] += self.cc[kc].a[k]
251            ll.append( s )
252            sm = string.join( ['%s: %s' % (k,vfmt(self.cc[kc].a[k]*2.)) for k in sorted( self.cc[kc].a.keys() ) ], '; ' )
253
254            if sss:
255              if self.fnm == 'new':
256                fss = 'expt_%s_%s_%s_%s%s.html' % (m,m2,self.tiermax, self.pmax,self.efnsfx)
257              else:
258                fss = '%s-%s_%s_%s.html' % (m,m2,self.tiermax, self.pmax)
259              llh.append( '<a title="By table: %s" href="tabs03/%s">%s</a>' % (sm,fss,s) )
260            else:
261              llh.append( '<a title="By table: %s" href="data/tabs02/%s">%s</a>' % (sm,fn,s) )
262          except:
263            print ( 'Failed to compute element: %s,%s  %s' % (m,m2, str(self.cc[m].a[m2]) ) )
264            raise
265      oo.write( string.join(ll, ' & ' ) + '\\\\ \n\\hline\n' )
266      llh.append( '<a href="data/tabs02/requestVol_%s_%s_%s.xlsx">Workings</a>' % (m,self.tiermax, self.pmax) )
267      mmh.append( '<tr>' + string.join(['<td>%s</td>' % x for x in llh] ) + '</tr>\n' )
268    mmh.append( '</table>' )
269    ttl = 'Data volume overview, upto tier %s and priority %s -- provisional' % (self.tiermax, self.pmax) 
270    if self.sc.gridPolicyDefaultNative:
271      defNat = 'For volume estimation, ocean data is assumed to be on the model native grid unless specifically requested on an interpolated grid'
272    else:
273      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)'
274    bdy = '''<h1>%(ttl)s</h1>
275<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
276<a href="https://earthsystemcog.org/projects/wip/CMIP6DataRequest" title="Data Request CoG page">Data Request home page</a>.</b></p>
277''' % {'ttl':ttl, 'defNat':defNat }
278    bdy += string.join( mmh, '\n' )
279    ooh = open( 'tab01_%s_%s%s.html' % (self.tiermax,self.pmax,self.efnsfx), 'w' )
280    ooh.write( self.dq.pageTmpl % (ttl, jsh, './', './index.html', bdy ) )
281    ooh.close()
282    oo.close()
283
284
285if __name__ == "__main__":
286  try:
287    import makeTables
288    import scope
289  except:
290    import dreqPy.scope as scope
291    import dreqPy.makeTables as makeTables
292  sc = scope.dreqQuery()
293  r = r1( sc, makeTables.tables, tiermax=1, pmax=1 )
294  r = r1( sc, makeTables.tables, tiermax=3, pmax=3 )
Note: See TracBrowser for help on using the repository browser.