Source code for cmtklib.carbonfootprint

# Copyright (C) 2009-2022, Ecole Polytechnique Federale de Lausanne (EPFL) and
# Hospital Center and University of Lausanne (UNIL-CHUV), Switzerland, and CMP3 contributors
# All rights reserved.
#
#  This software is distributed under the open-source license Modified BSD.

"""Module that defines CMTK functions for converting C02 emissions estimated with `codecarbon`."""

import os
from pkg_resources import resource_filename
import logging
from pathlib import Path
import pandas as pd
from codecarbon import EmissionsTracker

from cmp.info import __version__


[docs]def create_emissions_tracker(bids_root): """Return a new instance of `codecarbon.EmissionsTracker`. Parameters ---------- bids_root : string Path to the root directory of the BIDS dataset Returns ------- tracker: `codecarbon.EmissionsTracker` Return a new instance of `codecarbon.EmissionsTracker` References ---------- https://github.com/mlco2/codecarbon/blob/v1.2.0/codecarbon/emissions_tracker.py """ # Create the code folder if it does not exist yet if not os.path.exists(str(Path(bids_root) / "code")): os.makedirs(str(Path(bids_root) / "code"), exist_ok=True) # To not pollute CMP3 outputs with codecarbon outputs # Comment this line for debug if you get for instance # Emissions: O Kg logging.getLogger("codecarbon").disabled = True # Create and return the emissions tracker return EmissionsTracker( project_name=f"connectomemapper_{__version__}_gui", output_dir=str(Path(bids_root) / "code"), measure_power_secs=15, )
[docs]def get_emission_car_miles_equivalent(emissions): """Return the equivalent of CO2 emissions [Kg] in terms of kms traveled by an average car. References ---------- https://github.com/mlco2/codecarbon/blob/c6aebb9681186a71573748e381b6a3c9731de2d3/codecarbon/viz/data.py#L53 """ return "{:.0f}".format((emissions / 0.409) * 1.60934)
[docs]def get_emission_tv_time_equivalent(emissions): """Return the equivalent of CO2 emissions [Kg] in terms of kms traveled by an average car. References ---------- https://github.com/mlco2/codecarbon/blob/c6aebb9681186a71573748e381b6a3c9731de2d3/codecarbon/viz/data.py#L66 """ tv_time_in_minutes = emissions * (1 / 0.097) * 60 tv_time = "{:.0f} minutes".format(tv_time_in_minutes) if tv_time_in_minutes >= 60: time_in_hours = tv_time_in_minutes / 60 tv_time = "{:.0f} hours".format(time_in_hours) if time_in_hours >= 24: time_in_days = time_in_hours / 24 tv_time = "{:.0f} days".format(time_in_days) return tv_time
[docs]def load_and_compute_carbon_footprint_metrics(emissions_csv_file, nb_of_subjects_processed) -> dict: """Return a dictionary storing the different metrics and variables displayed in the carbon footprint report. The dictionary has the different fields: `'country_name'`, `'region_name'`, `'country_emissions_per_kwh'`, `'duration'`, `'energy_consumed'`, `'emissions'`, `'car_kms'`, `'tv_time'`, `'pred_energy_consumed'`, `'pred_emissions'`, `'pred_car_kms'`, `'pred_tv_time'`. Parameters ---------- emissions_csv_file : string Path to the `emissions.csv` file generated by `Codecarbon`. nb_of_subjects_processed : int Number of subject processed. """ emissions_df = pd.read_csv(emissions_csv_file) last_index = len(emissions_df) - 1 duration = emissions_df['duration'][last_index] energy_consumed = emissions_df['energy_consumed'][last_index] emissions = emissions_df['emissions'][last_index] country_name = emissions_df['country_name'][last_index] region_name = emissions_df['region'][last_index] del emissions_df country_emissions_per_kwh = float(emissions / energy_consumed) car_kms = get_emission_car_miles_equivalent(emissions) tv_time = get_emission_tv_time_equivalent(emissions) pred_duration = 100 * duration / nb_of_subjects_processed pred_energy_consumed = 100 * energy_consumed / nb_of_subjects_processed pred_emissions = 100 * emissions / nb_of_subjects_processed pred_car_kms = get_emission_car_miles_equivalent(pred_emissions) pred_tv_time = get_emission_tv_time_equivalent(pred_emissions) carbon_footprint_metrics = { 'country_name': f'{country_name}', 'region_name': f'{region_name}', 'country_emissions_per_kwh': f'{country_emissions_per_kwh}', 'duration': f'{duration}', 'energy_consumed': f'{energy_consumed}', 'emissions': f'{emissions}', 'car_kms': f'{car_kms}', 'tv_time': f'{tv_time}', 'pred_duration': f'{pred_duration}', 'pred_energy_consumed': f'{pred_energy_consumed}', 'pred_emissions': f'{pred_emissions}', 'pred_car_kms': f'{pred_car_kms}', 'pred_tv_time': f'{pred_tv_time}', } return carbon_footprint_metrics
[docs]def create_carbon_footprint_message(bids_dir, emissions_csv_file, nb_of_subjects_processed): """Return a string containg the carbon footprint print message to be passed to `print()`. Parameters ---------- bids_dir : string Path to root directory of the BIDS dataset emissions_csv_file : string Path to the `emissions.csv` file generated by `Codecarbon`. nb_of_subjects_processed : int Number of subject processed. Returns ------- carbon_footprint_msg : string String formatted containing the carbon footprint meassge to be passed to `print()` """ carbon_footprint_metrics = load_and_compute_carbon_footprint_metrics( emissions_csv_file=emissions_csv_file, nb_of_subjects_processed=nb_of_subjects_processed ) carbon_footprint_msg = "#" * 80 + "\n" carbon_footprint_msg += f"CARBON FOOTPRINT REPORT\n" carbon_footprint_msg += "#" * 80 + "\n" carbon_footprint_msg += "Carbon footprint results\n" carbon_footprint_msg += "-" * 80 + "\n" carbon_footprint_msg += f"Connectome Mapper ({__version__}) was run on {nb_of_subjects_processed} subject(s) " carbon_footprint_msg += f"in {carbon_footprint_metrics['region_name']} ({carbon_footprint_metrics['country_name']})" carbon_footprint_msg += f" (Mean CO<sub>2</sub> kg / kWH: {carbon_footprint_metrics['country_emissions_per_kwh']})," carbon_footprint_msg += " having the following estimated carbon footprint:\n" carbon_footprint_msg += f"\t* Duration: {carbon_footprint_metrics['duration']} s\n" carbon_footprint_msg += f"\t* Energy consumed: {carbon_footprint_metrics['energy_consumed']} kWh\n" carbon_footprint_msg += f"\t* Estimated Co2 emissions: {carbon_footprint_metrics['emissions']} kg\n" carbon_footprint_msg += "\t* Equivalent in distance travelled by " carbon_footprint_msg += f"avg car: {carbon_footprint_metrics['car_kms']} kms\n" carbon_footprint_msg += "\t* Equivalent in amount of time watching a 32-inch LCD flat " carbon_footprint_msg += f"screen TV: {carbon_footprint_metrics['tv_time']}\n" carbon_footprint_msg += "#" * 80 + "\n" carbon_footprint_msg += f"Carbon footprint prediction for 100 subjects in the same conditions\n" carbon_footprint_msg += "-" * 80 + "\n" carbon_footprint_msg += f"\t* Predicted duration: {carbon_footprint_metrics['pred_duration']} s\n" carbon_footprint_msg += f"\t* Predicted energy consumed: {carbon_footprint_metrics['pred_energy_consumed']} kWh\n" carbon_footprint_msg += f"\t* Predicted Co2 emissions: {carbon_footprint_metrics['pred_emissions']} kg\n" carbon_footprint_msg += "\t* Equivalent in distance travelled by " carbon_footprint_msg += f"avg car: {carbon_footprint_metrics['pred_car_kms']} kms\n" carbon_footprint_msg += "\t* Equivalent in amount of time watching a 32-inch LCD flat " carbon_footprint_msg += f"screen TV: {carbon_footprint_metrics['pred_tv_time']}\n" carbon_footprint_msg += "#" * 80 + "\n" carbon_footprint_msg += "Results can be visualized with the codecarbon visualization " carbon_footprint_msg += "tool using following command:\n\n" carbon_footprint_msg += f'\t$ carbonboard --filepath="{bids_dir}/code/emissions.csv" --port=9999\n' return carbon_footprint_msg
[docs]def create_html_carbon_footprint_report(emissions_csv_file, nb_of_subjects_processed): """Return a string containing the content of html report to be passed to traits `Str` with `HTMLEditor`. Parameters ---------- emissions_csv_file : string Path to the `emissions.csv` file generated by `Codecarbon`. nb_of_subjects_processed : int Number of subject processed. """ carbon_footprint_metrics = load_and_compute_carbon_footprint_metrics( emissions_csv_file=emissions_csv_file, nb_of_subjects_processed=nb_of_subjects_processed ) # Get path to different resources used in the <head> of the HTML document resources_dir = os.path.join('data', 'report', 'carbonfootprint') jquery_js_file = resource_filename('cmtklib', os.path.join(resources_dir, 'js', 'jquery.3.3.1.min.js')) bootstrap_css_file = resource_filename( 'cmtklib', os.path.join(resources_dir, 'css', 'bootstrap-combined.no-icons.min.css') ) return f""" <!DOCTYPE html> <html> <head> <title>Footer</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="{jquery_js_file}"></script> <link href="{bootstrap_css_file}" rel="stylesheet"> <script src="https://kit.fontawesome.com/d2ef6e0082.js" crossorigin="anonymous"></script> <style> div {{ border: 1px solid gray; padding: 8px; }} h1 {{ text-align: center; text-transform: uppercase; color: #4CAF50; }} p {{ margin: 0px 10px 0px 10px; padding: 10px 10px 10px 10px; text-indent: 0px; text-align: justify; background-color: #EEEEEE; }} a {{ text-decoration: none; color: #008CBA; }} #footer {{ border: 0px solid gray; padding: 8px; }} #GFG {{ border: 0px solid gray; padding: 8px; height: 60px; text-align: center; padding: 3px; color: white; background-image: url(https://ohbm-environment.org/wp-content/uploads/slider/cache/aceabfbee23a7b3e8e9fed910c639555/Borneo_rainforest-3.jpg); background-position: center center; background-repeat: no-repeat; background-size: cover; }} .fa-brain{{ color: pink; font-size: 1em; margin: 0px 10px 0px 10px; vertical-align: middle; horizontal-align: left; }} </style> </head> <body> <div id="GFG"> </div> <div> <h4> Carbon footprint results </h4> <p> Connectome Mapper ({__version__}) was run on {nb_of_subjects_processed} subject(s) in {carbon_footprint_metrics['region_name']} ({carbon_footprint_metrics['country_name']}) (Mean CO<sub>2</sub> kg / kWH: {carbon_footprint_metrics['country_emissions_per_kwh']}), having the following estimated carbon footprint: </p> <ul> <li>Total run time: {carbon_footprint_metrics['duration']}s </li> <li>Total energy consumed: {carbon_footprint_metrics['energy_consumed']} kWh </li> <li>Total estimated CO<sub>2</sub> emissions: {carbon_footprint_metrics['emissions']} kg </li> <li> Equivalent in distance travelled by avg <i class="fas fa-car"></i>: {carbon_footprint_metrics['car_kms']} kms </li> <li> Equivalent in amount of time watching a 32-inch LCD flat screen <i class="fas fa-tv"></i>: {carbon_footprint_metrics['tv_time']} </li> </ul> <p> <em> Estimations were conducted using the <a href="https://github.com/mlco2/codecarbon">CodeCarbon emissions tracker</a>. </em> </p> <h4> Carbon footprint prediction for 100 subjects </h4> <p> In the same conditions, this would have resulted in: </p> <ul> <li>Total run time: {carbon_footprint_metrics['pred_duration']}s </li> <li>Total energy consumed: {carbon_footprint_metrics['pred_energy_consumed']} kWh </li> <li>Co2 emissions: {carbon_footprint_metrics['pred_emissions']} kg</li> <li> Equivalent in distance travelled by avg <i class="fas fa-car"></i>: {carbon_footprint_metrics['pred_car_kms']} kms </li> <li> Equivalent in amount of time watching a 32-inch LCD flat screen <i class="fas fa-tv"></i>: {carbon_footprint_metrics['pred_tv_time']} </li> </ul> </div> </body> <footer> <div id="footer"> <p> Actively part of the initiative created by the <a href="https://neuropipelines.github.io/20pipelines"> Sustainability and Environment Action Special Interest Group</a>, the CMP developers hope that by providing you with such metrics it can allow you to be more aware about the carbon footprint of your<i class="fas fa-brain" aria-hidden= "true"></i>research. &#127757; &#10024; </p> </div> </footer> <html> """