diff --git a/NEWS b/NEWS index 8fa8d5a..f2722cd 100644 --- a/NEWS +++ b/NEWS @@ -44,7 +44,7 @@ The following classes have been renamed: - none The following methods have been added: -- GApplication::eCO2() +- GApplication::gCO2e() - GApplication::stamp(GFitsHdu&) - GApplication::stamp(GFits&) - GApplication::stamp(GFilename&) @@ -146,6 +146,8 @@ The following methods have been added: - gammalib::compare() - gammalib::xml_check_parnum() - gammalib::xml_check_type() +- gammalib::host_country() +- gammalib::http_query() - gammalib::check_energy_interval() - gammalib::check_prj_x2s_status() - gammalib::check_prj_s2x_status() @@ -214,7 +216,7 @@ Add GApplication::stamp() methods to write provenance information into a FITS HDU, a FITS object or a FITS file. So far the only provenance information that is written is the CREATOR keyword (#3662). -Add GApplication::eCO2() method to estimate the carbon footprint if the elapsed +Add GApplication::gCO2e() method to estimate the carbon footprint if the elapsed CPU time. The carbon footprint estimation is also added to the trailer text of an application to raise awareness. In addition, an ASCII file is maintained in the $HOME/.gamma folder that contains statistics on application usage, including @@ -410,6 +412,11 @@ were added to compute the total solid angle within specified sky region(s) (#178 14. Support module ------------------ +Added gammalib::host_country() method that returns the host country on which the code +is executed. + +Added gammalib::http_query() method to get the response of a HTTP query. + Added gammalib::strdate() method that returns a string of the current date and time (#3592). diff --git a/include/GApplication.hpp b/include/GApplication.hpp index c26ed69..3477ff8 100644 --- a/include/GApplication.hpp +++ b/include/GApplication.hpp @@ -83,7 +83,7 @@ public: const std::string& version(void) const; double telapse(void) const; double celapse(void) const; - double eCO2(void) const; + double gCO2e(const std::string& country) const; void logFileOpen(const bool& clobber = true); void logFileClose(void); bool logTerse(void) const; diff --git a/include/GTools.hpp b/include/GTools.hpp index fe9417a..068ad10 100644 --- a/include/GTools.hpp +++ b/include/GTools.hpp @@ -164,6 +164,7 @@ namespace gammalib { const double& tol); std::string http_query(const std::string& host, const std::string& query); + std::string host_country(void); } diff --git a/pyext/GApplication.i b/pyext/GApplication.i index 52c0c73..e347d57 100644 --- a/pyext/GApplication.i +++ b/pyext/GApplication.i @@ -1,7 +1,7 @@ /*************************************************************************** * GApplication.i - GammaLib application base class * * ----------------------------------------------------------------------- * - * copyright (C) 2010-2021 by Juergen Knoedlseder * + * copyright (C) 2010-2022 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * This program is free software: you can redistribute it and/or modify * @@ -60,7 +60,7 @@ public: // Public methods double telapse(void) const; double celapse(void) const; - double eCO2(void) const; + double gCO2e(const std::string& country) const; void logFileOpen(const bool& clobber = true); void logFileClose(void); diff --git a/pyext/GTools.i b/pyext/GTools.i index b74b206..ebcc2cb 100644 --- a/pyext/GTools.i +++ b/pyext/GTools.i @@ -117,4 +117,5 @@ namespace gammalib { const double& tol); std::string http_query(const std::string& host, const std::string& query); + std::string host_country(void); } diff --git a/src/app/GApplication.cpp b/src/app/GApplication.cpp index 5c60550..d1ca8c8 100644 --- a/src/app/GApplication.cpp +++ b/src/app/GApplication.cpp @@ -392,15 +392,16 @@ double GApplication::celapse(void) const /***********************************************************************//** - * @brief Return application equivalent CO2 imprint (units: g) + * @brief Return application equivalent CO2 footprint (units: g CO2e) * - * @return Application equivalent CO2 imprint (g). + * @param[in] country Country where computation is performed. + * @return Application equivalent CO2 footprint (g CO2e). * - * The method returns the equivalent CO2 imprint in grams after the currently - * elpased CPU time as returned by celapse(). The method assumes an imprint - * of 4.68 g eCO2 / CPU hour as estimated by Berthoud et al. (2020) - * (see page 10 of https://hal.archives-ouvertes.fr/hal-02549565v4/document). - * The imprint factor includes + * The method returns the equivalent CO2 footprint in grams after the + * currently elpased CPU time as returned by celapse(). The method assumes + * an emission factor of 4.68 g CO2e / CPU hour as estimated by Berthoud et + * al. (2020) (https://hal.archives-ouvertes.fr/hal-02549565v4/document). + * The emission factor includes * * server fabrication * * server environment * * server usage (electricity) @@ -409,23 +410,25 @@ double GApplication::celapse(void) const * * personnel equipment * * personnel energy * - * The imprint factor is based on an estimate done for the DAHU cluster - * of the UMS GRICAD in 2019. Note that the impact of electricity was + * The emission factor is based on an estimate done for the DAHU cluster + * of the UMS GRICAD in 2019. Note that the footprint of electricity was * computed assuming 108 g eCO2 / kWh consumed, and about 50% of the total - * imprint was due to electricity consumption. For countries with a more + * footprint was due to electricity consumption. For countries with a more * carbon intensive electricity production, the CO2 imprint will be * accordingly larger. + * + * @todo Implement carbon footprint for other countries than France ***************************************************************************/ -double GApplication::eCO2(void) const +double GApplication::gCO2e(const std::string& country) const { // Get elapsed time in CPU jours double cpu_hours = celapse() / 3600.0; // Convert into g eCO2 - double eCO2 = 4.68 * cpu_hours; + double gCO2e = 4.68 * cpu_hours; - // Return equivalent CO2 imprint - return eCO2; + // Return equivalent CO2 footprint + return gCO2e; } @@ -633,14 +636,14 @@ void GApplication::log_trailer(void) // Get application statistics double telapse = this->telapse(); double celapse = this->celapse(); - double eCO2 = this->eCO2(); + double gCO2e = this->gCO2e(gammalib::host_country()); // Dump trailer log << "Application \"" << m_name << "\" terminated after "; log << telapse << " wall clock seconds, consuming "; log << celapse << " seconds of CPU time and generating a carbon"; - log << " footprint of " << eCO2 << " g eCO2."; - if (eCO2 >= 1000.0) { + log << " footprint of " << gCO2e << " g eCO2."; + if (gCO2e >= 1000.0) { log << " Please watch your carbon footprint."; } if (telapse < 0.1) { @@ -1213,10 +1216,18 @@ void GApplication::write_statistics(void) // statistics FILE* fptr = fopen(filename.c_str(), "a"); if (fptr != NULL) { - fprintf(fptr, "%s,%s,FR,%s,%s,%e,%e,%e\n", + + // Get host country + std::string country = gammalib::host_country(); + + // Write statistics string + fprintf(fptr, "%s,%s,%s,%s,%s,%e,%e,%e\n", gammalib::strdate().c_str(), VERSION, + country.c_str(), name().c_str(), version().c_str(), - telapse(), celapse(), eCO2()); + telapse(), celapse(), gCO2e(country)); + + // Close file fclose(fptr); } diff --git a/src/support/GTools.cpp b/src/support/GTools.cpp index 129c785..5961fe0 100644 --- a/src/support/GTools.cpp +++ b/src/support/GTools.cpp @@ -2288,3 +2288,37 @@ std::string gammalib::http_query(const std::string& host, const std::string& que // Return response return std::string(response); } + + +/***********************************************************************//** + * @brief Return host country + * + * @return Host country. + * + * Returns host country using a curl query to http://api.hostip.info/. If + * the country could not be determined an empty string is returned. + ***************************************************************************/ +std::string gammalib::host_country(void) +{ + // Initialise country + std::string country; + + // Setup curl command + char command[256]; + sprintf(command, "curl --silent http://api.hostip.info/country.php?ip="); + + // Open the process with given 'command' for reading + FILE* file = popen(command, "r"); + + // Retrieve curl output + char output[1024]; + if (fgets(output, sizeof(output)-1, file) != NULL) { + country = std::string(output); + } + + // Close process + pclose(file); + + // Return country + return country; +}