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

Subversion URL: http://proj.badc.rl.ac.uk/svn/exarch/CMIP6dreq/trunk/dreqPy/overviewTabs.py@849
Revision 849, 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 scope
8  import makeTables
9except:
10  import dreqPy.dreq as dreq
11  import dreqPy.scope as scope
12  import dreqPy.makeTables as makeTables
13
14jsh='''
15<link type="text/css" href="/css/dreq.css" rel="Stylesheet" />
16'''
17
18def vfmt( x ):
19            if x < 1.e9:
20              s = '%sM' % int( x*1.e-6 )
21            elif x < 1.e12:
22              s = '%sG' % int( x*1.e-9 )
23            elif x < 1.e13:
24              s = '%3.1fT' % ( x*1.e-12 )
25            elif x < 1.e15:
26              s = '%3iT' % int( x*1.e-12 )
27            elif x < 1.e18:
28              s = '%3iP' % int( x*1.e-15 )
29            else:
30              s = '{:,.2f}'.format( x*1.e-9 ) 
31            return s
32
33class c1(object):
34  def __init__(self):
35    self.a = collections.defaultdict( int )
36
37class c2(object):
38  def __init__(self):
39    self.a = collections.defaultdict( list )
40
41hmap0 = {'CMIP6':'Historical'}
42class r1(object):
43  def __init__(self,sc,tiermax=1,pmax=1,only=False,vols=None,fnm='new'):
44
45    self.fnm = fnm
46    assert vols == None or type(vols) == type( () ), 'vols argument must be none or tuple of length 2: %s' % type(vols)
47    self.dq = sc.dq
48    self.mips = ['AerChemMIP', 'C4MIP', 'CFMIP', 'DAMIP', 'DCPP', 'FAFMIP', 'GeoMIP', 'GMMIP', 'HighResMIP', 'ISMIP6', 'LS3MIP', 'LUMIP', 'OMIP', 'PMIP', 'RFMIP', 'ScenarioMIP', 'VolMIP', 'CORDEX', 'DynVar', 'SIMIP', 'VIACSAB']
49    self.mipsp = ['DECK','CMIP6',] + self.mips[:-4]
50    self.sc = sc
51    self.pmax=pmax
52    self.efnsfx = ''
53    if sc.gridPolicyDefaultNative:
54        self.efnsfx = '_dn'
55    self.cc = collections.defaultdict( c1 )
56    self.ee = {}
57    for m2 in self.mipsp + ['TOTAL',]:
58        xx = [i for i in self.dq.coll['experiment'].items if i.mip == m2]
59        self.ee[m2] = xx
60
61    if vols != None:
62      assert len(vols) == 4, 'vols must be a tuple of length 4 (containing dictionaries ...): %s' % len(vols)
63      self.tiermax = sc.tierMax
64      vmm, vme, vmmt, vue = vols
65      for m in vmm:
66        for m2 in vmm[m]:
67          self.cc[m].a[m2] = vmm[m][m2]
68          if m2 != 'Unique':
69            self.cc[m].a['TOTAL'] += vmm[m][m2]
70
71      for m in vme:
72        for e in vme[m]:
73          i = sc.dq.inx.uid[e]
74          if i._h.label == 'experiment':
75            self.cc[m].a[i.label] = vme[m][e]
76
77      for m in vue:
78        for e in vue[m]:
79          i = sc.dq.inx.uid[e]
80          if i._h.label == 'experiment':
81            self.cc['_%s' % m].a[i.label] = vue[m][e]
82
83      for m in vmmt:
84        for m2,t in vmmt[m]: 
85           self.cc['_%s_%s' % (m,m2)].a[t] = vmmt[m][(m2,t)]
86           if m2 != 'Unique':
87             self.cc['_%s_%s' % (m,'TOTAL')].a[t] += vmmt[m][(m2,t)]
88           self.makeMMhtml(m,m2)
89        self.makeMMhtml(m,'TOTAL')
90
91      self.writeMips(True)
92      return
93    self.mode = 'def'
94
95    self.tiermax=tiermax
96    sc.setTierMax( tiermax )
97    tabs = makeTables.tables( sc )
98
99    mipsToDo = self.mips + ['TOTAL',]
100    assert 'SolarMIP' not in mipsToDo, 'SolarMIP error: %s ' % str(mipsToDo)
101    assert 'SolarMIP' not in self.mipsp, 'SolarMIP error: %s ' % str(self.mipsp)
102    if only != False:
103      mipsToDo = [only,]
104    for m in mipsToDo:
105      if m == 'TOTAL':
106        l1 = sc.rqiByMip( set( self.mips ) )
107      else:
108        l1 = sc.rqiByMip( m )
109
110      self.cc[m].dd = {}
111      tabs.accReset()
112##
113## need to check this option, and add a template for a view summarising the experiments for each mip-mip combinations
114##
115## sss=True not yet tested
116##
117      for m2 in self.mipsp + ['TOTAL',]:
118        sss = True
119        if sss:
120          for i in xx:
121            tabs.doTable(m,l1,i.uid,pmax,self.cc,acc=False)
122          tabs.doTable(m,l1,m2,pmax,self.cc)
123          if only == False:
124            self.makeMMhtml(m,m2)
125        else:
126          tabs.doTable(m,l1,m2,pmax,self.cc)
127
128    if only == False:
129      self.writeMips(sss)
130
131  def makeMMhtml(self,m,m2):
132    """Make a html page for data requested by MIP 'm' from MIP 'm2' experiments"""
133    if self.fnm == 'new':
134      fss = 'expt_%s_%s_%s_%s%s.html' % (m,m2,self.tiermax, self.pmax,self.efnsfx)
135    else:
136      fss = '%s-%s_%s_%s.html' % (m,m2,self.tiermax, self.pmax)
137    kc = '_%s_%s' % (m,m2)
138    print ('INFO.mmhtml.00001: %s, %s' % (kc,len( self.cc[kc].a.keys() ) ) )
139    if len( self.cc[kc].a.keys() ) == 0:
140      return
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 scope
288  except:
289    import dreqPy.scope as scope
290  sc = scope.dreqQuery()
291  r = r1( sc, tiermax=1, pmax=1 )
292  r = r1( sc, tiermax=3, pmax=3 )
Note: See TracBrowser for help on using the repository browser.