Commit bd0a89b5138be117f37f0883b0334f4e98b2cf5e

Authored by Jürgen Knödlseder
2 parents 1c891066 68576976

Merge branch '3592-csfootprint' into 3592-daemon

Showing 1 changed file with 98 additions and 7 deletions
cscripts/csfootprint.py
@@ -45,6 +45,9 @@ class csfootprint(ctools.cscript): @@ -45,6 +45,9 @@ class csfootprint(ctools.cscript):
45 # Initialise application by calling the base class constructor 45 # Initialise application by calling the base class constructor
46 self._init_cscript(self.__class__.__name__, ctools.__version__, argv) 46 self._init_cscript(self.__class__.__name__, ctools.__version__, argv)
47 47
  48 + # Initialise members
  49 + self._statistics = {}
  50 +
48 # Return 51 # Return
49 return 52 return
50 53
@@ -59,7 +62,8 @@ class csfootprint(ctools.cscript): @@ -59,7 +62,8 @@ class csfootprint(ctools.cscript):
59 Pickled instance 62 Pickled instance
60 """ 63 """
61 # Set pickled dictionary 64 # Set pickled dictionary
62 - state = {'base' : ctools.cscript.__getstate__(self)} 65 + state = {'base' : ctools.cscript.__getstate__(self),
  66 + 'statistics' : self._statistics}
63 67
64 # Return pickled dictionary 68 # Return pickled dictionary
65 return state 69 return state
@@ -75,6 +79,7 @@ class csfootprint(ctools.cscript): @@ -75,6 +79,7 @@ class csfootprint(ctools.cscript):
75 """ 79 """
76 # Set state 80 # Set state
77 ctools.cscript.__setstate__(self, state['base']) 81 ctools.cscript.__setstate__(self, state['base'])
  82 + self._statistics = state['statistics']
78 83
79 # Return 84 # Return
80 return 85 return
@@ -494,6 +499,89 @@ class csfootprint(ctools.cscript): @@ -494,6 +499,89 @@ class csfootprint(ctools.cscript):
494 # Return 499 # Return
495 return 500 return
496 501
  502 + # Create figure
  503 + def _create_figure(self, outfile, statistics):
  504 + """
  505 + Create figure
  506 +
  507 + Parameters
  508 + ----------
  509 + outfile : str
  510 + Figure file name
  511 + statistics : dict
  512 + Statistics dictionary
  513 + """
  514 + # Optionally use matplotlib to create a figure
  515 + try:
  516 +
  517 + # Import matplotlib
  518 + import matplotlib.pyplot as plt
  519 + import matplotlib.gridspec as gridspec
  520 +
  521 + # Create figure
  522 + fig = plt.figure(figsize=(15.0,7.8))
  523 +
  524 + # Create title and subtitle
  525 + title = 'ctools carbon footprint report'
  526 + subtitle = r'Dates: %s - %s' % \
  527 + (statistics['use_start'], statistics['use_stop'])
  528 + fig.suptitle(title, fontsize=16)
  529 + fig.text(0.5, 0.93, subtitle, fontsize=12, ha='center')
  530 +
  531 + # Set plot margins
  532 + fig.subplots_adjust(left=0.07, bottom=0.07, right=0.97, top=0.88, wspace=0.3, hspace=0.35)
  533 +
  534 + # Divide figure
  535 + gs1 = gridspec.GridSpec(3,3)
  536 + ax1 = fig.add_subplot(gs1[0,0:2])
  537 + ax2 = fig.add_subplot(gs1[0,2])
  538 +
  539 + # Plot daily footprint
  540 + self._plot_daily(ax1, statistics)
  541 +
  542 + #plt.show()
  543 +
  544 + # Save figure
  545 + fig.savefig(outfile, dpi=300)
  546 +
  547 + # Log file creation
  548 + self._log_value(gammalib.NORMAL, 'Graphics file', outfile)
  549 +
  550 + # Catch exceptions
  551 + except (ImportError, RuntimeError):
  552 +
  553 + # Log file creation
  554 + self._log_value(gammalib.NORMAL, 'Graphics file', 'matplotlib not available')
  555 +
  556 + # Return
  557 + return
  558 +
  559 + # Plot daily footprint
  560 + def _plot_daily(self, ax, statistics):
  561 + """
  562 + Plot daily footprint
  563 +
  564 + Parameters
  565 + ----------
  566 + ax : pyplot
  567 + Plotting frame
  568 + statistics : dict
  569 + Statistics dictionary
  570 + """
  571 + # Create bar data
  572 + days = [i for i, _ in enumerate(statistics['daily'])]
  573 + data = [entry['gCO2e'] for entry in statistics['daily']]
  574 +
  575 + # Plot bar data
  576 + ax.bar(days, data, 1.0, bottom=0.0, color='red')
  577 +
  578 + # Set labels
  579 + ax.set_title('Footprint')
  580 + ax.set_xlabel('Days since %s' % statistics['use_start'][0:10])
  581 + ax.set_ylabel(r'g CO$_2$e')
  582 +
  583 + # Return
  584 + return
497 585
498 # Public methods 586 # Public methods
499 def process(self): 587 def process(self):
@@ -507,12 +595,12 @@ class csfootprint(ctools.cscript): @@ -507,12 +595,12 @@ class csfootprint(ctools.cscript):
507 self._log_header1(gammalib.TERSE, 'Load statistics data') 595 self._log_header1(gammalib.TERSE, 'Load statistics data')
508 596
509 # Load statistics 597 # Load statistics
510 - statistics = self._load_statistics() 598 + self._statistics = self._load_statistics()
511 599
512 # Log statistics 600 # Log statistics
513 - self._global_statistics(statistics)  
514 - self._daily_statistics(statistics)  
515 - self._tools_statistics(statistics) 601 + self._global_statistics(self._statistics)
  602 + self._daily_statistics(self._statistics)
  603 + self._tools_statistics(self._statistics)
516 604
517 # Return 605 # Return
518 return 606 return
@@ -527,8 +615,11 @@ class csfootprint(ctools.cscript): @@ -527,8 +615,11 @@ class csfootprint(ctools.cscript):
527 # Continue only if filename is valid 615 # Continue only if filename is valid
528 if self['outfile'].is_valid(): 616 if self['outfile'].is_valid():
529 617
530 - # Implement saving of graphics file  
531 - pass 618 + # Get outfile
  619 + outfile = self['outfile'].filename()
  620 +
  621 + # Create figure
  622 + self._create_figure(outfile.url(), self._statistics)
532 623
533 # ... signal that no graphics file was specified 624 # ... signal that no graphics file was specified
534 else: 625 else: