Commit bb9a556d85a74a6a24f53ab3dbeb4dde46508ef8
1 parent
6887a0c9
Implement csfootprint script (#3592)
Showing
10 changed files
with
1055 additions
and
3 deletions
cscripts/Makefile.am
| 1 | 1 | ############################################################################# |
| 2 | 2 | # Makefile for cscripts scripts # |
| 3 | 3 | # ------------------------------------------------------------------------- # |
| 4 | -# Copyright (C) 2016-2021 Juergen Knoedlseder # | |
| 4 | +# Copyright (C) 2016-2022 Juergen Knoedlseder # | |
| 5 | 5 | # ------------------------------------------------------------------------- # |
| 6 | 6 | # # |
| 7 | 7 | # This program is free software: you can redistribute it and/or modify # |
| ... | ... | @@ -25,6 +25,7 @@ pythonscripts = $(top_builddir)/cscripts/__init__.py \ |
| 25 | 25 | $(srcdir)/csbkgmodel.py \ |
| 26 | 26 | $(srcdir)/cscaldb.py \ |
| 27 | 27 | $(srcdir)/csebins.py \ |
| 28 | + $(srcdir)/csfootprint.py \ | |
| 28 | 29 | $(srcdir)/csinfo.py \ |
| 29 | 30 | $(srcdir)/cslightcrv.py \ |
| 30 | 31 | $(srcdir)/csmodelinfo.py \ |
| ... | ... | @@ -88,6 +89,7 @@ parfiles = $(srcdir)/csadd2caldb.par \ |
| 88 | 89 | $(srcdir)/cstsmapsplit.par \ |
| 89 | 90 | $(srcdir)/csviscube.par \ |
| 90 | 91 | $(srcdir)/csscs.par \ |
| 92 | + $(srcdir)/csfootprint.par \ | |
| 91 | 93 | $(srcdir)/csworkflow.par \ |
| 92 | 94 | $(srcdir)/csfindobs.par \ |
| 93 | 95 | $(srcdir)/csiactcopy.par \ |
| ... | ... | @@ -123,6 +125,7 @@ linkscripts = csadd2caldb \ |
| 123 | 125 | cstsmapsplit \ |
| 124 | 126 | csviscube \ |
| 125 | 127 | csscs \ |
| 128 | + csfootprint \ | |
| 126 | 129 | csworkflow \ |
| 127 | 130 | csfindobs \ |
| 128 | 131 | csiactcopy \ |
| ... | ... | @@ -163,6 +166,7 @@ testscripts = $(srcdir)/tests/__init__.py \ |
| 163 | 166 | $(top_srcdir)/test/test_cstsmapsplit.py \ |
| 164 | 167 | $(top_srcdir)/test/test_csviscube.py \ |
| 165 | 168 | $(top_srcdir)/test/test_csscs.py \ |
| 169 | + $(top_srcdir)/test/test_csfootprint.py \ | |
| 166 | 170 | $(top_srcdir)/test/test_csworkflow.py \ |
| 167 | 171 | $(top_srcdir)/test/test_obsutils.py \ |
| 168 | 172 | $(top_srcdir)/test/test_mputils.py \ | ... | ... |
cscripts/__init__.py.in
| 1 | 1 | # ========================================================================== |
| 2 | 2 | # cscripts Python module |
| 3 | 3 | # |
| 4 | -# Copyright (C) 2015-2021 Juergen Knoedlseder | |
| 4 | +# Copyright (C) 2015-2022 Juergen Knoedlseder | |
| 5 | 5 | # |
| 6 | 6 | # This program is free software: you can redistribute it and/or modify |
| 7 | 7 | # it under the terms of the GNU General Public License as published by |
| ... | ... | @@ -28,6 +28,7 @@ __all__ = [ |
| 28 | 28 | "csbkgmodel", |
| 29 | 29 | "cscaldb", |
| 30 | 30 | "csebins", |
| 31 | + "csfootprint", | |
| 31 | 32 | "csinfo", |
| 32 | 33 | "cslightcrv", |
| 33 | 34 | "csmodelinfo", |
| ... | ... | @@ -94,6 +95,7 @@ from cscripts.cstsmapmerge import cstsmapmerge |
| 94 | 95 | from cscripts.cstsmapsplit import cstsmapsplit |
| 95 | 96 | from cscripts.csviscube import csviscube |
| 96 | 97 | from cscripts.csscs import csscs |
| 98 | +from cscripts.csfootprint import csfootprint | |
| 97 | 99 | from cscripts.csworkflow import csworkflow |
| 98 | 100 | from cscripts import obsutils |
| 99 | 101 | from cscripts import modutils | ... | ... |
cscripts/csfootprint.par
0 → 100644
| 1 | +############################################################################# | |
| 2 | +# # | |
| 3 | +# Science Analysis Tools # | |
| 4 | +# # | |
| 5 | +# ------------------------------------------------------------------------- # | |
| 6 | +# # | |
| 7 | +# File: csfootprint.par # | |
| 8 | +# # | |
| 9 | +# Author: Juergen Knoedlseder # | |
| 10 | +# Jurgen.Knodlseder@irap.omp.eu # | |
| 11 | +# IRAP # | |
| 12 | +# # | |
| 13 | +# Purpose: Parameter file for the csfootprint script # | |
| 14 | +# # | |
| 15 | +############################################################################# | |
| 16 | +# | |
| 17 | +# Input and output parameters | |
| 18 | +#============================ | |
| 19 | +infile, f, h, $HOME/.gamma/statistics.xml,,, "Input high-level statistics XML file" | |
| 20 | +outfile, f, a, NONE,,, "Output graphics file (NONE if no graphics should be generated)" | |
| 21 | + | |
| 22 | +# | |
| 23 | +# Script parameters | |
| 24 | +#================== | |
| 25 | +tmin, t, a, NONE,,, "Start time for report (UTC string, JD, MJD or MET in seconds)" | |
| 26 | +tmax, t, a, NONE,,, "Stop time for report (UTC string, JD, MJD or MET in seconds)" | |
| 27 | + | |
| 28 | +# | |
| 29 | +# Standard parameters | |
| 30 | +#==================== | |
| 31 | +chatter, i, h, 2,0,4, "Chattiness of output" | |
| 32 | +clobber, b, h, yes,,, "Overwrite existing output files with new output files?" | |
| 33 | +debug, b, h, no,,, "Activate debugging mode?" | |
| 34 | +mode, s, h, ql,,, "Mode of automatic parameters" | |
| 35 | +logfile, f, h, csfootprint.log,,, "Log filename" | ... | ... |
cscripts/csfootprint.py
0 → 100755
| 1 | +#! /usr/bin/env python | |
| 2 | +# ========================================================================== | |
| 3 | +# Carbon footprint report script | |
| 4 | +# | |
| 5 | +# Copyright (C) 2022 Juergen Knoedlseder | |
| 6 | +# | |
| 7 | +# This program is free software: you can redistribute it and/or modify | |
| 8 | +# it under the terms of the GNU General Public License as published by | |
| 9 | +# the Free Software Foundation, either version 3 of the License, or | |
| 10 | +# (at your option) any later version. | |
| 11 | +# | |
| 12 | +# This program is distributed in the hope that it will be useful, | |
| 13 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | +# GNU General Public License for more details. | |
| 16 | +# | |
| 17 | +# You should have received a copy of the GNU General Public License | |
| 18 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 19 | +# | |
| 20 | +# ========================================================================== | |
| 21 | +import sys | |
| 22 | +import gammalib | |
| 23 | +import ctools | |
| 24 | + | |
| 25 | + | |
| 26 | +# ================= # | |
| 27 | +# csfootprint class # | |
| 28 | +# ================= # | |
| 29 | +class csfootprint(ctools.cscript): | |
| 30 | + """ | |
| 31 | + Carbon footprint report script | |
| 32 | + """ | |
| 33 | + | |
| 34 | + # Constructor | |
| 35 | + def __init__(self, *argv): | |
| 36 | + """ | |
| 37 | + Constructor | |
| 38 | + | |
| 39 | + Parameters | |
| 40 | + ---------- | |
| 41 | + argv : list of str | |
| 42 | + List of IRAF command line parameter strings of the form | |
| 43 | + ``parameter=3``. | |
| 44 | + """ | |
| 45 | + # Initialise application by calling the base class constructor | |
| 46 | + self._init_cscript(self.__class__.__name__, ctools.__version__, argv) | |
| 47 | + | |
| 48 | + # Return | |
| 49 | + return | |
| 50 | + | |
| 51 | + # State methods for pickling | |
| 52 | + def __getstate__(self): | |
| 53 | + """ | |
| 54 | + Extend ctools.cscript __getstate__ method | |
| 55 | + | |
| 56 | + Returns | |
| 57 | + ------- | |
| 58 | + state : dict | |
| 59 | + Pickled instance | |
| 60 | + """ | |
| 61 | + # Set pickled dictionary | |
| 62 | + state = {'base' : ctools.cscript.__getstate__(self)} | |
| 63 | + | |
| 64 | + # Return pickled dictionary | |
| 65 | + return state | |
| 66 | + | |
| 67 | + def __setstate__(self, state): | |
| 68 | + """ | |
| 69 | + Extend ctools.cscript __setstate__ method | |
| 70 | + | |
| 71 | + Parameters | |
| 72 | + ---------- | |
| 73 | + state : dict | |
| 74 | + Pickled instance | |
| 75 | + """ | |
| 76 | + # Set state | |
| 77 | + ctools.cscript.__setstate__(self, state['base']) | |
| 78 | + | |
| 79 | + # Return | |
| 80 | + return | |
| 81 | + | |
| 82 | + | |
| 83 | + # Private methods | |
| 84 | + def _get_parameters(self): | |
| 85 | + """ | |
| 86 | + Get parameters from parfile | |
| 87 | + """ | |
| 88 | + # Query input parameters | |
| 89 | + self['infile'].filename() | |
| 90 | + if self['tmin'].is_valid(): | |
| 91 | + self['tmin'].time() | |
| 92 | + if self['tmax'].is_valid(): | |
| 93 | + self['tmax'].time() | |
| 94 | + | |
| 95 | + # Query ahead output model filename | |
| 96 | + if self._read_ahead(): | |
| 97 | + if self['outfile'].is_valid(): | |
| 98 | + self['outfile'].filename() | |
| 99 | + | |
| 100 | + # Write input parameters into logger | |
| 101 | + self._log_parameters(gammalib.TERSE) | |
| 102 | + | |
| 103 | + # Return | |
| 104 | + return | |
| 105 | + | |
| 106 | + # Load statistics | |
| 107 | + def _load_statistics(self): | |
| 108 | + """ | |
| 109 | + Load statistics | |
| 110 | + """ | |
| 111 | + # Initialise statistics | |
| 112 | + statistics = {} | |
| 113 | + | |
| 114 | + # Get filename | |
| 115 | + infile = self['infile'].filename() | |
| 116 | + | |
| 117 | + # Load XML file | |
| 118 | + xml = gammalib.GXml() | |
| 119 | + xml.load(infile) | |
| 120 | + | |
| 121 | + # Get useful nodes | |
| 122 | + header = xml.element('statistics > header') | |
| 123 | + data = xml.element('statistics > data') | |
| 124 | + dates = header.element('dates') | |
| 125 | + countries = data.element('countries') | |
| 126 | + versions = data.element('versions') | |
| 127 | + daily = data.element('daily') | |
| 128 | + | |
| 129 | + # Extract header dates information | |
| 130 | + statistics['creation'] = dates.element('creation').string() | |
| 131 | + statistics['modified'] = dates.element('modified').string() | |
| 132 | + statistics['start'] = dates.element('start').string() | |
| 133 | + statistics['stop'] = dates.element('stop').string() | |
| 134 | + | |
| 135 | + # Set used time interval [start,stop] | |
| 136 | + if self['tmin'].is_valid(): | |
| 137 | + start = self['tmin'].time().utc() | |
| 138 | + if start < statistics['start']: | |
| 139 | + start = statistics['start'] | |
| 140 | + else: | |
| 141 | + start = statistics['start'] | |
| 142 | + if self['tmax'].is_valid(): | |
| 143 | + stop = self['tmax'].time().utc() | |
| 144 | + if stop > statistics['stop']: | |
| 145 | + stop = statistics['stop'] | |
| 146 | + else: | |
| 147 | + stop = statistics['stop'] | |
| 148 | + | |
| 149 | + # Set used time interval | |
| 150 | + statistics['use_start'] = start | |
| 151 | + statistics['use_stop'] = stop | |
| 152 | + | |
| 153 | + # Extract list of countries | |
| 154 | + statistics['countries'] = [] | |
| 155 | + num = countries.elements() | |
| 156 | + for i in range(num): | |
| 157 | + element = countries.element(i) | |
| 158 | + country = element.name() | |
| 159 | + calls = element.attribute('calls') | |
| 160 | + wall = element.attribute('wall') | |
| 161 | + cpu = element.attribute('cpu') | |
| 162 | + gCO2e = element.attribute('gCO2e') | |
| 163 | + entry = {'country': country, 'calls': calls, 'wall': wall, | |
| 164 | + 'cpu': cpu, 'gCO2e': gCO2e} | |
| 165 | + statistics['countries'].append(entry) | |
| 166 | + | |
| 167 | + # Extract list of versions | |
| 168 | + statistics['versions'] = [] | |
| 169 | + num = versions.elements() | |
| 170 | + for i in range(num): | |
| 171 | + element = versions.element(i) | |
| 172 | + version = element.name() | |
| 173 | + calls = element.attribute('calls') | |
| 174 | + wall = element.attribute('wall') | |
| 175 | + cpu = element.attribute('cpu') | |
| 176 | + gCO2e = element.attribute('gCO2e') | |
| 177 | + entry = {'version': version, 'calls': calls, 'wall': wall, | |
| 178 | + 'cpu': cpu, 'gCO2e': gCO2e} | |
| 179 | + statistics['versions'].append(entry) | |
| 180 | + | |
| 181 | + # Extract daily and tools statistics | |
| 182 | + statistics['daily'] = [] | |
| 183 | + statistics['tools'] = [] | |
| 184 | + num = daily.elements() | |
| 185 | + total_calls = 0 | |
| 186 | + total_wall = 0.0 | |
| 187 | + total_cpu = 0.0 | |
| 188 | + total_gCO2e = 0.0 | |
| 189 | + for i in range(num): | |
| 190 | + | |
| 191 | + # Get date | |
| 192 | + element = daily.element(i) | |
| 193 | + date = element.element('value',0).string() | |
| 194 | + | |
| 195 | + # Continue if date is out of range | |
| 196 | + if date < start[0:10] or date > stop[0:10]: | |
| 197 | + continue | |
| 198 | + | |
| 199 | + # Collect information | |
| 200 | + tools = element.element('tools',0) | |
| 201 | + ntools = tools.elements() | |
| 202 | + sum_calls = 0 | |
| 203 | + sum_wall = 0.0 | |
| 204 | + sum_cpu = 0.0 | |
| 205 | + sum_gCO2e = 0.0 | |
| 206 | + for k in range(ntools): | |
| 207 | + | |
| 208 | + # Extract information | |
| 209 | + tool = tools.element(k) | |
| 210 | + name = tool.name() | |
| 211 | + calls = int(tool.attribute('calls')) | |
| 212 | + wall = float(tool.attribute('wall')) | |
| 213 | + cpu = float(tool.attribute('cpu')) | |
| 214 | + gCO2e = float(tool.attribute('gCO2e')) | |
| 215 | + | |
| 216 | + # Update sums | |
| 217 | + sum_calls += calls | |
| 218 | + sum_wall += wall | |
| 219 | + sum_cpu += cpu | |
| 220 | + sum_gCO2e += gCO2e | |
| 221 | + | |
| 222 | + # Update tools data | |
| 223 | + if name in statistics['tools']: | |
| 224 | + statistics['tools'][name]['calls'] += calls | |
| 225 | + statistics['tools'][name]['wall'] += wall | |
| 226 | + statistics['tools'][name]['cpu'] += cpu | |
| 227 | + statistics['tools'][name]['gCO2e'] += gCO2e | |
| 228 | + else: | |
| 229 | + entry = {'name': name, 'calls': calls, 'wall': wall, | |
| 230 | + 'cpu': cpu, 'gCO2e': gCO2e} | |
| 231 | + statistics['tools'].append(entry) | |
| 232 | + | |
| 233 | + # Update totals | |
| 234 | + total_calls += sum_calls | |
| 235 | + total_wall += sum_wall | |
| 236 | + total_cpu += sum_cpu | |
| 237 | + total_gCO2e += sum_gCO2e | |
| 238 | + | |
| 239 | + # Set entry | |
| 240 | + entry = {'date': date, 'calls': sum_calls, 'wall': sum_wall, | |
| 241 | + 'cpu': sum_cpu, 'gCO2e': sum_gCO2e} | |
| 242 | + statistics['daily'].append(entry) | |
| 243 | + | |
| 244 | + # Update total statistics | |
| 245 | + statistics['calls'] = total_calls | |
| 246 | + statistics['wall'] = total_wall | |
| 247 | + statistics['cpu'] = total_cpu | |
| 248 | + statistics['gCO2e'] = total_gCO2e | |
| 249 | + | |
| 250 | + # Return statistics | |
| 251 | + return statistics | |
| 252 | + | |
| 253 | + # Format time | |
| 254 | + def _format_time(self, seconds): | |
| 255 | + """ | |
| 256 | + Format time | |
| 257 | + | |
| 258 | + Parameters | |
| 259 | + ---------- | |
| 260 | + seconds : float | |
| 261 | + Time in seconds | |
| 262 | + """ | |
| 263 | + # Format according to precision | |
| 264 | + if seconds < 60.0: | |
| 265 | + format = '%.3f seconds' % (seconds) | |
| 266 | + elif seconds < 3600.0: | |
| 267 | + format = '%.3f minutes' % (seconds/60.0) | |
| 268 | + else: | |
| 269 | + format = '%.3f hours' % (seconds/3600.0) | |
| 270 | + | |
| 271 | + # Return format | |
| 272 | + return format | |
| 273 | + | |
| 274 | + # Format carbon footprint | |
| 275 | + def _format_footprint(self, gCO2e): | |
| 276 | + """ | |
| 277 | + Format carbon footprint | |
| 278 | + | |
| 279 | + Parameters | |
| 280 | + ---------- | |
| 281 | + gCO2e : float | |
| 282 | + Carbon footprint in gCO2e | |
| 283 | + """ | |
| 284 | + # Format according to precision | |
| 285 | + if gCO2e < 1000.0: | |
| 286 | + format = '%.3f g CO2e' % (gCO2e) | |
| 287 | + elif seconds < 1.0e6: | |
| 288 | + format = '%.3f kg CO2e' % (gCO2e/1000.0) | |
| 289 | + else: | |
| 290 | + format = '%.3f t CO2e' % (gCO2e/1.0e6) | |
| 291 | + | |
| 292 | + # Return format | |
| 293 | + return format | |
| 294 | + | |
| 295 | + # Log global statistics | |
| 296 | + def _global_statistics(self, statistics): | |
| 297 | + """ | |
| 298 | + Log global statistics | |
| 299 | + | |
| 300 | + Parameters | |
| 301 | + ---------- | |
| 302 | + statistics : dict | |
| 303 | + Statistics dictionary | |
| 304 | + """ | |
| 305 | + # Log header | |
| 306 | + self._log_header1(gammalib.TERSE, 'Global statistics') | |
| 307 | + | |
| 308 | + # Derive information | |
| 309 | + tstart = gammalib.GTime(statistics['use_start']) | |
| 310 | + tstop = gammalib.GTime(statistics['use_stop']) | |
| 311 | + duration = tstop - tstart | |
| 312 | + if statistics['cpu'] != 0.0: | |
| 313 | + ci_cpu = statistics['gCO2e']/(statistics['cpu']/3600.0) | |
| 314 | + else: | |
| 315 | + ci_cpu = 0.0 | |
| 316 | + if duration != 0.0: | |
| 317 | + fp_dur = statistics['gCO2e']/(duration * gammalib.sec2day) | |
| 318 | + else: | |
| 319 | + fp_dur = 0.0 | |
| 320 | + fp_yr = fp_dur * 365.25 | |
| 321 | + dur_str = self._format_time(duration) | |
| 322 | + if statistics['wall'] != 0.0: | |
| 323 | + load_str = '%.1f %%' % (statistics['cpu']/statistics['wall']*100.0) | |
| 324 | + else: | |
| 325 | + load_str = 'undefined' | |
| 326 | + ci_cpu_str = self._format_footprint(ci_cpu) + ' / CPU hour' | |
| 327 | + fp_dur_str = self._format_footprint(fp_dur) + ' / day' | |
| 328 | + fp_yr_str = self._format_footprint(fp_yr) + ' / year' | |
| 329 | + wall_str = self._format_time(statistics['wall']) | |
| 330 | + cpu_str = self._format_time(statistics['cpu']) | |
| 331 | + gCO2e_str = self._format_footprint(statistics['gCO2e']) | |
| 332 | + date_str = '%s - %s' % (statistics['start'], statistics['stop']) | |
| 333 | + use_str = '%s - %s' % (statistics['use_start'], statistics['use_stop']) | |
| 334 | + | |
| 335 | + # Log report information | |
| 336 | + self._log_value(gammalib.NORMAL, 'Creation date', statistics['creation']) | |
| 337 | + self._log_value(gammalib.NORMAL, 'Last statistics update', statistics['modified']) | |
| 338 | + self._log_value(gammalib.NORMAL, 'Statistics date interval', date_str) | |
| 339 | + self._log_value(gammalib.NORMAL, 'Used date interval', use_str) | |
| 340 | + self._log_value(gammalib.NORMAL, 'Duration of used interval', dur_str) | |
| 341 | + self._log_value(gammalib.NORMAL, 'Total number of ctool runs', statistics['calls']) | |
| 342 | + self._log_value(gammalib.NORMAL, 'Total wall clock time', wall_str) | |
| 343 | + self._log_value(gammalib.NORMAL, 'Total CPU time', cpu_str) | |
| 344 | + self._log_value(gammalib.NORMAL, 'Average CPU load', load_str) | |
| 345 | + self._log_value(gammalib.NORMAL, 'Total carbon footprint', gCO2e_str) | |
| 346 | + self._log_value(gammalib.NORMAL, 'Average carbon intensity', ci_cpu_str) | |
| 347 | + self._log_value(gammalib.NORMAL, 'Average daily footprint', fp_dur_str) | |
| 348 | + self._log_value(gammalib.NORMAL, 'Expected annual footprint', fp_yr_str) | |
| 349 | + | |
| 350 | + # Return | |
| 351 | + return | |
| 352 | + | |
| 353 | + # Log daily statistics | |
| 354 | + def _daily_statistics(self, statistics): | |
| 355 | + """ | |
| 356 | + Log daily statistics | |
| 357 | + | |
| 358 | + Parameters | |
| 359 | + ---------- | |
| 360 | + statistics : dict | |
| 361 | + Statistics dictionary | |
| 362 | + """ | |
| 363 | + # Log header | |
| 364 | + self._log_header1(gammalib.TERSE, 'Daily statistics') | |
| 365 | + | |
| 366 | + # Log daily carbon footprint statistics | |
| 367 | + self._log_header3(gammalib.NORMAL, 'Carbon footprint') | |
| 368 | + | |
| 369 | + # Loop over daily entries | |
| 370 | + for entry in statistics['daily']: | |
| 371 | + self._log_value(gammalib.NORMAL, entry['date'], self._format_footprint(entry['gCO2e'])) | |
| 372 | + | |
| 373 | + # Log daily run statistics | |
| 374 | + self._log_header3(gammalib.NORMAL, 'ctools or cscript calls') | |
| 375 | + | |
| 376 | + # Loop over daily entries | |
| 377 | + for entry in statistics['daily']: | |
| 378 | + self._log_value(gammalib.NORMAL, entry['date'], entry['calls']) | |
| 379 | + | |
| 380 | + # Log daily carbon footprint statistics | |
| 381 | + self._log_header3(gammalib.NORMAL, 'Used wall clock time') | |
| 382 | + | |
| 383 | + # Loop over daily entries | |
| 384 | + for entry in statistics['daily']: | |
| 385 | + self._log_value(gammalib.NORMAL, entry['date'], self._format_time(entry['wall'])) | |
| 386 | + | |
| 387 | + # Log daily carbon footprint statistics | |
| 388 | + self._log_header3(gammalib.NORMAL, 'Used CPU time') | |
| 389 | + | |
| 390 | + # Loop over daily entries | |
| 391 | + for entry in statistics['daily']: | |
| 392 | + self._log_value(gammalib.NORMAL, entry['date'], self._format_time(entry['cpu'])) | |
| 393 | + | |
| 394 | + # Return | |
| 395 | + return | |
| 396 | + | |
| 397 | + # Log tools statistics | |
| 398 | + def _tools_statistics(self, statistics): | |
| 399 | + """ | |
| 400 | + Log tools statistics | |
| 401 | + | |
| 402 | + Parameters | |
| 403 | + ---------- | |
| 404 | + statistics : dict | |
| 405 | + Statistics dictionary | |
| 406 | + """ | |
| 407 | + # Get Python version information | |
| 408 | + req_version = (2,4) | |
| 409 | + cur_version = sys.version_info | |
| 410 | + | |
| 411 | + # Log header | |
| 412 | + self._log_header1(gammalib.TERSE, 'ctools and cscripts statistics') | |
| 413 | + | |
| 414 | + # Log daily carbon footprint statistics | |
| 415 | + self._log_header3(gammalib.NORMAL, 'Carbon footprint') | |
| 416 | + | |
| 417 | + # Optionally sort list | |
| 418 | + if cur_version > req_version: | |
| 419 | + sorted_entries = sorted(statistics['tools'], key=lambda d: d['gCO2e'], reverse=True) | |
| 420 | + else: | |
| 421 | + sorted_entries = statistics['tools'] | |
| 422 | + | |
| 423 | + # Loop over entries | |
| 424 | + for i, entry in enumerate(sorted_entries): | |
| 425 | + if i < 10: | |
| 426 | + level = gammalib.NORMAL | |
| 427 | + else: | |
| 428 | + level = gammalib.EXPLICIT | |
| 429 | + self._log_value(level, entry['name'], self._format_footprint(entry['gCO2e'])) | |
| 430 | + if len(sorted_entries) > 9 and self['chatter'].integer() < 3: | |
| 431 | + self._log_string(gammalib.NORMAL, ' ... (list truncated after 10 entries) ...') | |
| 432 | + | |
| 433 | + # Log daily run statistics | |
| 434 | + self._log_header3(gammalib.NORMAL, 'ctools or cscript calls') | |
| 435 | + | |
| 436 | + # Optionally sort list | |
| 437 | + if cur_version > req_version: | |
| 438 | + sorted_entries = sorted(statistics['tools'], key=lambda d: d['calls'], reverse=True) | |
| 439 | + else: | |
| 440 | + sorted_entries = statistics['tools'] | |
| 441 | + | |
| 442 | + # Loop over entries | |
| 443 | + for i, entry in enumerate(sorted_entries): | |
| 444 | + if i < 10: | |
| 445 | + level = gammalib.NORMAL | |
| 446 | + else: | |
| 447 | + level = gammalib.EXPLICIT | |
| 448 | + self._log_value(level, entry['name'], entry['calls']) | |
| 449 | + if len(sorted_entries) > 9 and self['chatter'].integer() < 3: | |
| 450 | + self._log_string(gammalib.NORMAL, ' ... (list truncated after 10 entries) ...') | |
| 451 | + | |
| 452 | + # Log daily carbon footprint statistics | |
| 453 | + self._log_header3(gammalib.NORMAL, 'Used wall clock time') | |
| 454 | + | |
| 455 | + # Optionally sort list | |
| 456 | + if cur_version > req_version: | |
| 457 | + sorted_entries = sorted(statistics['tools'], key=lambda d: d['wall'], reverse=True) | |
| 458 | + else: | |
| 459 | + sorted_entries = statistics['tools'] | |
| 460 | + | |
| 461 | + # Loop over entries | |
| 462 | + for i, entry in enumerate(sorted_entries): | |
| 463 | + if i < 10: | |
| 464 | + level = gammalib.NORMAL | |
| 465 | + else: | |
| 466 | + level = gammalib.EXPLICIT | |
| 467 | + self._log_value(level, entry['name'], self._format_time(entry['wall'])) | |
| 468 | + if len(sorted_entries) > 9 and self['chatter'].integer() < 3: | |
| 469 | + self._log_string(gammalib.NORMAL, ' ... (list truncated after 10 entries) ...') | |
| 470 | + | |
| 471 | + # Log daily carbon footprint statistics | |
| 472 | + self._log_header3(gammalib.NORMAL, 'Used CPU time') | |
| 473 | + | |
| 474 | + # Optionally sort list | |
| 475 | + if cur_version > req_version: | |
| 476 | + sorted_entries = sorted(statistics['tools'], key=lambda d: d['cpu'], reverse=True) | |
| 477 | + else: | |
| 478 | + sorted_entries = statistics['tools'] | |
| 479 | + | |
| 480 | + # Loop over entries | |
| 481 | + for i, entry in enumerate(sorted_entries): | |
| 482 | + if i < 10: | |
| 483 | + level = gammalib.NORMAL | |
| 484 | + else: | |
| 485 | + level = gammalib.EXPLICIT | |
| 486 | + self._log_value(level, entry['name'], self._format_time(entry['cpu'])) | |
| 487 | + if len(sorted_entries) > 9 and self['chatter'].integer() < 3: | |
| 488 | + self._log_string(gammalib.NORMAL, ' ... (list truncated after 10 entries) ...') | |
| 489 | + | |
| 490 | + | |
| 491 | + # Return | |
| 492 | + return | |
| 493 | + | |
| 494 | + | |
| 495 | + # Public methods | |
| 496 | + def run(self): | |
| 497 | + """ | |
| 498 | + Run the script | |
| 499 | + """ | |
| 500 | + # Switch screen logging on in debug mode | |
| 501 | + if self._logDebug(): | |
| 502 | + self._log.cout(True) | |
| 503 | + | |
| 504 | + # Get parameters | |
| 505 | + self._get_parameters() | |
| 506 | + | |
| 507 | + # Log header | |
| 508 | + self._log_header1(gammalib.TERSE, 'Load statistics data') | |
| 509 | + | |
| 510 | + # Load statistics | |
| 511 | + statistics = self._load_statistics() | |
| 512 | + | |
| 513 | + # Log statistics | |
| 514 | + self._global_statistics(statistics) | |
| 515 | + self._daily_statistics(statistics) | |
| 516 | + self._tools_statistics(statistics) | |
| 517 | + | |
| 518 | + # Return | |
| 519 | + return | |
| 520 | + | |
| 521 | + def save(self): | |
| 522 | + """ | |
| 523 | + Save something | |
| 524 | + """ | |
| 525 | + # Write header | |
| 526 | + self._log_header1(gammalib.TERSE, 'Save graphics') | |
| 527 | + | |
| 528 | + # Continue only if filename is valid | |
| 529 | + if self['outfile'].is_valid(): | |
| 530 | + | |
| 531 | + # Implement saving of graphics file | |
| 532 | + pass | |
| 533 | + | |
| 534 | + # ... signal that no graphics file was specified | |
| 535 | + else: | |
| 536 | + self._log_value(gammalib.NORMAL, 'Graphics file', 'not specified') | |
| 537 | + | |
| 538 | + # Return | |
| 539 | + return | |
| 540 | + | |
| 541 | + | |
| 542 | +# ======================== # | |
| 543 | +# Main routine entry point # | |
| 544 | +# ======================== # | |
| 545 | +if __name__ == '__main__': | |
| 546 | + | |
| 547 | + # Create instance of application | |
| 548 | + app = csfootprint(sys.argv) | |
| 549 | + | |
| 550 | + # Execute application | |
| 551 | + app.execute() | ... | ... |
doc/source/users/environment.rst
| ... | ... | @@ -60,4 +60,104 @@ computation took, and :math:`{\rm Carbon\,\,footprint}` is the carbon footprint |
| 60 | 60 | |
| 61 | 61 | The carbon footprint of all ctools and cscript runs are stored in an ASCII file |
| 62 | 62 | that you will find in a folder under your home directory, named ``.gamma/statistics.csv``. |
| 63 | +This file is regularly scanned and purged by the GammaLib daemon that creates the | |
| 64 | +high-level statistics file ``.gamma/statistics.xml`` that is in the same folder. You may | |
| 65 | +display the content of this file using the ``csfootprint`` script: | |
| 66 | + | |
| 67 | +.. code-block:: bash | |
| 68 | + | |
| 69 | + $ csfootprint debug=yes | |
| 70 | + Start time for report (UTC string, JD, MJD or MET in seconds) [NONE] | |
| 71 | + Stop time for report (UTC string, JD, MJD or MET in seconds) [NONE] | |
| 72 | + Output graphics file (NONE if no graphics should be generated) [NONE] | |
| 73 | + ... | |
| 74 | + 2022-02-20T14:38:29: +===================+ | |
| 75 | + 2022-02-20T14:38:29: | Global statistics | | |
| 76 | + 2022-02-20T14:38:29: +===================+ | |
| 77 | + 2022-02-20T14:38:29: Creation date .............: 2022-02-19T22:09:05 | |
| 78 | + 2022-02-20T14:38:29: Last statistics update ....: 2022-02-20T14:35:20 | |
| 79 | + 2022-02-20T14:38:29: Statistics date interval ..: 2022-02-18T22:21:56 - 2022-02-20T14:35:17 | |
| 80 | + 2022-02-20T14:38:29: Used date interval ........: 2022-02-18T22:21:56 - 2022-02-20T14:35:17 | |
| 81 | + 2022-02-20T14:38:29: Duration of used interval .: 40.222 hours | |
| 82 | + 2022-02-20T14:38:29: Total number of ctool runs : 3104 | |
| 83 | + 2022-02-20T14:38:29: Total wall clock time .....: 34.200 minutes | |
| 84 | + 2022-02-20T14:38:29: Total CPU time ............: 27.543 minutes | |
| 85 | + 2022-02-20T14:38:29: Average CPU load ..........: 80.5 % | |
| 86 | + 2022-02-20T14:38:29: Total carbon footprint ....: 1.623 g CO2e | |
| 87 | + 2022-02-20T14:38:29: Average carbon intensity ..: 3.535 g CO2e / CPU hour | |
| 88 | + 2022-02-20T14:38:29: Average daily footprint ...: 0.968 g CO2e / day | |
| 89 | + 2022-02-20T14:38:29: Expected annual footprint .: 353.632 g CO2e / year | |
| 90 | + 2022-02-20T14:38:29: | |
| 91 | + 2022-02-20T14:38:29: +==================+ | |
| 92 | + 2022-02-20T14:38:29: | Daily statistics | | |
| 93 | + 2022-02-20T14:38:29: +==================+ | |
| 94 | + 2022-02-20T14:38:29: === Carbon footprint === | |
| 95 | + 2022-02-20T14:38:29: 2022-02-18 ................: 1.336 g CO2e | |
| 96 | + 2022-02-20T14:38:29: 2022-02-19 ................: 0.010 g CO2e | |
| 97 | + 2022-02-20T14:38:29: 2022-02-20 ................: 0.277 g CO2e | |
| 98 | + 2022-02-20T14:38:29: === ctools or cscript calls === | |
| 99 | + 2022-02-20T14:38:29: 2022-02-18 ................: 2895 | |
| 100 | + 2022-02-20T14:38:29: 2022-02-19 ................: 80 | |
| 101 | + 2022-02-20T14:38:29: 2022-02-20 ................: 129 | |
| 102 | + 2022-02-20T14:38:29: === Used wall clock time === | |
| 103 | + 2022-02-20T14:38:29: 2022-02-18 ................: 25.483 minutes | |
| 104 | + 2022-02-20T14:38:29: 2022-02-19 ................: 1.033 minutes | |
| 105 | + 2022-02-20T14:38:29: 2022-02-20 ................: 7.683 minutes | |
| 106 | + 2022-02-20T14:38:29: === Used CPU time === | |
| 107 | + 2022-02-20T14:38:29: 2022-02-18 ................: 22.682 minutes | |
| 108 | + 2022-02-20T14:38:29: 2022-02-19 ................: 9.895 seconds | |
| 109 | + 2022-02-20T14:38:29: 2022-02-20 ................: 4.695 minutes | |
| 110 | + 2022-02-20T14:38:29: | |
| 111 | + 2022-02-20T14:38:29: +================================+ | |
| 112 | + 2022-02-20T14:38:29: | ctools and cscripts statistics | | |
| 113 | + 2022-02-20T14:38:29: +================================+ | |
| 114 | + 2022-02-20T14:38:29: === Carbon footprint === | |
| 115 | + 2022-02-20T14:38:29: ctlike ....................: 0.318 g CO2e | |
| 116 | + 2022-02-20T14:38:29: cspull ....................: 0.186 g CO2e | |
| 117 | + 2022-02-20T14:38:29: csbkgmodel ................: 0.178 g CO2e | |
| 118 | + 2022-02-20T14:38:29: ctobssim ..................: 0.172 g CO2e | |
| 119 | + 2022-02-20T14:38:29: ctobssim ..................: 0.087 g CO2e | |
| 120 | + 2022-02-20T14:38:29: comobsbin .................: 0.081 g CO2e | |
| 121 | + 2022-02-20T14:38:29: comlixmap .................: 0.069 g CO2e | |
| 122 | + 2022-02-20T14:38:29: ctulimit ..................: 0.064 g CO2e | |
| 123 | + 2022-02-20T14:38:29: cstsdist ..................: 0.058 g CO2e | |
| 124 | + 2022-02-20T14:38:29: ctselect ..................: 0.044 g CO2e | |
| 125 | + 2022-02-20T14:38:29: ... (list truncated after 10 entries) ... | |
| 126 | + 2022-02-20T14:38:29: === ctools or cscript calls === | |
| 127 | + 2022-02-20T14:38:29: ctobssim ..................: 1795 | |
| 128 | + 2022-02-20T14:38:29: ctlike ....................: 220 | |
| 129 | + 2022-02-20T14:38:29: ctselect ..................: 87 | |
| 130 | + 2022-02-20T14:38:29: csfootprint ...............: 80 | |
| 131 | + 2022-02-20T14:38:29: cscaldb ...................: 79 | |
| 132 | + 2022-02-20T14:38:29: csscs .....................: 55 | |
| 133 | + 2022-02-20T14:38:29: ctulimit ..................: 54 | |
| 134 | + 2022-02-20T14:38:29: ctcubemask ................: 51 | |
| 135 | + 2022-02-20T14:38:29: csphagen ..................: 46 | |
| 136 | + 2022-02-20T14:38:29: ctbin .....................: 31 | |
| 137 | + 2022-02-20T14:38:29: ... (list truncated after 10 entries) ... | |
| 138 | + 2022-02-20T14:38:29: === Used wall clock time === | |
| 139 | + 2022-02-20T14:38:29: ctlike ....................: 5.367 minutes | |
| 140 | + 2022-02-20T14:38:29: cspull ....................: 3.817 minutes | |
| 141 | + 2022-02-20T14:38:29: csbkgmodel ................: 3.067 minutes | |
| 142 | + 2022-02-20T14:38:29: ctobssim ..................: 2.967 minutes | |
| 143 | + 2022-02-20T14:38:29: csfootprint ...............: 2.300 minutes | |
| 144 | + 2022-02-20T14:38:29: ctobssim ..................: 1.483 minutes | |
| 145 | + 2022-02-20T14:38:29: comobsbin .................: 1.367 minutes | |
| 146 | + 2022-02-20T14:38:29: cstsdist ..................: 1.300 minutes | |
| 147 | + 2022-02-20T14:38:29: comlixmap .................: 1.183 minutes | |
| 148 | + 2022-02-20T14:38:29: ctselect ..................: 1.083 minutes | |
| 149 | + 2022-02-20T14:38:29: ... (list truncated after 10 entries) ... | |
| 150 | + 2022-02-20T14:38:29: === Used CPU time === | |
| 151 | + 2022-02-20T14:38:29: ctlike ....................: 5.392 minutes | |
| 152 | + 2022-02-20T14:38:29: cspull ....................: 3.157 minutes | |
| 153 | + 2022-02-20T14:38:29: csbkgmodel ................: 3.029 minutes | |
| 154 | + 2022-02-20T14:38:29: ctobssim ..................: 2.921 minutes | |
| 155 | + 2022-02-20T14:38:29: ctobssim ..................: 1.469 minutes | |
| 156 | + 2022-02-20T14:38:29: comobsbin .................: 1.367 minutes | |
| 157 | + 2022-02-20T14:38:29: comlixmap .................: 1.169 minutes | |
| 158 | + 2022-02-20T14:38:29: ctulimit ..................: 1.086 minutes | |
| 159 | + 2022-02-20T14:38:29: cstsdist ..................: 58.978 seconds | |
| 160 | + 2022-02-20T14:38:29: ctselect ..................: 45.005 seconds | |
| 161 | + 2022-02-20T14:38:29: ... (list truncated after 10 entries) ... | |
| 162 | + | |
| 63 | 163 | ... | ... |
doc/source/users/reference_manual/csfootprint.rst
0 → 100644
| 1 | +.. _csfootprint: | |
| 2 | + | |
| 3 | +csfootprint | |
| 4 | +=========== | |
| 5 | + | |
| 6 | +Generates a carbon footprint report for the usage of ctools on your computed. | |
| 7 | + | |
| 8 | + | |
| 9 | +Synopsis | |
| 10 | +-------- | |
| 11 | + | |
| 12 | +This script generates a carbon footprint report based on the usage of ctools | |
| 13 | +on your computed. ctools usage statistics are collected in the file | |
| 14 | +``~/.gamma/statistics.xml`` that is located in the user's home directory. The | |
| 15 | +information file is updated using a dedicated daemon that works in the background | |
| 16 | +and collects information about ctools usage. | |
| 17 | + | |
| 18 | + | |
| 19 | +General parameters | |
| 20 | +------------------ | |
| 21 | + | |
| 22 | +``(infile = $HOME/.gamma/statistics.xml) [file]`` | |
| 23 | + Input high-level statistics XML file. | |
| 24 | + | |
| 25 | +``outfile [file]`` | |
| 26 | + Output graphics file (``NONE`` if no graphics should be generated). | |
| 27 | + | |
| 28 | +``tmin [time]`` | |
| 29 | + Start time for footprint reporting (UTC string, JD, MJD or MET in seconds). | |
| 30 | + Start times given in MET seconds are counted with respect to the time | |
| 31 | + reference of the input observation(s). | |
| 32 | + If ``INDEF``, ``NONE``, ``UNDEF`` or ``UNDEFINED`` is passed as value, the | |
| 33 | + report will be generated for the full data provided in the statistics | |
| 34 | + file. | |
| 35 | + | |
| 36 | +``tmax [time]`` | |
| 37 | + Stop time for footprint reporting (UTC string, JD, MJD or MET in seconds). | |
| 38 | + Stop times given in MET seconds are counted with respect to the time | |
| 39 | + reference of the input observation(s). | |
| 40 | + If ``INDEF``, ``NONE``, ``UNDEF`` or ``UNDEFINED`` is passed as value, the | |
| 41 | + report will be generated for the full data provided in the statistics | |
| 42 | + file. | |
| 43 | + | |
| 44 | + | |
| 45 | +Standard parameters | |
| 46 | +------------------- | |
| 47 | + | |
| 48 | +``(chatter = 2) [integer]`` | |
| 49 | + Verbosity of the executable: | |
| 50 | + ``chatter = 0``: no information will be logged | |
| 51 | + | |
| 52 | + ``chatter = 1``: only errors will be logged | |
| 53 | + | |
| 54 | + ``chatter = 2``: errors and actions will be logged | |
| 55 | + | |
| 56 | + ``chatter = 3``: report about the task execution | |
| 57 | + | |
| 58 | + ``chatter = 4``: detailed report about the task execution | |
| 59 | + | |
| 60 | +``(clobber = yes) [boolean]`` | |
| 61 | + Specifies whether an existing output file should be overwritten. | |
| 62 | + | |
| 63 | +``(debug = no) [boolean]`` | |
| 64 | + Enables debug mode. In debug mode the executable will dump any log file output to the console. | |
| 65 | + | |
| 66 | +``(mode = ql) [string]`` | |
| 67 | + Mode of automatic parameters (default is ``ql``, i.e. "query and learn"). | |
| 68 | + | |
| 69 | +``(logfile = csfootprint.log) [string]`` | |
| 70 | + Name of log file. | |
| 71 | + | |
| 72 | + | |
| 73 | +Related tools or scripts | |
| 74 | +------------------------ | |
| 75 | + | |
| 76 | +None | ... | ... |
doc/source/users/reference_manual/index.rst
| ... | ... | @@ -57,6 +57,7 @@ CTA and IACT analysis tools and scripts |
| 57 | 57 | ctskymap --- Generates sky map <ctskymap> |
| 58 | 58 | csbkgmodel --- Generates background model for 3D analysis <csbkgmodel> |
| 59 | 59 | csebins --- Generates energy boundaries for stacked analysis <csebins> |
| 60 | + csfootprint --- Generates carbon footprint report <csfootprint> | |
| 60 | 61 | csobsdef --- Generates observation definition file <csobsdef> |
| 61 | 62 | csobsselect --- Select observations from observation definition file <csobsselect> |
| 62 | 63 | csphagen --- Generates PHA, ARF, RMF files based on source/background regions <csphagen> | ... | ... |
test/data/statistics.xml
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
| 2 | +<statistics title="High-level statistic"> | |
| 3 | + <header> | |
| 4 | + <dates> | |
| 5 | + <creation>2022-02-19T22:09:05</creation> | |
| 6 | + <modified>2022-02-20T14:35:20</modified> | |
| 7 | + <start>2022-02-18T22:21:56</start> | |
| 8 | + <stop>2022-02-20T14:35:17</stop> | |
| 9 | + </dates> | |
| 10 | + <countries> | |
| 11 | + <country>FR</country> | |
| 12 | + </countries> | |
| 13 | + </header> | |
| 14 | + <data> | |
| 15 | + <daily> | |
| 16 | + <date> | |
| 17 | + <value>2022-02-18</value> | |
| 18 | + <tools> | |
| 19 | + <test_GApplication version="1.0.0" calls="10" wall="0" cpu="0.034568" gCO2e="3.6524768e-05" /> | |
| 20 | + <ctobssim version="2.0.0.dev" calls="1795" wall="178" cpu="175.230736" gCO2e="0.172060195882" /> | |
| 21 | + <ctselect version="2.0.0.dev" calls="87" wall="65" cpu="45.005446" gCO2e="0.0441931424436" /> | |
| 22 | + <ctphase version="2.0.0.dev" calls="13" wall="0" cpu="0.162489" gCO2e="0.0001595595941" /> | |
| 23 | + <ctfindvar version="2.0.0.dev" calls="9" wall="3" cpu="2.356012" gCO2e="0.002313321049" /> | |
| 24 | + <ctbin version="2.0.0.dev" calls="31" wall="6" cpu="4.978268" gCO2e="0.004889514038" /> | |
| 25 | + <ctlike version="2.0.0.dev" calls="220" wall="322" cpu="323.513057" gCO2e="0.31765157135" /> | |
| 26 | + <cttsmap version="2.0.0.dev" calls="10" wall="12" cpu="10.679273" gCO2e="0.01048572233" /> | |
| 27 | + <ctmodel version="2.0.0.dev" calls="28" wall="6" cpu="4.591355" gCO2e="0.004508190556" /> | |
| 28 | + <ctskymap version="2.0.0.dev" calls="19" wall="1" cpu="0.433249" gCO2e="0.0004254149905" /> | |
| 29 | + <ctexpcube version="2.0.0.dev" calls="24" wall="6" cpu="4.030692" gCO2e="0.00395767278" /> | |
| 30 | + <ctpsfcube version="2.0.0.dev" calls="23" wall="5" cpu="3.274088" gCO2e="0.003214774076" /> | |
| 31 | + <ctedispcube version="2.0.0.dev" calls="14" wall="3" cpu="3.050093" gCO2e="0.002994823833" /> | |
| 32 | + <ctbkgcube version="2.0.0.dev" calls="23" wall="6" cpu="2.757245" gCO2e="0.002707299323" /> | |
| 33 | + <ctmapcube version="2.0.0.dev" calls="14" wall="14" cpu="4.75437" gCO2e="0.0046682128217" /> | |
| 34 | + <ctcubemask version="2.0.0.dev" calls="51" wall="8" cpu="1.13723" gCO2e="0.0011201495309" /> | |
| 35 | + <ctbutterfly version="2.0.0.dev" calls="5" wall="1" cpu="0.759734" gCO2e="0.0007459676696" /> | |
| 36 | + <ctulimit version="2.0.0.dev" calls="54" wall="64" cpu="65.159264" gCO2e="0.06397913951" /> | |
| 37 | + <cterror version="2.0.0.dev" calls="10" wall="25" cpu="25.103675" gCO2e="0.02464868358" /> | |
| 38 | + <ctprob version="2.0.0.dev" calls="11" wall="4" cpu="1.608447" gCO2e="0.0015793075709" /> | |
| 39 | + <cscript_test version="2.0.0.dev" calls="27" wall="3" cpu="0.913572" gCO2e="0.000897810804" /> | |
| 40 | + <ctobservation_test version="2.0.0.dev" calls="2" wall="0" cpu="0.002656" gCO2e="2.608842e-06" /> | |
| 41 | + <ctlikelihood_test version="2.0.0.dev" calls="1" wall="0" cpu="0.000474" gCO2e="4.673725e-07" /> | |
| 42 | + <csadd2caldb version="2.0.0.dev" calls="7" wall="0" cpu="0.082939" gCO2e="8.1443581e-05" /> | |
| 43 | + <csbkgmodel version="2.0.0.dev" calls="16" wall="184" cpu="181.730569" gCO2e="0.178436729885" /> | |
| 44 | + <cscaldb version="2.0.0.dev" calls="6" wall="0" cpu="0.020241" gCO2e="1.9882967e-05" /> | |
| 45 | + <csebins version="2.0.0.dev" calls="3" wall="1" cpu="0.586342" gCO2e="0.000575717516" /> | |
| 46 | + <csobsselect version="2.0.0.dev" calls="18" wall="1" cpu="0.091911" gCO2e="9.1630531e-05" /> | |
| 47 | + <cslightcrv version="2.0.0.dev" calls="27" wall="45" cpu="29.142719" gCO2e="0.028614540668" /> | |
| 48 | + <csphagen version="2.0.0.dev" calls="46" wall="38" cpu="33.605548" gCO2e="0.032996623152" /> | |
| 49 | + <csmodelinfo version="2.0.0.dev" calls="4" wall="2" cpu="0.510316" gCO2e="0.000501071409" /> | |
| 50 | + <csmodelmerge version="2.0.0.dev" calls="6" wall="0" cpu="0.035814" gCO2e="3.5175674e-05" /> | |
| 51 | + <csmodelselect version="2.0.0.dev" calls="3" wall="0" cpu="0.032228" gCO2e="3.164878e-05" /> | |
| 52 | + <csmodelsois version="2.0.0.dev" calls="4" wall="5" cpu="4.443827" gCO2e="0.004363287526" /> | |
| 53 | + <csobs2caldb version="2.0.0.dev" calls="4" wall="0" cpu="0.536876" gCO2e="0.00052715198" /> | |
| 54 | + <csobsdef version="2.0.0.dev" calls="5" wall="2" cpu="2.083649" gCO2e="0.002045889685" /> | |
| 55 | + <csobsinfo version="2.0.0.dev" calls="5" wall="3" cpu="2.06328" gCO2e="0.00202735977" /> | |
| 56 | + <csphasecrv version="2.0.0.dev" calls="26" wall="29" cpu="16.067829" gCO2e="0.015776636533" /> | |
| 57 | + <cspull version="2.0.0.dev" calls="24" wall="6" cpu="2.647948" gCO2e="0.002599984392" /> | |
| 58 | + <csresmap version="2.0.0.dev" calls="6" wall="0" cpu="0.614617" gCO2e="0.0006034869" /> | |
| 59 | + <csresspec version="2.0.0.dev" calls="8" wall="3" cpu="3.078816" gCO2e="0.003023022045" /> | |
| 60 | + <csroot2caldb version="2.0.0.dev" calls="2" wall="1" cpu="0.036487" gCO2e="3.58296e-05" /> | |
| 61 | + <cssens version="2.0.0.dev" calls="12" wall="25" cpu="12.589562" gCO2e="0.012361392076" /> | |
| 62 | + <csspec version="2.0.0.dev" calls="18" wall="64" cpu="43.689946" gCO2e="0.042898087855" /> | |
| 63 | + <cssrcdetect version="2.0.0.dev" calls="3" wall="1" cpu="0.155595" gCO2e="0.00015277975" /> | |
| 64 | + <cstsdist version="2.0.0.dev" calls="17" wall="78" cpu="58.977613" gCO2e="0.057908662799" /> | |
| 65 | + <cstsmapmerge version="2.0.0.dev" calls="7" wall="0" cpu="0.054628" gCO2e="5.3648664e-05" /> | |
| 66 | + <cstsmapsplit version="2.0.0.dev" calls="7" wall="3" cpu="0.686096" gCO2e="0.000673666381" /> | |
| 67 | + <csviscube version="2.0.0.dev" calls="2" wall="1" cpu="1.127427" gCO2e="0.0011069963" /> | |
| 68 | + <csscs version="2.0.0.dev" calls="55" wall="32" cpu="23.301421" gCO2e="0.022879160613" /> | |
| 69 | + <csworkflow version="2.0.0.dev" calls="3" wall="22" cpu="21.524805" gCO2e="0.021134671" /> | |
| 70 | + <mputils_test version="2.0.0.dev" calls="9" wall="0" cpu="0.019627" gCO2e="1.92879525e-05" /> | |
| 71 | + <csfindobs version="2.0.0.dev" calls="5" wall="0" cpu="0.03152" gCO2e="3.0956552e-05" /> | |
| 72 | + <csiactcopy version="2.0.0.dev" calls="8" wall="2" cpu="0.12279" gCO2e="0.000120576215" /> | |
| 73 | + <csiactdata version="2.0.0.dev" calls="4" wall="0" cpu="0.023479" gCO2e="2.3057371e-05" /> | |
| 74 | + <csiactobs version="2.0.0.dev" calls="9" wall="7" cpu="4.970589" gCO2e="0.004880509978" /> | |
| 75 | + <comobsselect version="2.0.0.dev" calls="2" wall="1" cpu="0.118271" gCO2e="0.0001161293" /> | |
| 76 | + <comobsbin version="2.0.0.dev" calls="3" wall="82" cpu="82.020818" gCO2e="0.080534191756" /> | |
| 77 | + <comobsback version="2.0.0.dev" calls="5" wall="21" cpu="21.588201" gCO2e="0.02119691057" /> | |
| 78 | + <comobsmodel version="2.0.0.dev" calls="3" wall="1" cpu="0.475343" gCO2e="0.000466731257" /> | |
| 79 | + <comobsadd version="2.0.0.dev" calls="3" wall="2" cpu="1.467164" gCO2e="0.00144057658" /> | |
| 80 | + <comobsres version="2.0.0.dev" calls="3" wall="19" cpu="17.898668" gCO2e="0.017574257417" /> | |
| 81 | + <comobssim version="2.0.0.dev" calls="3" wall="1" cpu="0.355431" gCO2e="0.000348993711" /> | |
| 82 | + <comlixfit version="2.0.0.dev" calls="5" wall="44" cpu="42.639466" gCO2e="0.041866632735" /> | |
| 83 | + <comlixmap version="2.0.0.dev" calls="5" wall="71" cpu="70.110307" gCO2e="0.06883955744" /> | |
| 84 | + <comsrcdetect version="2.0.0.dev" calls="3" wall="0" cpu="0.035303" gCO2e="3.4668041e-05" /> | |
| 85 | + </tools> | |
| 86 | + </date> | |
| 87 | + <date> | |
| 88 | + <value>2022-02-19</value> | |
| 89 | + <tools> | |
| 90 | + <cscaldb version="2.0.0.dev" calls="79" wall="27" cpu="2.098166" gCO2e="0.00206024862" /> | |
| 91 | + <ctobssim version="2.0.0.dev" calls="1" wall="35" cpu="7.797325" gCO2e="0.007656001" /> | |
| 92 | + </tools> | |
| 93 | + </date> | |
| 94 | + <date> | |
| 95 | + <value>2022-02-20</value> | |
| 96 | + <tools> | |
| 97 | + <ctobssim version="2.0.0.dev" calls="14" wall="89" cpu="88.139225" gCO2e="0.086544736" /> | |
| 98 | + <ctlike version="2.0.0.dev" calls="14" wall="1" cpu="2.907895" gCO2e="0.0028552129" /> | |
| 99 | + <cspull version="2.0.0.dev" calls="10" wall="229" cpu="189.407517" gCO2e="0.1859745197" /> | |
| 100 | + <test_GApplication version="1.0.0" calls="4" wall="1" cpu="0.020321" gCO2e="2.2644983e-05" country="FR" /> | |
| 101 | + <cscaldb version="2.0.0.dev" country="FR" calls="7" wall="3" cpu="0.194611" gCO2e="0.00019109055" /> | |
| 102 | + <csfootprint version="2.0.0.dev" country="FR" calls="80" wall="138" cpu="1.05496" gCO2e="0.00103598216" /> | |
| 103 | + </tools> | |
| 104 | + </date> | |
| 105 | + </daily> | |
| 106 | + <countries> | |
| 107 | + <FR version="2.0.0.dev" calls="83" wall="140" cpu="1.136547" gCO2e="0.00111609432" /> | |
| 108 | + </countries> | |
| 109 | + <versions> | |
| 110 | + <2.0.0.dev calls="82" wall="138" cpu="1.109517" gCO2e="0.00108955228" /> | |
| 111 | + </versions> | |
| 112 | + </data> | |
| 113 | +</statistics> | ... | ... |
test/test_csfootprint.py
0 → 100644
| 1 | +#! /usr/bin/env python | |
| 2 | +# ========================================================================== | |
| 3 | +# This scripts performs unit tests for the csfootprint script. | |
| 4 | +# | |
| 5 | +# Copyright (C) 2022 Juergen Knoedlseder | |
| 6 | +# | |
| 7 | +# This program is free software: you can redistribute it and/or modify | |
| 8 | +# it under the terms of the GNU General Public License as published by | |
| 9 | +# the Free Software Foundation, either version 3 of the License, or | |
| 10 | +# (at your option) any later version. | |
| 11 | +# | |
| 12 | +# This program is distributed in the hope that it will be useful, | |
| 13 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 14 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 15 | +# GNU General Public License for more details. | |
| 16 | +# | |
| 17 | +# You should have received a copy of the GNU General Public License | |
| 18 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. | |
| 19 | +# | |
| 20 | +# ========================================================================== | |
| 21 | +import os | |
| 22 | +import gammalib | |
| 23 | +import cscripts | |
| 24 | +from testing import test | |
| 25 | + | |
| 26 | + | |
| 27 | +# ================================= # | |
| 28 | +# Test class for csfootprint script # | |
| 29 | +# ================================= # | |
| 30 | +class Test(test): | |
| 31 | + """ | |
| 32 | + Test class for csfootprint script | |
| 33 | + | |
| 34 | + This test class makes unit tests for the csfootprint script by using it from | |
| 35 | + the command line and from Python. | |
| 36 | + """ | |
| 37 | + | |
| 38 | + # Constructor | |
| 39 | + def __init__(self): | |
| 40 | + """ | |
| 41 | + Constructor | |
| 42 | + """ | |
| 43 | + # Call base class constructor | |
| 44 | + test.__init__(self) | |
| 45 | + | |
| 46 | + # Set members | |
| 47 | + self._infile = self._datadir + '/statistics.xml' | |
| 48 | + | |
| 49 | + # Return | |
| 50 | + return | |
| 51 | + | |
| 52 | + # Set test functions | |
| 53 | + def set(self): | |
| 54 | + """ | |
| 55 | + Set all test functions | |
| 56 | + """ | |
| 57 | + # Set test name | |
| 58 | + self.name('csfootprint') | |
| 59 | + | |
| 60 | + # Append tests | |
| 61 | + self.append(self._test_cmd, 'Test csfootprint on command line') | |
| 62 | + self.append(self._test_python, 'Test csfootprint from Python') | |
| 63 | + self.append(self._test_pickeling, 'Test csfootprint pickeling') | |
| 64 | + | |
| 65 | + # Return | |
| 66 | + return | |
| 67 | + | |
| 68 | + # Test csfootprint on command line | |
| 69 | + def _test_cmd(self): | |
| 70 | + """ | |
| 71 | + Test csfootprint on the command line | |
| 72 | + """ | |
| 73 | + # Set script name | |
| 74 | + csfootprint = self._script('csfootprint') | |
| 75 | + | |
| 76 | + # Setup csfootprint command | |
| 77 | + cmd = csfootprint+' infile="'+self._infile+'" outfile=NONE tmin=NONE'+ \ | |
| 78 | + ' tmax=NONE logfile="csfootprint_cmd1.log" chatter=1' | |
| 79 | + | |
| 80 | + # Check if execution was successful | |
| 81 | + self.test_value(self._execute(cmd), 0, | |
| 82 | + 'Check successful execution from command line') | |
| 83 | + | |
| 84 | + # Setup csfootprint command | |
| 85 | + cmd = csfootprint+' infile="file_that_does_not_exist.xml" outfile=NONE tmin=NONE'+ \ | |
| 86 | + ' tmax=NONE logfile="csfootprint_cmd1.log" chatter=1' | |
| 87 | + | |
| 88 | + # Check if execution was successful | |
| 89 | + self.test_assert(self._execute(cmd, success=False) != 0, | |
| 90 | + 'Check invalid input file when executed from command line') | |
| 91 | + | |
| 92 | + # Check csfootprint --help | |
| 93 | + self._check_help(csfootprint) | |
| 94 | + | |
| 95 | + # Return | |
| 96 | + return | |
| 97 | + | |
| 98 | + # Test csfootprint from Python | |
| 99 | + def _test_python(self): | |
| 100 | + """ | |
| 101 | + Test csfootprint from Python | |
| 102 | + """ | |
| 103 | + # Allocate csfootprint | |
| 104 | + script = cscripts.csfootprint() | |
| 105 | + | |
| 106 | + # Check that saving does not nothing | |
| 107 | + script['infile'] = self._infile | |
| 108 | + script['outfile'] = 'NONE' | |
| 109 | + script['tmin'] = 'NONE' | |
| 110 | + script['tmax'] = 'NONE' | |
| 111 | + script['logfile'] = 'csfootprint_py0.log' | |
| 112 | + script['chatter'] = 2 | |
| 113 | + | |
| 114 | + # Run csfootprint script | |
| 115 | + script.logFileOpen() | |
| 116 | + script.run() | |
| 117 | + | |
| 118 | + # Check result | |
| 119 | + self._check_result(script) | |
| 120 | + | |
| 121 | + # Return | |
| 122 | + return | |
| 123 | + | |
| 124 | + # Test csfootprint pickeling | |
| 125 | + def _test_pickeling(self): | |
| 126 | + """ | |
| 127 | + Test csfootprint pickeling | |
| 128 | + """ | |
| 129 | + # Perform pickeling test of empty class | |
| 130 | + self._pickeling(cscripts.csfootprint()) | |
| 131 | + | |
| 132 | + # Setup script for pickling text | |
| 133 | + script = cscripts.csfootprint() | |
| 134 | + script['infile'] = self._infile | |
| 135 | + script['outfile'] = 'NONE' | |
| 136 | + script['tmin'] = 'NONE' | |
| 137 | + script['tmax'] = 'NONE' | |
| 138 | + script['logfile'] = 'csfootprint_py1_pickle.log' | |
| 139 | + script['chatter'] = 2 | |
| 140 | + | |
| 141 | + # Perform pickeling tests of filled class | |
| 142 | + obj = self._pickeling(script) | |
| 143 | + | |
| 144 | + # Run csfootprint script and save result | |
| 145 | + obj.logFileOpen() # Make sure we get a log file | |
| 146 | + obj.run() | |
| 147 | + obj.save() | |
| 148 | + | |
| 149 | + # Check result | |
| 150 | + self._check_result(script) | |
| 151 | + | |
| 152 | + # Return | |
| 153 | + return | |
| 154 | + | |
| 155 | + # Check csfootprint result | |
| 156 | + def _check_result(self, script): | |
| 157 | + """ | |
| 158 | + Check content of script | |
| 159 | + | |
| 160 | + Parameters | |
| 161 | + ---------- | |
| 162 | + script : `~cscripts.csfootprint` | |
| 163 | + csfootprint instance | |
| 164 | + """ | |
| 165 | + # TODO: Implement test on script result | |
| 166 | + | |
| 167 | + # Return | |
| 168 | + return | ... | ... |
test/test_python_cscripts.py
| ... | ... | @@ -2,7 +2,7 @@ |
| 2 | 2 | # ========================================================================== |
| 3 | 3 | # This scripts performs unit tests for cscripts |
| 4 | 4 | # |
| 5 | -# Copyright (C) 2016-2021 Juergen Knoedlseder | |
| 5 | +# Copyright (C) 2016-2022 Juergen Knoedlseder | |
| 6 | 6 | # |
| 7 | 7 | # This program is free software: you can redistribute it and/or modify |
| 8 | 8 | # it under the terms of the GNU General Public License as published by |
| ... | ... | @@ -28,6 +28,7 @@ import test_cscaldb |
| 28 | 28 | import test_csadd2caldb |
| 29 | 29 | import test_csbkgmodel |
| 30 | 30 | import test_csebins |
| 31 | +import test_csfootprint | |
| 31 | 32 | import test_csfindobs |
| 32 | 33 | import test_csinfo |
| 33 | 34 | import test_cslightcrv |
| ... | ... | @@ -146,6 +147,7 @@ def test(installed=False, debug=False): |
| 146 | 147 | test_cstsmapsplit.Test(), |
| 147 | 148 | test_csviscube.Test(), |
| 148 | 149 | test_csscs.Test(), |
| 150 | + test_csfootprint.Test(), | |
| 149 | 151 | test_csworkflow.Test(), |
| 150 | 152 | test_obsutils.Test(), |
| 151 | 153 | test_mputils.Test()] | ... | ... |