Repository: mlco2/codecarbon (language: python)

Issue:
Separate CPU and GPU consumption in emissions output
* CodeCarbon version: 1.2.0
* Python version: 3.6
* Operating System: MAC

### Description

At the moment total energy contains the sum of all energy consumed by the CPU and GPU and it's the only measure that exist in the output results. It would be best to store the CPU and GPU consumption separately as well.






Discussion / hints:
I have couple of questions around this:

1. I have added 2 measures called cpu_power and gpu_power in the package inside`emission_tracker` . Should they be in Kwh as well? (Also, let me know if the naming is good). This is how I calculated it: 
```           
           energy = Energy.from_power_and_time(
                power=hardware.total_power(), time=Time.from_seconds(last_duration)
            )
            self._total_energy += energy
            if isinstance(hardware, CPU):
                self._total_cpu_power += energy
            if isinstance(hardware, GPU):
                self._total_gpu_power += energy
```
2. I noticed that for the file output mode, if the file exists we append data. This would create inconsistencies because we add two columns in the header with this change. Do you guys have any idea on how this can be handeled? Is it okay to override the file if the header does not include the two new columns?
Looks good to me. We may rename in '.bak' the existing file if in wrong format ?
To me too :) 

WRT 2. I think we could create a new one? Or rename the previous one?
As we're adding sources of information, maybe it would be worth having `self._total_power` as a dictionary? And then have something like `total_power = sum(self._total_power.values())`

Fix patch:
diff --git a/carbonserver/carbonserver/api/infra/database/sql_models.py b/carbonserver/carbonserver/api/infra/database/sql_models.py
index aad022dbb..9968e29c4 100644
--- a/carbonserver/carbonserver/api/infra/database/sql_models.py
+++ b/carbonserver/carbonserver/api/infra/database/sql_models.py
@@ -13,7 +13,14 @@ class Emission(Base):
     id = Column(UUID(as_uuid=True), primary_key=True, index=True, default=uuid.uuid4)
     timestamp = Column(DateTime)
     duration = Column(Float)
-    emissions = Column(Float)
+    emissions_sum = Column(Float)
+    emissions_rate = Column(Float)
+    cpu_power = Column(Float)
+    gpu_power = Column(Float)
+    ram_power = Column(Float)
+    cpu_energy = Column(Float)
+    gpu_energy = Column(Float)
+    ram_energy = Column(Float)
     energy_consumed = Column(Float)
     run_id = Column(UUID(as_uuid=True), ForeignKey("runs.id"))
     run = relationship("Run", back_populates="emissions")
@@ -22,7 +29,7 @@ def __repr__(self):
         return (
             f'<Emission(id="{self.id}", '
             f'timestamp="{self.timestamp}", '
-            f'emissions="{self.emissions}", '
+            f'emissions_rate="{self.emissions_rate}", '
             f'run_id="{self.run_id}")>'
         )
 
diff --git a/carbonserver/carbonserver/api/infra/repositories/repository_emissions.py b/carbonserver/carbonserver/api/infra/repositories/repository_emissions.py
index 83f54f779..4e5b78e73 100644
--- a/carbonserver/carbonserver/api/infra/repositories/repository_emissions.py
+++ b/carbonserver/carbonserver/api/infra/repositories/repository_emissions.py
@@ -30,7 +30,14 @@ def add_emission(self, emission: schemas.EmissionCreate):
                 id=uuid4(),
                 timestamp=emission.timestamp,
                 duration=emission.duration,
-                emissions=emission.emissions,
+                emissions_sum=emission.emissions_sum,
+                emissions_rate=emission.emissions_rate,
+                cpu_power=emission.cpu_power,
+                gpu_power=emission.gpu_power,
+                ram_power=emission.ram_power,
+                cpu_energy=emission.cpu_energy,
+                gpu_energy=emission.gpu_energy,
+                ram_energy=emission.ram_energy,
                 energy_consumed=emission.energy_consumed,
                 run_id=emission.run_id,
             )
@@ -89,7 +96,14 @@ def map_sql_to_schema(emission: sql_models.Emission) -> schemas.Emission:
             id=emission.id,
             timestamp=emission.timestamp,
             duration=emission.duration,
-            emissions=emission.emissions,
+            emissions_sum=emission.emissions_sum,
+            emissions_rate=emission.emissions_rate,
+            cpu_power=emission.cpu_power,
+            gpu_power=emission.gpu_power,
+            ram_power=emission.ram_power,
+            cpu_energy=emission.cpu_energy,
+            gpu_energy=emission.gpu_energy,
+            ram_energy=emission.ram_energy,
             energy_consumed=emission.energy_consumed,
             run_id=emission.run_id,
         )
diff --git a/carbonserver/carbonserver/api/schemas.py b/carbonserver/carbonserver/api/schemas.py
index a5b3c73f5..aa91808a4 100644
--- a/carbonserver/carbonserver/api/schemas.py
+++ b/carbonserver/carbonserver/api/schemas.py
@@ -21,12 +21,21 @@ class EmissionBase(BaseModel):
     duration: int = Field(
         ..., gt=0, description="The duration must be greater than zero"
     )
-    emissions: float = Field(
-        ..., gt=0, description="The emissions must be greater than zero"
+    emissions_sum: float = Field(
+        ..., ge=0, description="The emissions must be greater than zero"
+    )
+    emissions_rate: float = Field(
+        ..., ge=0, description="The emissions rate must be greater than zero"
     )
     energy_consumed: float = Field(
         ..., gt=0, description="The energy_consumed must be greater than zero"
     )
+    cpu_power: float
+    gpu_power: float
+    ram_power: float
+    cpu_energy: float
+    gpu_energy: float
+    ram_energy: float
 
     class Config:
         schema_extra = {
@@ -34,7 +43,14 @@ class Config:
                 "timestamp": "2021-04-04T08:43:00+02:00",
                 "run_id": "40088f1a-d28e-4980-8d80-bf5600056a14",
                 "duration": 98745,
-                "emissions": 1.548444,
+                "emissions_sum": 1544.54,
+                "emissions_rate": 1.548444,
+                "cpu_power": 0.3,
+                "gpu_power": 0.0,
+                "ram_power": 0.15,
+                "cpu_energy": 55.21874,
+                "gpu_energy": 0.0,
+                "ram_energy": 2.0,
                 "energy_consumed": 57.21874,
             }
         }
diff --git a/carbonserver/carbonserver/database/alembic/versions/f12747ed7e9c_seperate_cpu_and_gpu_energy_values.py b/carbonserver/carbonserver/database/alembic/versions/f12747ed7e9c_seperate_cpu_and_gpu_energy_values.py
new file mode 100644
index 000000000..c85929ef7
--- /dev/null
+++ b/carbonserver/carbonserver/database/alembic/versions/f12747ed7e9c_seperate_cpu_and_gpu_energy_values.py
@@ -0,0 +1,37 @@
+"""seperate cpu and gpu energy values
+
+Revision ID: f12747ed7e9c
+Revises: 73a394753d3a
+Create Date: 2021-07-07 14:27:19.702460
+
+"""
+import sqlalchemy as sa
+from alembic import op
+
+# revision identifiers, used by Alembic.
+revision = "f12747ed7e9c"
+down_revision = "73a394753d3a"
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    op.add_column("emissions", sa.Column("cpu_power", sa.Float))
+    op.add_column("emissions", sa.Column("gpu_power", sa.Float))
+    op.add_column("emissions", sa.Column("ram_power", sa.Float))
+    op.add_column("emissions", sa.Column("cpu_energy", sa.Float))
+    op.add_column("emissions", sa.Column("gpu_energy", sa.Float))
+    op.add_column("emissions", sa.Column("ram_energy", sa.Float))
+    op.add_column("emissions", sa.Column("emissions_rate", sa.Float))
+    op.alter_column("emissions", "emissions", new_column_name="emissions_sum")
+
+
+def downgrade():
+    op.drop_column("emissions", "cpu_power")
+    op.drop_column("emissions", "gpu_power")
+    op.drop_column("emissions", "ram_power")
+    op.drop_column("emissions", "cpu_energy")
+    op.drop_column("emissions", "gpu_energy")
+    op.drop_column("emissions", "ram_energy")
+    op.drop_column("emissions", "emissions_rate")
+    op.alter_column("emissions", "emissions_sum", new_column_name="emissions")
diff --git a/codecarbon/core/api_client.py b/codecarbon/core/api_client.py
index e0265f051..8e20e256f 100644
--- a/codecarbon/core/api_client.py
+++ b/codecarbon/core/api_client.py
@@ -65,7 +65,14 @@ def add_emission(self, carbon_emission: dict):
             timestamp=get_datetime_with_timezone(),
             run_id=self.run_id,
             duration=int(carbon_emission["duration"]),
-            emissions=carbon_emission["emissions"],
+            emissions_sum=carbon_emission["emissions"],
+            emissions_rate=carbon_emission["emissions_rate"],
+            cpu_power=carbon_emission["cpu_power"],
+            gpu_power=carbon_emission["gpu_power"],
+            ram_power=carbon_emission["ram_power"],
+            cpu_energy=carbon_emission["cpu_energy"],
+            gpu_energy=carbon_emission["gpu_energy"],
+            ram_energy=carbon_emission["ram_energy"],
             energy_consumed=carbon_emission["energy_consumed"],
         )
         try:
diff --git a/codecarbon/core/emissions.py b/codecarbon/core/emissions.py
index d2a902fa1..dc1958a98 100644
--- a/codecarbon/core/emissions.py
+++ b/codecarbon/core/emissions.py
@@ -157,6 +157,9 @@ def get_country_emissions(self, energy: Energy, geo: GeoMetadata) -> float:
 
         country_energy_mix: Dict = energy_mix[geo.country_iso_code]
         emissions_per_kwh = self._energy_mix_to_emissions_rate(country_energy_mix)
+        logger.debug(
+            f"We apply an energy mix of {emissions_per_kwh.kgs_per_kwh:.6f} Kg.CO2eq/kWh for {geo.country_name}"
+        )
         return emissions_per_kwh.kgs_per_kwh * energy.kwh  # kgs
 
     @staticmethod
diff --git a/codecarbon/core/schemas.py b/codecarbon/core/schemas.py
index bfd05c8da..de8ef3919 100644
--- a/codecarbon/core/schemas.py
+++ b/codecarbon/core/schemas.py
@@ -12,7 +12,14 @@ class EmissionBase:
     timestamp: str
     run_id: str
     duration: int
-    emissions: float
+    emissions_sum: float
+    emissions_rate: float
+    cpu_power: float
+    gpu_power: float
+    ram_power: float
+    cpu_energy: float
+    gpu_energy: float
+    ram_energy: float
     energy_consumed: float
 
 
diff --git a/codecarbon/core/units.py b/codecarbon/core/units.py
index 4c1cc3fe3..a60b86142 100644
--- a/codecarbon/core/units.py
+++ b/codecarbon/core/units.py
@@ -89,6 +89,9 @@ def W(self):
             return self.kW
         return self.kW * 1000
 
+    def __add__(self, other: "Power") -> "Power":
+        return Power(self.kW + other.kW)
+
 
 @dataclass
 class Time:
diff --git a/codecarbon/emissions_tracker.py b/codecarbon/emissions_tracker.py
index d769bff63..498879890 100644
--- a/codecarbon/emissions_tracker.py
+++ b/codecarbon/emissions_tracker.py
@@ -15,7 +15,7 @@
 from codecarbon.core import cpu, gpu
 from codecarbon.core.config import get_hierarchical_config, parse_gpu_ids
 from codecarbon.core.emissions import Emissions
-from codecarbon.core.units import Energy, Time
+from codecarbon.core.units import Energy, Power, Time
 from codecarbon.core.util import set_log_level, suppress
 from codecarbon.external.geography import CloudMetadata, GeoMetadata
 from codecarbon.external.hardware import CPU, GPU, RAM
@@ -199,8 +199,14 @@ def __init__(
         self._start_time: Optional[float] = None
         self._last_measured_time: float = time.time()
         self._total_energy: Energy = Energy.from_energy(kwh=0)
+        self._total_cpu_energy: Energy = Energy.from_energy(kwh=0)
+        self._total_gpu_energy: Energy = Energy.from_energy(kwh=0)
+        self._total_ram_energy: Energy = Energy.from_energy(kwh=0)
+        self._cpu_power: Power = Power.from_watts(watts=0)
+        self._gpu_power: Power = Power.from_watts(watts=0)
+        self._ram_power: Power = Power.from_watts(watts=0)
         self._scheduler = BackgroundScheduler()
-        self._hardware = [RAM(self._tracking_mode)]
+        self._hardware = [RAM(tracking_mode=self._tracking_mode)]
         self._conf["hardware"] = []
         self._cc_api__out = None
         self._measure_occurrence: int = 0
@@ -269,7 +275,7 @@ def __init__(
             self.persistence_objs.append(HTTPOutput(emissions_endpoint))
 
         if self._save_to_api:
-            experiment_id = self._get_conf(
+            experiment_id = self._set_from_conf(
                 experiment_id, "experiment_id", "5b0fa12a-3dd7-45bb-9766-cc326314d9f1"
             )
             self._cc_api__out = CodeCarbonAPIOutput(
@@ -346,12 +352,18 @@ def _prepare_emissions_data(self, delta=False) -> EmissionsData:
             on_cloud = "Y"
             cloud_provider = cloud.provider
             cloud_region = cloud.region
-        logger.debug(f"emissions={emissions}")
         total_emissions = EmissionsData(
             timestamp=datetime.now().strftime("%Y-%m-%dT%H:%M:%S"),
             project_name=self._project_name,
             duration=duration.seconds,
             emissions=emissions,
+            emissions_rate=emissions * 1000 / duration.seconds,
+            cpu_power=self._cpu_power.W,
+            gpu_power=self._gpu_power.W,
+            ram_power=self._ram_power.W,
+            cpu_energy=self._total_cpu_energy.kwh,
+            gpu_energy=self._total_gpu_energy.kwh,
+            ram_energy=self._total_ram_energy.kwh,
             energy_consumed=self._total_energy.kwh,
             country_name=country_name,
             country_iso_code=country_iso_code,
@@ -363,18 +375,17 @@ def _prepare_emissions_data(self, delta=False) -> EmissionsData:
         if delta:
             if self._previous_emissions is None:
                 self._previous_emissions = total_emissions
-                return total_emissions
             else:
                 # Create a copy
                 delta_emissions = dataclasses.replace(total_emissions)
-                # Compute delta
-                delta_emissions.substract_in_place(self._previous_emissions)
+                # Compute emissions rate from delta
+                delta_emissions.compute_emissions_rate(self._previous_emissions)
                 # TODO : find a way to store _previous_emissions only when
                 # TODO : the API call succeded
                 self._previous_emissions = total_emissions
-                return delta_emissions
-        else:
-            return total_emissions
+                total_emissions = delta_emissions
+        logger.debug(total_emissions)
+        return total_emissions
 
     @abstractmethod
     def _get_geo_metadata(self) -> GeoMetadata:
@@ -407,21 +418,36 @@ def _measure_power(self) -> None:
             logger.warning(warn_msg, last_duration)
 
         for hardware in self._hardware:
-            self._total_energy += Energy.from_power_and_time(
+            energy = Energy.from_power_and_time(
                 power=hardware.total_power(), time=Time.from_seconds(last_duration)
             )
-            logger.info(
-                "Energy consumed for all "
-                + f"{hardware.__class__.__name__} : {self._total_energy.kwh:.6f} kWh"
-            )
+            self._total_energy += energy
+            if isinstance(hardware, CPU):
+                self._total_cpu_energy += energy
+                self._cpu_power = hardware.total_power()
+            if isinstance(hardware, GPU):
+                self._total_gpu_energy += energy
+                self._gpu_power = hardware.total_power()
+            if isinstance(hardware, RAM):
+                self._total_ram_energy += energy
+                self._ram_power = hardware.total_power()
+
             logger.debug(
-                f"\n={hardware.total_power()} power x {Time.from_seconds(last_duration)}"
+                f"{hardware.__class__.__name__} : {hardware.total_power().W:,.2f} W during {last_duration:,.2f} s"
             )
+        logger.info(
+            f"{self._total_energy.kwh:.6f} kWh of electricity used since the begining."
+        )
         self._last_measured_time = time.time()
         self._measure_occurrence += 1
         if self._cc_api__out is not None:
             if self._measure_occurrence >= self._api_call_interval:
-                self._cc_api__out.out(self._prepare_emissions_data(delta=True))
+                emissions = self._prepare_emissions_data(delta=True)
+                logger.info(
+                    f"{emissions.emissions_rate:.6f} g.CO2eq/s mean an estimation of "
+                    + f"{emissions.emissions_rate*3600*24*365:,} Kg.CO2eq/year"
+                )
+                self._cc_api__out.out(emissions)
                 self._measure_occurrence = 0
 
     def __enter__(self):
diff --git a/codecarbon/output.py b/codecarbon/output.py
index 69ea6f242..0da9e0d0b 100644
--- a/codecarbon/output.py
+++ b/codecarbon/output.py
@@ -21,13 +21,19 @@
 class EmissionsData:
     """
     Output object containg experiment data
-    # TODO : Replace by a pdantic BaseModel ?
     """
 
     timestamp: str
     project_name: str
     duration: float
     emissions: float
+    emissions_rate: float
+    cpu_power: float
+    gpu_power: float
+    ram_power: float
+    cpu_energy: float
+    gpu_energy: float
+    ram_energy: float
     energy_consumed: float
     country_name: str
     country_iso_code: str
@@ -44,6 +50,16 @@ def substract_in_place(self, previous_emission):
         self.duration = self.duration - previous_emission.duration
         self.emissions = self.emissions - previous_emission.emissions
         self.energy_consumed = self.energy_consumed - previous_emission.energy_consumed
+        self.emissions_rate = (self.emissions * 1000 / self.duration,)
+
+    def compute_emissions_rate(self, previous_emission):
+        delta_duration = self.duration - previous_emission.duration
+        delta_emissions = self.emissions - previous_emission.emissions
+        # delta_emissions in Kg.CO2/s * 1000 / duration in seconds = g.CO2/s
+        if delta_duration > 0:
+            self.emissions_rate = delta_emissions * 1000 / delta_duration
+        else:
+            self.emissions_rate = 0
 
 
 class BaseOutput(ABC):
@@ -66,8 +82,19 @@ class FileOutput(BaseOutput):
     def __init__(self, save_file_path: str):
         self.save_file_path: str = save_file_path
 
+    def has_valid_headers(self, data: EmissionsData):
+        with open(self.save_file_path) as csv_file:
+            csv_reader = csv.DictReader(csv_file)
+            dict_from_csv = dict(list(csv_reader)[0])
+            list_of_column_names = list(dict_from_csv.keys())
+            return list(data.values.keys()) == list_of_column_names
+
     def out(self, data: EmissionsData):
         file_exists: bool = os.path.isfile(self.save_file_path)
+        if file_exists and not self.has_valid_headers(data):
+            logger.info("Backing up old emission file")
+            os.rename(self.save_file_path, self.save_file_path + ".bak")
+            file_exists = False
 
         with open(self.save_file_path, "a+") as f:
             writer = csv.DictWriter(f, fieldnames=data.values.keys())
diff --git a/docker/README.md b/docker/README.md
index 06fd3d740..219eafae3 100644
--- a/docker/README.md
+++ b/docker/README.md
@@ -22,7 +22,7 @@ docker-compose up -d
 This will run :
  - Postgresql on localhost:5480
  - PGAdmin 4 on [http://localhost:5080](http://localhost:5080) login : *test@test.com* , password : *test* (Dans PGAdmin, use the host *postgres_codecarbon* and port *5432* for in docker network access)
- - CodeCarbon API on [http://localhost:5080](http://localhost:5080)
+ - CodeCarbon API on [http://localhost:8008](http://localhost:8008)
  
 
 ## Stop
diff --git a/examples/api_call_debug.py b/examples/api_call_debug.py
index acbf8a8cc..8cedf26e3 100644
--- a/examples/api_call_debug.py
+++ b/examples/api_call_debug.py
@@ -6,7 +6,7 @@
 
 
 @track_emissions(
-    # api_endpoint="http://app-d6bc59c3-0f69-4d8b-a6a3-bc39a9ceb0c2.cleverapps.io",
+    api_endpoint="http://localhost:8008",
     measure_power_secs=30,
     api_call_interval=4,
     api_key="12aaaaaa-0b23-1234-1234-abcdef123456",
diff --git a/examples/emissions.csv b/examples/emissions.csv
index f0621c0a9..7f5e42ec4 100644
--- a/examples/emissions.csv
+++ b/examples/emissions.csv
@@ -1,101 +1,101 @@
-﻿timestamp,experiment_id,project_name,duration,emissions,energy_consumed,country_name,country_iso_code,region,on_cloud,cloud_provider,cloud_region
-2020-03-23T09:26:11,68f53844-f3af-48fb-971a-ffab844a6b6f,project_gamma,34,8,8,USA,USA,Ohio,Y,aws,us-east-2
-2020-03-24T15:26:11,9288b395-c196-45c3-9c5e-05a8c127f753,project_delta,16,1,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-03-25T21:26:11,ed2a22f1-aa97-4fe2-a52c-a985817b7493,project_alpha,19,1,1,Canada,CAN,Ontario,N,,
-2020-03-27T03:26:11,c9d83605-a95b-464c-94f4-f630dbdebb0d,project_theta,34,8,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-03-28T09:26:11,00604242-376c-4e73-8eb0-dacf223029bc,project_gamma,48,8,7,USA,USA,Ohio,Y,aws,us-east-2
-2020-03-29T15:26:11,001b2a28-5199-475c-835f-5894fde101b9,project_theta,25,7,6,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-03-30T21:26:11,9d9b5cb0-8e5b-4736-95e9-9a6567645af2,project_delta,29,6,8,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-04-01T03:26:11,dc64ca2e-fefb-45da-bda8-5eee1d6e588c,project_alpha,10,6,6,Canada,CAN,Ontario,N,,
-2020-04-02T09:26:11,f195944a-0ffc-4216-a90d-874fbc55abfe,project_alpha,13,9,9,Canada,CAN,Ontario,N,,
-2020-04-03T15:26:11,94a6178f-e144-4419-8cb3-b1f700f4641d,project_delta,35,2,4,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-04-04T21:26:11,e93e7b74-441a-41ff-a00f-bdd128ef7daa,project_beta,27,7,8,Canada,CAN,Ontario,N,,
-2020-04-06T03:26:11,5c01053f-a4c8-413c-b677-117dfb022310,project_delta,42,7,1,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-04-07T09:26:11,d41e582e-34eb-4f5a-9b32-41c8297cfd94,project_theta,49,7,6,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-04-08T15:26:11,79e9332e-56cd-4a7c-96d6-918c8365c1d6,project_gamma,49,3,9,USA,USA,Ohio,Y,aws,us-east-2
-2020-04-09T21:26:11,dc7f5b4a-84c9-4dd2-a318-89874316c31e,project_gamma,40,9,7,USA,USA,Ohio,Y,aws,us-east-2
-2020-04-11T03:26:11,c1abf2c5-b2f9-44b6-b6c1-c14c05e37807,project_beta,36,6,6,Canada,CAN,Ontario,N,,
-2020-04-12T09:26:11,da0a923b-d2ce-4cf6-bfe8-e0d9a8d799a1,project_beta,18,3,2,Canada,CAN,Ontario,N,,
-2020-04-13T15:26:11,1fac9aa8-607b-4b50-ba0a-739e87111ec5,project_theta,26,6,6,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-04-14T21:26:11,fc6ab08c-e032-413e-890c-f92c3e023ce9,project_alpha,39,8,6,Canada,CAN,Ontario,N,,
-2020-04-16T03:26:11,fa8532d7-71b0-4f36-8ae3-c658e146cb32,project_gamma,24,2,8,USA,USA,Ohio,Y,aws,us-east-2
-2020-04-17T09:26:11,1058e5c4-301a-4f49-a032-675a2b835c7f,project_theta,40,8,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-04-18T15:26:11,d9d753ac-b4ce-4bae-ad71-2e6f0e621688,project_gamma,42,4,1,USA,USA,Ohio,Y,aws,us-east-2
-2020-04-19T21:26:11,38719fcd-6ba4-4188-8742-04d41adb5a71,project_beta,12,5,4,Canada,CAN,Ontario,N,,
-2020-04-21T03:26:11,ef41c8ea-c249-48f8-86f4-70beef99b0e8,project_gamma,26,9,2,USA,USA,Ohio,Y,aws,us-east-2
-2020-04-22T09:26:11,db4d3d79-5401-48a1-9a3f-8f3cfd59a05c,project_beta,31,4,2,Canada,CAN,Ontario,N,,
-2020-04-23T15:26:11,700e1425-5417-42e3-9a9c-e80efd3144ff,project_gamma,29,4,4,USA,USA,Ohio,Y,aws,us-east-2
-2020-04-24T21:26:11,889a97c2-ada3-4dd9-9149-1e19ef7219e5,project_beta,19,2,7,Canada,CAN,Ontario,N,,
-2020-04-26T03:26:11,01f7cd91-a200-451c-bc21-795859772cbb,project_theta,39,1,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-04-27T09:26:11,3cb6b905-4355-443a-8f01-5a739a9c2b40,project_delta,43,4,2,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-04-28T15:26:11,12726352-06e6-4050-8924-f2d1b4667638,project_delta,10,8,4,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-04-29T21:26:11,8aff0992-9e1d-49ff-8d5c-02b797a4372a,project_gamma,19,7,9,USA,USA,Ohio,Y,aws,us-east-2
-2020-04-31T03:26:11,042a0aca-97b4-4782-9263-1fe66d630a6d,project_beta,49,2,3,Canada,CAN,Ontario,N,,
-2020-05-01T09:26:11,7c8896c1-64e7-4e26-a9b7-917e050bb6eb,project_alpha,37,3,2,Canada,CAN,Ontario,N,,
-2020-05-02T15:26:11,302776ba-4919-41de-96e8-090ad555700a,project_alpha,29,6,4,Canada,CAN,Ontario,N,,
-2020-05-03T21:26:11,cfa16447-9ecb-41d9-ae9c-2605be94b4ec,project_theta,38,7,8,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-05-05T03:26:11,26ab41dd-7cd1-4317-9540-e223c4b82326,project_alpha,32,8,4,Canada,CAN,Ontario,N,,
-2020-05-06T09:26:11,45ec5fc1-d120-4437-9eaa-64ed4ab16be1,project_beta,19,5,3,Canada,CAN,Ontario,N,,
-2020-05-07T15:26:11,b2616820-719f-429b-bfa2-4c52d4f8846e,project_delta,26,9,1,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-05-08T21:26:11,d25bb0a7-757a-428e-a22d-537c5c20a2e3,project_theta,20,7,8,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-05-10T03:26:11,09154017-c27b-4e27-a90d-e48b134bc7c7,project_gamma,24,6,5,USA,USA,Ohio,Y,aws,us-east-2
-2020-05-11T09:26:11,495151cf-3944-4416-9cf9-05434e5ff7fc,project_alpha,38,5,4,Canada,CAN,Ontario,N,,
-2020-05-12T15:26:11,6e1865b4-b210-4022-8a95-b431a2ee9775,project_alpha,41,3,5,Canada,CAN,Ontario,N,,
-2020-05-13T21:26:11,a673a232-7878-481c-98d9-29df56cddbe8,project_beta,47,4,3,Canada,CAN,Ontario,N,,
-2020-05-15T03:26:11,9a877fad-1de6-474a-a8d5-249deb478f5f,project_theta,24,9,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-05-16T09:26:11,9c8d974c-21e6-43a5-b7a2-c710aec9ef2a,project_delta,40,2,8,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-05-17T15:26:11,fc6f5fff-c7c0-49f4-8f9e-ccc3fd5b2bd2,project_delta,16,5,8,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-05-18T21:26:11,1f840670-8662-4069-9956-dad8f3fe22da,project_gamma,40,2,2,USA,USA,Ohio,Y,aws,us-east-2
-2020-05-20T03:26:11,05925b46-1ce8-4d53-a6f7-328aace4b30d,project_theta,13,5,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-05-21T09:26:11,1554f01e-8916-4896-ae3b-fdb76cfa6b70,project_theta,11,4,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-05-22T15:26:11,69aef481-e5a5-4d0f-a8df-42eaba2beb3e,project_delta,23,7,6,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-05-23T21:26:11,4d982b74-7a4b-4011-a5b4-646c1e8e3bec,project_alpha,45,8,5,Canada,CAN,Ontario,N,,
-2020-05-25T03:26:11,f99c75fe-77f4-4346-b8e3-e7c4af1d317a,project_delta,18,7,1,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-05-26T09:26:11,6a2a6c62-649e-43e6-bf07-80fef9dc3977,project_beta,19,9,8,Canada,CAN,Ontario,N,,
-2020-05-27T15:26:11,53fbb54c-dd01-416b-a857-1c5fc85161c8,project_delta,33,4,4,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-05-28T21:26:11,2b9a061a-08b1-417d-8ebf-1d838ced4db3,project_alpha,15,4,3,Canada,CAN,Ontario,N,,
-2020-05-30T03:26:11,6ba6b8c9-60bc-4dc7-aa5d-de2edb657bf5,project_gamma,45,4,2,USA,USA,Ohio,Y,aws,us-east-2
-2020-06-01T09:26:11,68493bcc-bf25-4566-83d3-576a928df62e,project_gamma,15,6,8,USA,USA,Ohio,Y,aws,us-east-2
-2020-06-02T15:26:11,1c3869bb-fc43-4716-87fd-caefa089ccb3,project_alpha,45,4,2,Canada,CAN,Ontario,N,,
-2020-06-03T21:26:11,a755ecd7-078f-44f6-8797-e07c55a18113,project_delta,44,1,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-06-05T03:26:11,5b7609a1-ad17-4dde-a944-8fda11bb7b75,project_delta,48,4,7,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-06-06T09:26:11,b09b3510-5860-40ad-95fd-62bd2beeefe4,project_delta,11,5,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-06-07T15:26:11,daa85d09-1d48-4b4e-b4a3-ab79a27eb1a2,project_delta,21,1,7,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-06-08T21:26:11,7055ff50-42e9-44eb-8b2b-79bced20ea26,project_theta,43,2,2,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-06-10T03:26:11,c15e7b61-7b89-45b1-ace9-66cfe62f1d78,project_alpha,19,8,5,Canada,CAN,Ontario,N,,
-2020-06-11T09:26:11,1d4c9213-9652-4d38-b6af-6c751e88030c,project_alpha,20,9,3,Canada,CAN,Ontario,N,,
-2020-06-12T15:26:11,225c99ed-6073-4138-bc67-11d571164180,project_theta,19,1,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-06-13T21:26:11,89e5f095-d1d8-4abe-adc9-56a36f4031a2,project_alpha,48,4,4,Canada,CAN,Ontario,N,,
-2020-06-15T03:26:11,56a8180b-4fc1-42ef-b999-37ec2fbc855b,project_alpha,48,2,9,Canada,CAN,Ontario,N,,
-2020-06-16T09:26:11,5a13a175-3a5e-43df-ace4-4c078db3a712,project_delta,18,9,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-06-17T15:26:11,4170e0b8-ce66-4c24-9c51-690bc18549b6,project_theta,38,7,7,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-06-18T21:26:11,cbf48a43-21b5-44b0-baa7-c58c82cc23e5,project_gamma,36,5,7,USA,USA,Ohio,Y,aws,us-east-2
-2020-06-20T03:26:11,c3de7b5b-cf45-4687-a975-0bcc648a0fda,project_delta,15,2,7,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-06-21T09:26:11,dc39635d-c9b7-4ecb-9bf3-5e726cf04723,project_alpha,41,4,6,Canada,CAN,Ontario,N,,
-2020-06-22T15:26:11,36f600c9-cd2b-4550-806a-a4fe33a50860,project_alpha,11,4,6,Canada,CAN,Ontario,N,,
-2020-06-23T21:26:11,c243c8af-3b2e-4f9c-840c-57b52442d5b6,project_beta,23,5,1,Canada,CAN,Ontario,N,,
-2020-06-25T03:26:11,2e00f329-55d2-46f4-bbd3-8eda3d3679d3,project_alpha,47,9,6,Canada,CAN,Ontario,N,,
-2020-06-26T09:26:11,4bc85d53-7c1f-457a-9cde-105bdcea0b71,project_beta,19,9,4,Canada,CAN,Ontario,N,,
-2020-06-27T15:26:11,72458b15-998a-459c-b09a-2ccc7a7d6587,project_alpha,39,2,7,Canada,CAN,Ontario,N,,
-2020-06-28T21:26:11,8b41a40f-2e0b-4c6d-8ea1-fb757e8e976d,project_alpha,11,7,1,Canada,CAN,Ontario,N,,
-2020-06-30T03:26:11,258b8bb9-a643-45d5-b3c0-ae2e7513cd07,project_gamma,46,9,1,USA,USA,Ohio,Y,aws,us-east-2
-2020-06-31T09:26:11,97ee03d2-1366-4987-95ea-7e8e0a8af252,project_alpha,23,2,9,Canada,CAN,Ontario,N,,
-2020-07-01T15:26:11,5326a613-358b-423f-85a4-b712a10bf8c8,project_beta,34,7,8,Canada,CAN,Ontario,N,,
-2020-07-02T21:26:11,82ee3c55-83d6-4a6e-bb8f-3dfc5e7d07ca,project_gamma,40,1,5,USA,USA,Ohio,Y,aws,us-east-2
-2020-07-04T03:26:11,31f7043d-d96d-4ef6-b8c5-3575f95a1104,project_gamma,34,7,7,USA,USA,Ohio,Y,aws,us-east-2
-2020-07-05T09:26:11,a5c8bf4c-3119-4c6a-9bd9-6d0eaf30108c,project_delta,39,9,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-07-06T15:26:11,816698dc-9b91-48d7-a8d4-0b9695cd2a89,project_theta,49,5,3,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-07-07T21:26:11,fefca44b-5493-4cac-8574-80783f880424,project_gamma,42,8,9,USA,USA,Ohio,Y,aws,us-east-2
-2020-07-09T03:26:11,64e325df-2552-43cd-91b4-6e1c562731c0,project_delta,48,8,6,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-07-10T09:26:11,4e1c4e47-25c3-4921-b19c-71e3727e7a18,project_theta,31,6,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-07-11T15:26:11,e29d8171-7e08-4fcf-ab3b-f88fc16237ee,project_delta,21,2,6,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-07-12T21:26:11,7c3c4266-0cfa-45cf-acd5-77feabad1db3,project_gamma,35,3,1,USA,USA,Ohio,Y,aws,us-east-2
-2020-07-14T03:26:11,516a14c3-4c39-4f14-be21-3bd77556b804,project_theta,20,1,8,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
-2020-07-15T09:26:11,a41f98a8-bdad-4f34-9cca-8aa2736cc45f,project_gamma,31,6,1,USA,USA,Ohio,Y,aws,us-east-2
-2020-07-16T15:26:11,0fa1657b-102a-4a58-b8cd-7c709b774a03,project_gamma,48,5,4,USA,USA,Ohio,Y,aws,us-east-2
-2020-07-17T21:26:11,664b02b5-bd94-4f87-9569-9728297f352a,project_beta,16,7,8,Canada,CAN,Ontario,N,,
-2020-07-19T03:26:11,eadd4540-a8ae-483f-a86c-6502383c5868,project_delta,38,9,2,Taiwan,TWN,Changhua County,Y,gcp,asia-east1
-2020-07-20T09:26:11,b87f203e-b8cc-434b-80a9-0df2bc2ebc9e,project_gamma,45,4,9,USA,USA,Ohio,Y,aws,us-east-2
-2020-07-21T15:26:11,29a689f4-f875-4e6e-bf8e-28c8f5e08781,project_beta,14,1,8,Canada,CAN,Ontario,N,,
-2020-07-22T21:26:11,dd0af408-06ea-440a-b99e-6358a9bc5711,project_alpha,48,4,6,Canada,CAN,Ontario,N,,
-2020-07-24T03:26:11,f65e46fc-298d-4f7a-9827-7f756b1d2f44,project_theta,32,8,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth
+timestamp,project_name,duration,emissions,emissions_rate,cpu_power,gpu_power,ram_power,cpu_energy,gpu_energy,ram_energy,energy_consumed,country_name,country_iso_code,region,on_cloud,cloud_provider,cloud_region,,,,,,,,,,,,,,
+2020-03-23T09:26:11,project_gamma,34,8,4,8,0,1.234535,8,0,0.1565332,8,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-03-24T15:26:11,project_delta,16,1,0.5,3,0,1.234535034,3,0,0.156533207,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-03-25T21:26:11,project_alpha,19,1,0.5,1,0,1.234535069,1,0,0.156533215,1,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-03-27T03:26:11,project_theta,34,8,4,5,0,1.234535103,5,0,0.156533222,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-03-28T09:26:11,project_gamma,48,8,4,7,0,1.234535137,7,0,0.156533229,7,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-03-29T15:26:11,project_theta,25,7,3.5,6,0,1.234535172,6,0,0.156533236,6,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-03-30T21:26:11,project_delta,29,6,3,8,0,1.234535206,8,0,0.156533244,8,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-04-01T03:26:11,project_alpha,10,6,3,6,0,1.23453524,6,0,0.156533251,6,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-02T09:26:11,project_alpha,13,9,4.5,9,0,1.234535274,9,0,0.156533258,9,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-03T15:26:11,project_delta,35,2,1,4,0,1.234535309,4,0,0.156533265,4,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-04-04T21:26:11,project_beta,27,7,3.5,8,0,1.234535343,8,0,0.156533273,8,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-06T03:26:11,project_delta,42,7,3.5,1,0,1.234535377,1,0,0.15653328,1,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-04-07T09:26:11,project_theta,49,7,3.5,6,0,1.234535412,6,0,0.156533287,6,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-04-08T15:26:11,project_gamma,49,3,1.5,9,0,1.234535446,9,0,0.156533295,9,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-04-09T21:26:11,project_gamma,40,9,4.5,7,0,1.23453548,7,0,0.156533302,7,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-04-11T03:26:11,project_beta,36,6,3,6,0,1.234535515,6,0,0.156533309,6,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-12T09:26:11,project_beta,18,3,1.5,2,0,1.234535549,2,0,0.156533316,2,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-13T15:26:11,project_theta,26,6,3,6,0,1.234535583,6,0,0.156533324,6,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-04-14T21:26:11,project_alpha,39,8,4,6,0,1.234535617,6,0,0.156533331,6,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-16T03:26:11,project_gamma,24,2,1,8,0,1.234535652,8,0,0.156533338,8,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-04-17T09:26:11,project_theta,40,8,4,5,0,1.234535686,5,0,0.156533345,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-04-18T15:26:11,project_gamma,42,4,2,1,0,1.23453572,1,0,0.156533353,1,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-04-19T21:26:11,project_beta,12,5,2.5,4,0,1.234535755,4,0,0.15653336,4,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-21T03:26:11,project_gamma,26,9,4.5,2,0,1.234535789,2,0,0.156533367,2,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-04-22T09:26:11,project_beta,31,4,2,2,0,1.234535823,2,0,0.156533375,2,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-23T15:26:11,project_gamma,29,4,2,4,0,1.234535858,4,0,0.156533382,4,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-04-24T21:26:11,project_beta,19,2,1,7,0,1.234535892,7,0,0.156533389,7,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-04-26T03:26:11,project_theta,39,1,0.5,4,0,1.234535926,4,0,0.156533396,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-04-27T09:26:11,project_delta,43,4,2,2,0,1.23453596,2,0,0.156533404,2,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-04-28T15:26:11,project_delta,10,8,4,4,0,1.234535995,4,0,0.156533411,4,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-04-29T21:26:11,project_gamma,19,7,3.5,9,0,1.234536029,9,0,0.156533418,9,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-04-31T03:26:11,project_beta,49,2,1,3,0,1.234536063,3,0,0.156533425,3,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-01T09:26:11,project_alpha,37,3,1.5,2,0,1.234536098,2,0,0.156533433,2,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-02T15:26:11,project_alpha,29,6,3,4,0,1.234536132,4,0,0.15653344,4,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-03T21:26:11,project_theta,38,7,3.5,8,0,1.234536166,8,0,0.156533447,8,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-05-05T03:26:11,project_alpha,32,8,4,4,0,1.234536201,4,0,0.156533455,4,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-06T09:26:11,project_beta,19,5,2.5,3,0,1.234536235,3,0,0.156533462,3,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-07T15:26:11,project_delta,26,9,4.5,1,0,1.234536269,1,0,0.156533469,1,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-05-08T21:26:11,project_theta,20,7,3.5,8,0,1.234536303,8,0,0.156533476,8,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-05-10T03:26:11,project_gamma,24,6,3,5,0,1.234536338,5,0,0.156533484,5,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-05-11T09:26:11,project_alpha,38,5,2.5,4,0,1.234536372,4,0,0.156533491,4,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-12T15:26:11,project_alpha,41,3,1.5,5,0,1.234536406,5,0,0.156533498,5,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-13T21:26:11,project_beta,47,4,2,3,0,1.234536441,3,0,0.156533505,3,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-15T03:26:11,project_theta,24,9,4.5,4,0,1.234536475,4,0,0.156533513,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-05-16T09:26:11,project_delta,40,2,1,8,0,1.234536509,8,0,0.15653352,8,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-05-17T15:26:11,project_delta,16,5,2.5,8,0,1.234536544,8,0,0.156533527,8,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-05-18T21:26:11,project_gamma,40,2,1,2,0,1.234536578,2,0,0.156533535,2,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-05-20T03:26:11,project_theta,13,5,2.5,5,0,1.234536612,5,0,0.156533542,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-05-21T09:26:11,project_theta,11,4,2,4,0,1.234536646,4,0,0.156533549,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-05-22T15:26:11,project_delta,23,7,3.5,6,0,1.234536681,6,0,0.156533556,6,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-05-23T21:26:11,project_alpha,45,8,4,5,0,1.234536715,5,0,0.156533564,5,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-25T03:26:11,project_delta,18,7,3.5,1,0,1.234536749,1,0,0.156533571,1,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-05-26T09:26:11,project_beta,19,9,4.5,8,0,1.234536784,8,0,0.156533578,8,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-27T15:26:11,project_delta,33,4,2,4,0,1.234536818,4,0,0.156533585,4,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-05-28T21:26:11,project_alpha,15,4,2,3,0,1.234536852,3,0,0.156533593,3,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-05-30T03:26:11,project_gamma,45,4,2,2,0,1.234536887,2,0,0.1565336,2,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-06-01T09:26:11,project_gamma,15,6,3,8,0,1.234536921,8,0,0.156533607,8,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-06-02T15:26:11,project_alpha,45,4,2,2,0,1.234536955,2,0,0.156533615,2,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-03T21:26:11,project_delta,44,1,0.5,3,0,1.234536989,3,0,0.156533622,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-06-05T03:26:11,project_delta,48,4,2,7,0,1.234537024,7,0,0.156533629,7,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-06-06T09:26:11,project_delta,11,5,2.5,3,0,1.234537058,3,0,0.156533636,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-06-07T15:26:11,project_delta,21,1,0.5,7,0,1.234537092,7,0,0.156533644,7,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-06-08T21:26:11,project_theta,43,2,1,2,0,1.234537127,2,0,0.156533651,2,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-06-10T03:26:11,project_alpha,19,8,4,5,0,1.234537161,5,0,0.156533658,5,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-11T09:26:11,project_alpha,20,9,4.5,3,0,1.234537195,3,0,0.156533665,3,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-12T15:26:11,project_theta,19,1,0.5,5,0,1.23453723,5,0,0.156533673,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-06-13T21:26:11,project_alpha,48,4,2,4,0,1.234537264,4,0,0.15653368,4,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-15T03:26:11,project_alpha,48,2,1,9,0,1.234537298,9,0,0.156533687,9,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-16T09:26:11,project_delta,18,9,4.5,3,0,1.234537332,3,0,0.156533695,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-06-17T15:26:11,project_theta,38,7,3.5,7,0,1.234537367,7,0,0.156533702,7,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-06-18T21:26:11,project_gamma,36,5,2.5,7,0,1.234537401,7,0,0.156533709,7,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-06-20T03:26:11,project_delta,15,2,1,7,0,1.234537435,7,0,0.156533716,7,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-06-21T09:26:11,project_alpha,41,4,2,6,0,1.23453747,6,0,0.156533724,6,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-22T15:26:11,project_alpha,11,4,2,6,0,1.234537504,6,0,0.156533731,6,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-23T21:26:11,project_beta,23,5,2.5,1,0,1.234537538,1,0,0.156533738,1,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-25T03:26:11,project_alpha,47,9,4.5,6,0,1.234537573,6,0,0.156533745,6,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-26T09:26:11,project_beta,19,9,4.5,4,0,1.234537607,4,0,0.156533753,4,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-27T15:26:11,project_alpha,39,2,1,7,0,1.234537641,7,0,0.15653376,7,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-28T21:26:11,project_alpha,11,7,3.5,1,0,1.234537675,1,0,0.156533767,1,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-06-30T03:26:11,project_gamma,46,9,4.5,1,0,1.23453771,1,0,0.156533775,1,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-06-31T09:26:11,project_alpha,23,2,1,9,0,1.234537744,9,0,0.156533782,9,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-07-01T15:26:11,project_beta,34,7,3.5,8,0,1.234537778,8,0,0.156533789,8,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-07-02T21:26:11,project_gamma,40,1,0.5,5,0,1.234537813,5,0,0.156533796,5,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-07-04T03:26:11,project_gamma,34,7,3.5,7,0,1.234537847,7,0,0.156533804,7,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-07-05T09:26:11,project_delta,39,9,4.5,3,0,1.234537881,3,0,0.156533811,3,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-07-06T15:26:11,project_theta,49,5,2.5,3,0,1.234537916,3,0,0.156533818,3,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-07-07T21:26:11,project_gamma,42,8,4,9,0,1.23453795,9,0,0.156533825,9,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-07-09T03:26:11,project_delta,48,8,4,6,0,1.234537984,6,0,0.156533833,6,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-07-10T09:26:11,project_theta,31,6,3,4,0,1.234538018,4,0,0.15653384,4,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-07-11T15:26:11,project_delta,21,2,1,6,0,1.234538053,6,0,0.156533847,6,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-07-12T21:26:11,project_gamma,35,3,1.5,1,0,1.234538087,1,0,0.156533855,1,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-07-14T03:26:11,project_theta,20,1,0.5,8,0,1.234538121,8,0,0.156533862,8,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth,,,,,,,,,,,,,,
+2020-07-15T09:26:11,project_gamma,31,6,3,1,0,1.234538156,1,0,0.156533869,1,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-07-16T15:26:11,project_gamma,48,5,2.5,4,0,1.23453819,4,0,0.156533876,4,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-07-17T21:26:11,project_beta,16,7,3.5,8,0,1.234538224,8,0,0.156533884,8,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-07-19T03:26:11,project_delta,38,9,4.5,2,0,1.234538259,2,0,0.156533891,2,Taiwan,TWN,Changhua County,Y,gcp,asia-east1,,,,,,,,,,,,,,
+2020-07-20T09:26:11,project_gamma,45,4,2,9,0,1.234538293,9,0,0.156533898,9,USA,USA,Ohio,Y,aws,us-east-2,,,,,,,,,,,,,,
+2020-07-21T15:26:11,project_beta,14,1,0.5,8,0,1.234538327,8,0,0.156533905,8,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-07-22T21:26:11,project_alpha,48,4,2,6,0,1.234538361,6,0,0.156533913,6,Canada,CAN,Ontario,N,,,,,,,,,,,,,,,,
+2020-07-24T03:26:11,project_theta,32,8,4,5,0,1.234538396,5,0,0.15653392,5,Brazil,BRA,Sao Paulo,Y,azure,brazilsouth2021-07-14T10:59:36,codecarbon,3565.51492,0.027399096,2.6775,0,1.533303325,0.022284099,0,0.012761264,0.035045363,Morocco,MAR,casablanca-settat,N
\ No newline at end of file


Test patch:
diff --git a/carbonserver/tests/api/routers/test_emissions.py b/carbonserver/tests/api/routers/test_emissions.py
index 7e6d7d55d..2923c2a2b 100644
--- a/carbonserver/tests/api/routers/test_emissions.py
+++ b/carbonserver/tests/api/routers/test_emissions.py
@@ -23,7 +23,14 @@
     "timestamp": "2021-04-04T08:43:00+02:00",
     "run_id": "40088f1a-d28e-4980-8d80-bf5600056a14",
     "duration": 98745,
-    "emissions": 1.548444,
+    "emissions_sum": 206.548444,
+    "emissions_rate": 89.548444,
+    "cpu_power": 0.3,
+    "gpu_power": 0.0,
+    "ram_power": 0.15,
+    "cpu_energy": 55.21874,
+    "gpu_energy": 0.0,
+    "ram_energy": 2.0,
     "energy_consumed": 57.21874,
 }
 
@@ -32,7 +39,14 @@
     "timestamp": "2021-04-04T08:43:00+02:00",
     "run_id": RUN_1_ID,
     "duration": 98745,
-    "emissions": 1.548444,
+    "emissions_sum": 106.548444,
+    "emissions_rate": 0.548444,
+    "cpu_power": 0.3,
+    "gpu_power": 0.0,
+    "ram_power": 0.15,
+    "cpu_energy": 55.21874,
+    "gpu_energy": 0.0,
+    "ram_energy": 2.0,
     "energy_consumed": 57.21874,
 }
 
@@ -41,7 +55,14 @@
     "timestamp": "2021-04-04T08:43:00+02:00",
     "run_id": RUN_1_ID,
     "duration": 98745,
-    "emissions": 1.548444,
+    "emissions_sum": 136.548444,
+    "emissions_rate": 5.548444,
+    "cpu_power": 0.3,
+    "gpu_power": 0.0,
+    "ram_power": 0.15,
+    "cpu_energy": 55.21874,
+    "gpu_energy": 0.0,
+    "ram_energy": 2.0,
     "energy_consumed": 57.21874,
 }
 
@@ -51,7 +72,14 @@
     "timestamp": "2021-04-04T08:43:00+02:00",
     "run_id": RUN_2_ID,
     "duration": 98745,
-    "emissions": 1.548444,
+    "emissions_sum": 256.548444,
+    "emissions_rate": 98.548444,
+    "cpu_power": 0.3,
+    "gpu_power": 0.0,
+    "ram_power": 0.15,
+    "cpu_energy": 55.21874,
+    "gpu_energy": 0.0,
+    "ram_energy": 2.0,
     "energy_consumed": 57.21874,
 }
 
diff --git a/carbonserver/tests/api/service/test_emission_service.py b/carbonserver/tests/api/service/test_emission_service.py
index 8c225bf1f..2701c4883 100644
--- a/carbonserver/tests/api/service/test_emission_service.py
+++ b/carbonserver/tests/api/service/test_emission_service.py
@@ -18,7 +18,14 @@
     timestamp="2021-04-04T08:43:00+02:00",
     run_id=RUN_1_ID,
     duration=98745,
-    emissions=1.548444,
+    emissions_sum=455.6544,
+    emissions_rate=1.548444,
+    cpu_power=0.3,
+    gpu_power=0.0,
+    ram_power=0.15,
+    cpu_energy=55.21874,
+    gpu_energy=0.0,
+    ram_energy=2.0,
     energy_consumed=57.21874,
 )
 
@@ -27,7 +34,14 @@
     timestamp="2021-04-04T08:43:00+02:00",
     run_id=RUN_1_ID,
     duration=98745,
-    emissions=1.548444,
+    emissions_sum=455.6544,
+    emissions_rate=0.548444,
+    cpu_power=0.3,
+    gpu_power=0.0,
+    ram_power=0.15,
+    cpu_energy=55.21874,
+    gpu_energy=0.0,
+    ram_energy=2.0,
     energy_consumed=57.21874,
 )
 
@@ -36,7 +50,14 @@
     timestamp="2021-04-04T08:43:00+02:00",
     run_id=RUN_1_ID,
     duration=98745,
-    emissions=1.548444,
+    emissions_sum=451.6544,
+    emissions_rate=1.5324,
+    cpu_power=0.3,
+    gpu_power=0.0,
+    ram_power=0.15,
+    cpu_energy=55.21874,
+    gpu_energy=0.0,
+    ram_energy=2.0,
     energy_consumed=57.21874,
 )
 
@@ -52,7 +73,14 @@ def test_emission_service_creates_correct_emission(_):
         timestamp="2021-04-04T08:43:00+02:00",
         run_id=RUN_1_ID,
         duration=98745,
-        emissions=1.548444,
+        emissions_sum=433.6544,
+        emissions_rate=1.548444,
+        cpu_power=0.3,
+        gpu_power=0.0,
+        ram_power=0.15,
+        cpu_energy=55.21874,
+        gpu_energy=0.0,
+        ram_energy=2.0,
         energy_consumed=57.21874,
     )
 
diff --git a/tests/test_api_call.py b/tests/test_api_call.py
index 4856c18f1..41d3ab9db 100644
--- a/tests/test_api_call.py
+++ b/tests/test_api_call.py
@@ -7,7 +7,6 @@
 
 
 def test_call_api():
-    # mock_path = 'codecarbon.core.api_client.requests'
     with requests_mock.Mocker() as m:
         m.post(
             "http://test.com/run",
@@ -28,6 +27,13 @@ def test_call_api():
             project_name="",
             duration=1.5,
             emissions=2.0,
+            emissions_rate=2.0,
+            cpu_energy=2,
+            gpu_energy=0,
+            ram_energy=1,
+            cpu_power=3.0,
+            gpu_power=0,
+            ram_power=0.15,
             energy_consumed=3.0,
             country_name="Groland",
             country_iso_code="GRD",
diff --git a/tests/test_data/emissions_invalid_headers.csv b/tests/test_data/emissions_invalid_headers.csv
new file mode 100644
index 000000000..61545134f
--- /dev/null
+++ b/tests/test_data/emissions_invalid_headers.csv
@@ -0,0 +1,2 @@
+timestamp,project_name,duration,emissions,energy_consumed,country_name,country_iso_code,region,on_cloud,cloud_provider,cloud_region
+2021-06-29T11:00:38,codecarbon,210.39603400230408,0.0010231017276686953,0.001308618772068,Morocco,MAR,casablanca-settat,N,,
diff --git a/tests/test_data/emissions_valid_headers.csv b/tests/test_data/emissions_valid_headers.csv
new file mode 100644
index 000000000..50dcc40f2
--- /dev/null
+++ b/tests/test_data/emissions_valid_headers.csv
@@ -0,0 +1,2 @@
+timestamp,project_name,duration,emissions,emissions_rate,cpu_power,gpu_power,ram_power,cpu_energy,gpu_energy,ram_energy,energy_consumed,country_name,country_iso_code,region,on_cloud,cloud_provider,cloud_region
+2021-07-13T17:36:33,codecarbon,175.7496521,0.001327206,0.000663603,0.27,0,0.154618823,0.001079437,0,0.000618153,0.00169759,Morocco,MAR,casablanca-settat,N,,
diff --git a/tests/test_emissions_tracker.py b/tests/test_emissions_tracker.py
index cf9083ff7..2f9e682c8 100644
--- a/tests/test_emissions_tracker.py
+++ b/tests/test_emissions_tracker.py
@@ -1,3 +1,5 @@
+import os
+import shutil
 import tempfile
 import time
 import unittest
@@ -183,7 +185,7 @@ def dummy_train_model():
         dummy_train_model()
 
         # THEN
-        self.verify_output_file(self.emissions_file_path)
+        self.verify_output_file(self.emissions_file_path, 2)
 
     @responses.activate
     def test_decorator_ONLINE_WITH_ARGS(
@@ -210,7 +212,7 @@ def dummy_train_model():
         dummy_train_model()
 
         # THEN
-        self.verify_output_file(self.emissions_file_path)
+        self.verify_output_file(self.emissions_file_path, 2)
 
     def test_decorator_OFFLINE_NO_COUNTRY(
         self,
@@ -248,7 +250,7 @@ def dummy_train_model():
             return 42
 
         dummy_train_model()
-        self.verify_output_file(self.emissions_file_path)
+        self.verify_output_file(self.emissions_file_path, 2)
 
     def test_decorator_OFFLINE_WITH_CLOUD_ARGS(
         self,
@@ -270,7 +272,7 @@ def dummy_train_model():
             return 42
 
         dummy_train_model()
-        self.verify_output_file(self.emissions_file_path)
+        self.verify_output_file(self.emissions_file_path, 2)
 
     def test_offline_tracker_country_name(
         self,
@@ -292,10 +294,67 @@ def test_offline_tracker_country_name(
         self.assertEqual("United States", emissions_df["country_name"].values[0])
         self.assertEqual("USA", emissions_df["country_iso_code"].values[0])
 
-    def verify_output_file(self, file_path: str) -> None:
+    def test_offline_tracker_invalid_headers(
+        self,
+        mocked_get_cloud_metadata,
+        mocked_get_gpu_details,
+        mocked_is_gpu_details_available,
+        mock_setup_intel_cli,
+        mock_log_values,
+    ):
+        tracker = OfflineEmissionsTracker(
+            country_iso_code="USA", output_dir=self.temp_path
+        )
+        emissions = os.path.join(
+            os.path.dirname(__file__), "test_data", "emissions_invalid_headers.csv"
+        )
+        shutil.copyfile(emissions, self.emissions_file_path)
+        tracker.start()
+        heavy_computation(run_time_secs=2)
+        tracker.stop()
+
+        emissions_df = pd.read_csv(self.emissions_file_path)
+        emissions_backup_df = pd.read_csv(
+            self.emissions_file_path.with_suffix(".csv.bak")
+        )
+
+        self.verify_output_file(self.emissions_file_path, 2)
+        self.verify_output_file(self.emissions_file_path.with_suffix(".csv.bak"), 2)
+
+        self.assertEqual("United States", emissions_df["country_name"].values[0])
+        self.assertEqual("Morocco", emissions_backup_df["country_name"].values[0])
+
+    def test_offline_tracker_valid_headers(
+        self,
+        mocked_get_cloud_metadata,
+        mocked_get_gpu_details,
+        mocked_is_gpu_details_available,
+        mock_setup_intel_cli,
+        mock_log_values,
+    ):
+        tracker = OfflineEmissionsTracker(
+            country_iso_code="USA", output_dir=self.temp_path
+        )
+        emissions = os.path.join(
+            os.path.dirname(__file__), "test_data", "emissions_valid_headers.csv"
+        )
+        shutil.copyfile(emissions, self.emissions_file_path)
+        tracker.start()
+        heavy_computation(run_time_secs=2)
+        tracker.stop()
+
+        emissions_df = pd.read_csv(self.emissions_file_path)
+
+        self.verify_output_file(self.emissions_file_path, 3)
+
+        self.assertAlmostEqual(0.269999999999999, emissions_df["cpu_power"].values[0])
+        self.assertEqual("Morocco", emissions_df["country_name"].values[0])
+        self.assertEqual("United States", emissions_df["country_name"].values[1])
+
+    def verify_output_file(self, file_path: str, num_lines: int) -> None:
         with open(file_path, "r") as f:
             lines = [line.rstrip() for line in f]
-        assert len(lines) == 2
+        assert len(lines) == num_lines
 
     @responses.activate
     def test_carbon_tracker_online_context_manager_TWO_GPU_PRIVATE_INFRA_CANADA(