Exemplo n.º 1
0
class Data:
    def __init__(self):
        self._data_source = DataSource()
        self._emissions = Emissions(self._data_source)

    @staticmethod
    def get_project_data(df: pd.DataFrame, project_name) -> dt.DataTable:
        project_df = df[df.project_name == project_name]
        project_df = project_df.sort_values(by="timestamp")
        project_data = project_df.to_dict("rows")
        columns = [{
            "name": column,
            "id": column
        } for column in project_df.columns]
        return dt.DataTable(data=project_data, columns=columns)

    @staticmethod
    def get_project_summary(project_data: List[Dict]):
        last_run = project_data[-1]
        project_summary = {
            "last_run": {
                "timestamp": last_run["timestamp"],
                "duration": last_run["duration"],
                "emissions": round(last_run["emissions"], 1),
                "energy_consumed": round((last_run["energy_consumed"]), 1),
            },
            "total": {
                "duration":
                sum(
                    map(lambda experiment: experiment["duration"],
                        project_data)),
                "emissions":
                round(
                    sum(
                        map(lambda experiment: experiment["emissions"],
                            project_data)),
                    1,
                ),
                "energy_consumed":
                round(
                    sum(
                        map(
                            lambda experiment: experiment["energy_consumed"],
                            project_data,
                        )),
                    1,
                ),
            },
            "country_name": last_run["country_name"],
            "country_iso_code": last_run["country_iso_code"],
            "region": last_run["region"],
            "on_cloud": last_run["on_cloud"],
            "cloud_provider": last_run["cloud_provider"],
            "cloud_region": last_run["cloud_region"],
        }
        return project_summary

    def get_car_miles(self, project_carbon_equivalent: float):
        """
        8.89 × 10-3 metric tons CO2/gallon gasoline ×
        1/22.0 miles per gallon car/truck average ×
        1 CO2, CH4, and N2O/0.988 CO2
        = 4.09 x 10-4 metric tons CO2E/mile
        = 0.409 kg CO2E/mile
        Source: EPA
        :param project_carbon_equivalent: total project emissions in kg CO2E
        :return: number of miles driven by avg car
        """
        return "{:.0f}".format(project_carbon_equivalent / 0.409)

    def get_tv_time(self, project_carbon_equivalent: float):
        """
        Gives the amount of time
        a 32-inch LCD flat screen TV will emit
        an equivalent amount of carbon
        Ratio is 0.097 kg CO2 / 1 hour tv
        :param project_carbon_equivalent: total project emissions in kg CO2E
        :return: equivalent TV time
        """
        time_in_minutes = project_carbon_equivalent * (1 / 0.097) * 60
        formated_value = "{:.0f} minutes".format(time_in_minutes)
        if time_in_minutes >= 60:
            time_in_hours = time_in_minutes / 60
            formated_value = "{:.0f} hours".format(time_in_hours)
            if time_in_hours >= 24:
                time_in_days = time_in_hours / 24
                formated_value = "{:.0f} days".format(time_in_days)
        return formated_value

    def get_household_fraction(self, project_carbon_equivalent: float):
        """
        Total CO2 emissions for energy use per home: 5.734 metric tons CO2 for electricity
        + 2.06 metric tons CO2 for natural gas + 0.26 metric tons CO2 for liquid petroleum gas
         + 0.30 metric tons CO2 for fuel oil  = 8.35 metric tons CO2 per home per year / 52 weeks
         = 160.58 kg CO2/week on average
        Source: EPA
        :param project_carbon_equivalent: total project emissions in kg CO2E
        :return: % of weekly emissions re: an average American household
        """
        return "{:.2f}".format((project_carbon_equivalent / 160.58) * 100)

    def get_global_emissions_choropleth_data(
            self, net_energy_consumed: float) -> List[Dict]:
        def formatted_energy_percentage(energy_type: float,
                                        total: float) -> float:
            return float("{:.1f}".format((energy_type / total) * 100))

        global_energy_mix = self._data_source.get_global_energy_mix_data()
        choropleth_data = []
        for country_iso_code in global_energy_mix.keys():
            country_name = global_energy_mix[country_iso_code]["countryName"]

            if country_iso_code not in ["_define", "ATA"]:
                from codecarbon.core.units import Energy

                energy_consumed = Energy.from_energy(kwh=net_energy_consumed)

                from codecarbon.external.geography import GeoMetadata

                country_emissions = self._emissions.get_country_emissions(
                    energy_consumed,
                    GeoMetadata(country_name=country_name,
                                country_iso_code=country_iso_code),
                )
                total = global_energy_mix[country_iso_code]["total"]
                choropleth_data.append({
                    "iso_code":
                    country_iso_code,
                    "emissions":
                    country_emissions,
                    "country":
                    country_name,
                    "coal":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["coal"], total),
                    "petroleum":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["petroleum"],
                        total),
                    "natural_gas":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["naturalGas"],
                        total),
                    "low_carbon":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["lowCarbon"],
                        total),
                })
        return choropleth_data

    def get_regional_emissions_choropleth_data(
            self, net_energy_consumed: float,
            country_iso_code: str) -> List[Dict]:

        # add country codes here to render for different countries
        if country_iso_code.upper() not in ["USA"]:
            return [{"region_code": "", "region_name": "", "emissions": ""}]

        region_emissions = self._data_source.get_country_emissions_data(
            country_iso_code.lower())
        choropleth_data = []
        for region_name in region_emissions.keys():

            region_code = region_emissions[region_name]["regionCode"]
            if region_name not in ["_unit"]:
                from codecarbon.core.units import Energy

                energy_consumed = Energy.from_energy(kwh=net_energy_consumed)

                from codecarbon.external.geography import GeoMetadata

                emissions = self._emissions.get_region_emissions(
                    energy_consumed,
                    GeoMetadata(country_iso_code=country_iso_code,
                                region=region_name),
                )

                choropleth_data.append({
                    "region_code": region_code,
                    "region_name": region_name.upper(),
                    "emissions": emissions,
                })
        return choropleth_data

    def get_cloud_emissions_barchart_data(
        self,
        net_energy_consumed: float,
        on_cloud: str,
        cloud_provider: str,
        cloud_region: str,
    ) -> Tuple[str, pd.DataFrame]:
        if on_cloud == "N":
            return (
                "",
                pd.DataFrame(data={
                    "region": [],
                    "emissions": [],
                    "countryName": []
                }),
            )
        cloud_emissions = self._data_source.get_cloud_emissions_data()
        cloud_emissions = cloud_emissions[[
            "provider", "providerName", "region", "impact", "countryName"
        ]]

        from codecarbon.core.units import EmissionsPerKwh

        cloud_emissions["emissions"] = cloud_emissions.apply(
            lambda row: EmissionsPerKwh.from_g_per_kwh(row.impact).kgs_per_kwh
            * net_energy_consumed,
            axis=1,
        )

        cloud_emissions_project_region = cloud_emissions[cloud_emissions.region
                                                         == cloud_region]
        cloud_emissions = cloud_emissions[
            (cloud_emissions.provider == cloud_provider)
            & (cloud_emissions.region != cloud_region)].sort_values(
                by="emissions")

        return (
            cloud_emissions_project_region.iloc[0, :].providerName,
            pd.concat([cloud_emissions_project_region, cloud_emissions]),
        )
Exemplo n.º 2
0
class Data:
    def __init__(self):
        self._data_source = DataSource()
        self._emissions = Emissions(self._data_source)

    @staticmethod
    def get_project_data(df: pd.DataFrame, project_name) -> dt.DataTable:
        project_df = df[df.project_name == project_name]
        project_df = project_df.sort_values(by="timestamp")
        project_data = project_df.to_dict("rows")
        columns = [{
            "name": column,
            "id": column
        } for column in project_df.columns]
        return dt.DataTable(data=project_data, columns=columns)

    @staticmethod
    def get_project_summary(project_data: List[Dict]):
        last_run = project_data[-1]
        project_summary = {
            "last_run": {
                "timestamp": last_run["timestamp"],
                "duration": last_run["duration"],
                "emissions": round(last_run["emissions"], 1),
                "energy_consumed": round((last_run["energy_consumed"]), 1),
            },
            "total": {
                "duration":
                sum(
                    map(lambda experiment: experiment["duration"],
                        project_data)),
                "emissions":
                sum(
                    map(lambda experiment: experiment["emissions"],
                        project_data)),
                "energy_consumed":
                sum(
                    map(lambda experiment: experiment["energy_consumed"],
                        project_data)),
            },
            "country_name": last_run["country_name"],
            "country_iso_code": last_run["country_iso_code"],
            "region": last_run["region"],
            "on_cloud": last_run["on_cloud"],
            "cloud_provider": last_run["cloud_provider"],
            "cloud_region": last_run["cloud_region"],
        }
        return project_summary

    def get_car_miles(self, project_carbon_equivalent: float):
        """
        8.89 × 10-3 metric tons CO2/gallon gasoline ×
        1/22.0 miles per gallon car/truck average ×
        1 CO2, CH4, and N2O/0.988 CO2
        = 4.09 x 10-4 metric tons CO2E/mile
        = 0.409 kg CO2E/mile
        Source: EPA
        :param project_carbon_equivalent: total project emissions in kg CO2E
        :return: number of miles driven by avg car
        """
        return "{:.0f}".format(project_carbon_equivalent / 0.409)

    def get_tv_time(self, project_carbon_equivalent: float):
        """
        Gives the amount of time
        a 32-inch LCD flat screen TV will emit
        an equivalent amount of carbon
        Ratio is 0.097 kg CO2 / 1 hour tv
        :param project_carbon_equivalent: total project emissions in kg CO2E
        :return: equivalent TV time
        """
        time_in_minutes = project_carbon_equivalent * (1 / 0.097) * 60
        formated_value = "{:.0f} minutes".format(time_in_minutes)
        if time_in_minutes >= 60:
            time_in_hours = time_in_minutes / 60
            formated_value = "{:.0f} hours".format(time_in_hours)
            if time_in_hours >= 24:
                time_in_days = time_in_hours / 24
                formated_value = "{:.0f} days".format(time_in_days)
        return formated_value

    def get_household_fraction(self, project_carbon_equivalent: float):
        """
        Total CO2 emissions for energy use per home: 5.734 metric tons CO2 for electricity
        + 2.06 metric tons CO2 for natural gas + 0.26 metric tons CO2 for liquid petroleum gas
         + 0.30 metric tons CO2 for fuel oil  = 8.35 metric tons CO2 per home per year / 52 weeks
         = 160.58 kg CO2/week on average
        Source: EPA
        :param project_carbon_equivalent: total project emissions in kg CO2E
        :return: % of weekly emissions re: an average American household
        """
        return "{:.2f}".format((project_carbon_equivalent / 160.58) * 100)

    def get_global_emissions_choropleth_data(
            self, net_energy_consumed: float) -> List[Dict]:
        def formatted_energy_percentage(energy_type: float,
                                        total: float) -> float:
            return float("{:.1f}".format((energy_type / total) * 100))

        global_energy_mix = self._data_source.get_global_energy_mix_data()
        choropleth_data = []
        for country_iso_code in global_energy_mix.keys():
            country_name = global_energy_mix[country_iso_code]["country_name"]

            if country_iso_code not in ["_define", "ATA"]:
                from codecarbon.core.units import Energy

                energy_consumed = Energy.from_energy(kWh=net_energy_consumed)

                from codecarbon.external.geography import GeoMetadata

                country_emissions = self._emissions.get_country_emissions(
                    energy_consumed,
                    GeoMetadata(country_name=country_name,
                                country_iso_code=country_iso_code),
                )
                total = global_energy_mix[country_iso_code]["total_TWh"]
                choropleth_data.append({
                    "iso_code":
                    country_iso_code,
                    "emissions":
                    country_emissions,
                    "country":
                    country_name,
                    "fossil":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["fossil_TWh"],
                        total),
                    "geothermal":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["geothermal_TWh"],
                        total),
                    "hydroelectricity":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]
                        ["hydroelectricity_TWh"],
                        total,
                    ),
                    "nuclear":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["nuclear_TWh"],
                        total),
                    "solar":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["solar_TWh"],
                        total),
                    "wind":
                    formatted_energy_percentage(
                        global_energy_mix[country_iso_code]["wind_TWh"],
                        total),
                })
        return choropleth_data

    def get_regional_emissions_choropleth_data(
            self, net_energy_consumed: float,
            country_iso_code: str) -> List[Dict]:

        # add country codes here to render for different countries
        if country_iso_code.upper() not in ["USA", "CAN"]:
            return [{"region_code": "", "region_name": "", "emissions": ""}]

        try:
            region_emissions = self._data_source.get_country_emissions_data(
                country_iso_code.lower())
        except DataSourceException:  # This country has regional data at the energy mix level, not the emissions level
            country_energy_mix = self._data_source.get_country_energy_mix_data(
                country_iso_code.lower())
            region_emissions = {
                region: {
                    "regionCode": region
                }
                for region, energy_mix in country_energy_mix.items()
            }
        choropleth_data = []
        for region_name in region_emissions.keys():

            region_code = region_emissions[region_name]["regionCode"]
            if region_name not in ["_unit"]:
                from codecarbon.core.units import Energy

                energy_consumed = Energy.from_energy(kWh=net_energy_consumed)

                from codecarbon.external.geography import GeoMetadata

                emissions = self._emissions.get_region_emissions(
                    energy_consumed,
                    GeoMetadata(country_iso_code=country_iso_code,
                                region=region_name),
                )

                choropleth_data.append({
                    "region_code": region_code,
                    "region_name": region_name.upper(),
                    "emissions": emissions,
                })
        return choropleth_data

    def get_cloud_emissions_barchart_data(
        self,
        net_energy_consumed: float,
        on_cloud: str,
        cloud_provider: str,
        cloud_region: str,
    ) -> Tuple[str, pd.DataFrame]:
        if on_cloud == "N":
            return (
                "",
                pd.DataFrame(data={
                    "region": [],
                    "emissions": [],
                    "country_name": []
                }),
            )
        cloud_emissions = self._data_source.get_cloud_emissions_data()
        cloud_emissions = cloud_emissions[[
            "provider", "providerName", "region", "impact", "country_name"
        ]]

        from codecarbon.core.units import EmissionsPerKWh

        cloud_emissions["emissions"] = cloud_emissions.apply(
            lambda row: EmissionsPerKWh.from_g_per_kWh(row.impact).kgs_per_kWh
            * net_energy_consumed,
            axis=1,
        )

        cloud_emissions_project_region = cloud_emissions[cloud_emissions.region
                                                         == cloud_region]
        cloud_emissions = cloud_emissions[
            (cloud_emissions.provider == cloud_provider)
            & (cloud_emissions.region != cloud_region)].sort_values(
                by="emissions")

        return (
            cloud_emissions_project_region.iloc[0, :].providerName,
            pd.concat([cloud_emissions_project_region, cloud_emissions]),
        )

    @staticmethod
    def get_data_from_api(host):
        transformed_projects = []
        project_list = Data.list_projects(host)
        for project in project_list:
            project_sum_by_experiments_url = (
                host + "/experiments/{project_id}/detailed_sums".format(
                    project_id=project["id"]))
            project_name = project["name"]
            sums = requests.get(project_sum_by_experiments_url).json()
            for experiment in sums:
                experiment["project_name"] = project_name
                # experiment["emission_rate"] = 0
                # if experiment["emissions_count"] > 0:
                #     experiment["emission_rate"] = (
                #         experiment["emissions_rate"] / experiment["emissions_count"]
                #     )
                transformed_projects.append(experiment)
        df_projects = pd.DataFrame(transformed_projects)
        return df_projects

    @staticmethod
    def list_projects(host):
        projects = []
        teams_url = host + "/teams"
        teams = requests.get(teams_url).json()
        for team in teams:
            projets_url = host + "/projects/team/{team_id}".format(
                team_id=team["id"])
            team_projects = requests.get(projets_url).json()
            if team_projects:
                projects.append(
                    list(
                        map(
                            lambda x: {
                                "id": x["id"],
                                "name": x["name"]
                            },
                            iter(team_projects),
                        )))
        project_list = sum(projects, [])
        return project_list