123 infile = self[
'infile'].filename()
126 xml = gammalib.GXml()
130 header = xml.element(
'statistics > header')
131 data = xml.element(
'statistics > data')
132 dates = header.element(
'dates')
133 countries = data.element(
'countries')
134 versions = data.element(
'versions')
135 daily = data.element(
'daily')
138 statistics[
'creation'] = dates.element(
'creation').string()
139 statistics[
'modified'] = dates.element(
'modified').string()
140 statistics[
'start'] = dates.element(
'start').string()
141 statistics[
'stop'] = dates.element(
'stop').string()
144 if self[
'tmin'].is_valid():
145 start = self[
'tmin'].time().utc()
146 if start < statistics[
'start']:
147 start = statistics[
'start']
149 start = statistics[
'start']
150 if self[
'tmax'].is_valid():
151 stop = self[
'tmax'].time().utc()
152 if stop > statistics[
'stop']:
153 stop = statistics[
'stop']
155 stop = statistics[
'stop']
158 statistics[
'use_start'] = start
159 statistics[
'use_stop'] = stop
162 statistics[
'countries'] = []
163 num = countries.elements()
165 element = countries.element(i)
166 country = element.name()
167 calls = element.attribute(
'calls')
168 wall = element.attribute(
'wall')
169 cpu = element.attribute(
'cpu')
170 gCO2e = element.attribute(
'gCO2e')
171 entry = {
'country': country,
'calls': calls,
'wall': wall,
172 'cpu': cpu,
'gCO2e': gCO2e}
173 statistics[
'countries'].append(entry)
176 statistics[
'versions'] = []
177 num = versions.elements()
179 element = versions.element(i)
180 version = element.name()
181 calls = element.attribute(
'calls')
182 wall = element.attribute(
'wall')
183 cpu = element.attribute(
'cpu')
184 gCO2e = element.attribute(
'gCO2e')
185 entry = {
'version': version,
'calls': calls,
'wall': wall,
186 'cpu': cpu,
'gCO2e': gCO2e}
187 statistics[
'versions'].append(entry)
190 statistics[
'daily'] = []
191 statistics[
'tools'] = []
192 num = daily.elements()
200 element = daily.element(i)
201 date = element.element(
'value',0).string()
204 if date < start[0:10]
or date > stop[0:10]:
208 tools = element.element(
'tools',0)
209 ntools = tools.elements()
214 for k
in range(ntools):
217 tool = tools.element(k)
219 calls = int(tool.attribute(
'calls'))
220 wall = float(tool.attribute(
'wall'))
221 cpu = float(tool.attribute(
'cpu'))
222 gCO2e = float(tool.attribute(
'gCO2e'))
232 for s
in statistics[
'tools']:
233 if name == s[
'name']:
241 entry = {
'name': name,
'calls': calls,
'wall': wall,
242 'cpu': cpu,
'gCO2e': gCO2e}
243 statistics[
'tools'].append(entry)
246 total_calls += sum_calls
247 total_wall += sum_wall
249 total_gCO2e += sum_gCO2e
252 entry = {
'date': date,
'calls': sum_calls,
'wall': sum_wall,
253 'cpu': sum_cpu,
'gCO2e': sum_gCO2e}
254 statistics[
'daily'].append(entry)
257 statistics[
'calls'] = total_calls
258 statistics[
'wall'] = total_wall
259 statistics[
'cpu'] = total_cpu
260 statistics[
'gCO2e'] = total_gCO2e
397 Log global statistics
402 Statistics dictionary
405 self._log_header1(gammalib.TERSE,
'Global statistics')
411 self._log_value(gammalib.NORMAL,
'Creation date', statistics[
'creation'])
412 self._log_value(gammalib.NORMAL,
'Last statistics update', statistics[
'modified'])
413 self._log_value(gammalib.NORMAL,
'Statistics date interval', info[
'date'])
414 self._log_value(gammalib.NORMAL,
'Used date interval', info[
'use'])
415 self._log_value(gammalib.NORMAL,
'Duration of used interval', info[
'dur'])
416 self._log_value(gammalib.NORMAL,
'Total number of ctool runs', statistics[
'calls'])
417 self._log_value(gammalib.NORMAL,
'Total wall clock time', info[
'wall'])
418 self._log_value(gammalib.NORMAL,
'Total CPU time', info[
'cpu'])
419 self._log_value(gammalib.NORMAL,
'Average CPU load', info[
'load'])
420 self._log_value(gammalib.NORMAL,
'Total carbon footprint', info[
'gCO2e'])
421 self._log_value(gammalib.NORMAL,
' due to power consumption', info[
'elect'])
422 self._log_value(gammalib.NORMAL,
' due to infrastructure', info[
'gCO2e_infra'])
423 self._log_value(gammalib.NORMAL,
'Average carbon intensity', info[
'ci_cpu'])
424 self._log_value(gammalib.NORMAL,
'Average daily footprint', info[
'fp_dur'])
425 self._log_value(gammalib.NORMAL,
'Estimated annual footprint', info[
'fp_yr'])
438 Statistics dictionary
441 self._log_header1(gammalib.TERSE,
'Daily statistics')
444 self._log_header3(gammalib.NORMAL,
'Carbon footprint')
447 for entry
in statistics[
'daily']:
448 self._log_value(gammalib.NORMAL, entry[
'date'], self.
_format_footprint(entry[
'gCO2e']))
451 self._log_header3(gammalib.NORMAL,
'ctools or cscript calls')
454 for entry
in statistics[
'daily']:
455 self._log_value(gammalib.NORMAL, entry[
'date'], entry[
'calls'])
458 self._log_header3(gammalib.NORMAL,
'Used wall clock time')
461 for entry
in statistics[
'daily']:
462 self._log_value(gammalib.NORMAL, entry[
'date'], self.
_format_time(entry[
'wall']))
465 self._log_header3(gammalib.NORMAL,
'Used CPU time')
468 for entry
in statistics[
'daily']:
469 self._log_value(gammalib.NORMAL, entry[
'date'], self.
_format_time(entry[
'cpu']))
482 Statistics dictionary
486 cur_version = sys.version_info
489 self._log_header1(gammalib.TERSE,
'ctools and cscripts statistics')
492 self._log_header3(gammalib.NORMAL,
'Carbon footprint')
495 if cur_version > req_version:
496 sorted_entries = sorted(statistics[
'tools'], key=
lambda d: d[
'gCO2e'], reverse=
True)
498 sorted_entries = statistics[
'tools']
501 for i, entry
in enumerate(sorted_entries):
503 level = gammalib.NORMAL
505 level = gammalib.EXPLICIT
507 if len(sorted_entries) > 9
and self[
'chatter'].integer() < 3:
508 self._log_string(gammalib.NORMAL,
' ... (list truncated after 10 entries) ...')
511 self._log_header3(gammalib.NORMAL,
'ctools or cscript calls')
514 if cur_version > req_version:
515 sorted_entries = sorted(statistics[
'tools'], key=
lambda d: d[
'calls'], reverse=
True)
517 sorted_entries = statistics[
'tools']
520 for i, entry
in enumerate(sorted_entries):
522 level = gammalib.NORMAL
524 level = gammalib.EXPLICIT
525 self._log_value(level, entry[
'name'], entry[
'calls'])
526 if len(sorted_entries) > 9
and self[
'chatter'].integer() < 3:
527 self._log_string(gammalib.NORMAL,
' ... (list truncated after 10 entries) ...')
530 self._log_header3(gammalib.NORMAL,
'Used wall clock time')
533 if cur_version > req_version:
534 sorted_entries = sorted(statistics[
'tools'], key=
lambda d: d[
'wall'], reverse=
True)
536 sorted_entries = statistics[
'tools']
539 for i, entry
in enumerate(sorted_entries):
541 level = gammalib.NORMAL
543 level = gammalib.EXPLICIT
544 self._log_value(level, entry[
'name'], self.
_format_time(entry[
'wall']))
545 if len(sorted_entries) > 9
and self[
'chatter'].integer() < 3:
546 self._log_string(gammalib.NORMAL,
' ... (list truncated after 10 entries) ...')
549 self._log_header3(gammalib.NORMAL,
'Used CPU time')
552 if cur_version > req_version:
553 sorted_entries = sorted(statistics[
'tools'], key=
lambda d: d[
'cpu'], reverse=
True)
555 sorted_entries = statistics[
'tools']
558 for i, entry
in enumerate(sorted_entries):
560 level = gammalib.NORMAL
562 level = gammalib.EXPLICIT
563 self._log_value(level, entry[
'name'], self.
_format_time(entry[
'cpu']))
564 if len(sorted_entries) > 9
and self[
'chatter'].integer() < 3:
565 self._log_string(gammalib.NORMAL,
' ... (list truncated after 10 entries) ...')
580 Statistics dictionary
586 import matplotlib.pyplot
as plt
587 import matplotlib.gridspec
as gridspec
591 xsize = 1.4142 * ysize
592 fig = plt.figure(figsize=(xsize, ysize))
595 user = pwd.getpwuid(os.getuid())[0]
596 title =
'ctools carbon footprint report for user "%s"' % (user)
597 subtitle =
r'Dates: %s - %s' % \
598 (statistics[
'use_start'], statistics[
'use_stop'])
599 fig.suptitle(title, fontsize=16)
600 fig.text(0.5, 0.925, subtitle, fontsize=11, ha=
'center')
603 fig.subplots_adjust(left=0.08, bottom=0.07, right=0.97, top=0.88,
604 wspace=0.1, hspace=0.2)
607 gs1 = gridspec.GridSpec(4,3)
608 gs1.update(hspace=0.8, wspace=0.8)
609 ax1 = fig.add_subplot(gs1[0,0:2])
610 ax2 = fig.add_subplot(gs1[1,0:2])
611 ax3 = fig.add_subplot(gs1[2,0:2])
612 ax4 = fig.add_subplot(gs1[3,0:2])
614 gs2 = gridspec.GridSpec(8,3)
615 gs2.update(hspace=0.3, bottom=0.0, top=0.95, right=0.96, wspace=0.0)
616 ax10 = fig.add_subplot(gs2[2:5,2])
617 ax11 = fig.add_subplot(gs2[5:8,2])
620 self.
_plot_daily(ax1, statistics, quantity=
'gCO2e', title=
'Footprint',
622 self.
_plot_daily(ax2, statistics, quantity=
'cpu', title=
'CPU hours',
623 ylabel=
'hours', yscale=1.0/3600.0)
624 self.
_plot_daily(ax3, statistics, quantity=
'wall', title=
'Wall clock hours',
625 ylabel=
'hours', yscale=1.0/3600.0)
626 self.
_plot_daily(ax4, statistics, quantity=
'calls',
627 title=
'ctools calls', ylabel=
'calls')
630 ver = sys.version.split()[0]
632 args, _, _, _, _, _, _ = inspect.getfullargspec(plt.pie)
634 args, _, _, _ = inspect.getargspec(plt.pie)
637 self.
_plot_pie(ax10, statistics, quantity=
'gCO2e', title=
'Footprint', args=args)
638 self.
_plot_pie(ax11, statistics, quantity=
'calls', title=
'ctools calls', args=args)
649 fig.text(x0, y0,
'Total carbon footprint: ', fontsize=fontsize, ha=
'left')
650 fig.text(x0+dx, y0, info[
'gCO2e'], fontsize=fontsize, ha=
'left')
652 fig.text(x0, y0,
' due to power consumption: ', fontsize=fontsize, ha=
'left')
653 fig.text(x0+dx, y0, info[
'elect'], fontsize=fontsize, ha=
'left')
655 fig.text(x0, y0,
' due to infrastructure: ', fontsize=fontsize, ha=
'left')
656 fig.text(x0+dx, y0, info[
'gCO2e_infra'], fontsize=fontsize, ha=
'left')
658 fig.text(x0, y0,
'Total CPU time: ', fontsize=fontsize, ha=
'left')
659 fig.text(x0+dx, y0, info[
'cpu'], fontsize=fontsize, ha=
'left')
661 fig.text(x0, y0,
'Average carbon intensity: ', fontsize=fontsize, ha=
'left')
662 fig.text(x0+dx, y0, info[
'ci_cpu'], fontsize=fontsize, ha=
'left')
664 fig.text(x0, y0,
'Average daily footprint: ', fontsize=fontsize, ha=
'left')
665 fig.text(x0+dx, y0, info[
'fp_dur'], fontsize=fontsize, ha=
'left')
667 fig.text(x0, y0,
'Estimated annual footprint: ', fontsize=fontsize, ha=
'left')
668 fig.text(x0+dx, y0, info[
'fp_yr'], fontsize=fontsize, ha=
'left')
675 fig.savefig(outfile, dpi=300)
678 self._log_value(gammalib.NORMAL,
'Graphics file', outfile)
681 except (ImportError, RuntimeError):
684 self._log_value(gammalib.NORMAL,
'Graphics file',
'matplotlib not available')
730 def _plot_pie(self, ax, statistics, quantity='gCO2e', title='Footprint', num=5, args=None):
739 Statistics dictionary
740 quantity : str, optional
742 title : str, optional
744 num : integer, optional
745 Number of pies displayed explicitly
746 arg : list or str, optional
747 List of pie method keyword arguments
751 cur_version = sys.version_info
754 if cur_version > req_version:
755 sorted_entries = sorted(statistics[
'tools'], key=
lambda d: d[quantity], reverse=
True)
757 sorted_entries = statistics[
'tools']
763 for i, entry
in enumerate(sorted_entries):
765 labels.append(entry[
'name'])
766 sizes.append(entry[quantity])
768 others += entry[quantity]
769 labels.append(
'others')
773 if 'wedgeprops' in args:
774 wedges, _, _ = ax.pie(sizes, autopct=
'%1.0f%%', pctdistance=0.8,
775 startangle=90, radius=1.0,
776 wedgeprops=dict(width=0.4, edgecolor=
'w'))
778 wedges, _, _ = ax.pie(sizes, autopct=
'%1.0f%%', pctdistance=0.8,
779 startangle=90, radius=1.0)
781 ax.legend(wedges, labels, loc=
'center', fontsize=8, frameon=
False)