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

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

further import updates

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