From 97ec2a1436d4ade1f4d7507ac3b4fe683e2e5111 Mon Sep 17 00:00:00 2001 From: atiya Date: Sat, 13 Nov 2021 00:55:04 -0500 Subject: [PATCH 1/3] added Machine and Vehicle classes to Life Cycle Assessment --- city_model_structure/machine.py | 78 +++++++++++++++++++ city_model_structure/vehicle.py | 61 +++++++++++++++ .../lca_fuel.py | 2 +- imports/life_cycle_assessment/lca_machine.py | 26 +++++++ imports/life_cycle_assessment/lca_vehicle.py | 25 ++++++ ...ry.py => life_cycle_assessment_factory.py} | 20 ++++- .../test_life_cycle_assessment_factory.py | 50 ++++++++++++ 7 files changed, 258 insertions(+), 4 deletions(-) create mode 100644 city_model_structure/machine.py create mode 100644 city_model_structure/vehicle.py rename imports/{life_cicle_analize => life_cycle_assessment}/lca_fuel.py (93%) create mode 100644 imports/life_cycle_assessment/lca_machine.py create mode 100644 imports/life_cycle_assessment/lca_vehicle.py rename imports/{life_cicle_analyze_factory.py => life_cycle_assessment_factory.py} (56%) create mode 100644 unittests/test_life_cycle_assessment_factory.py diff --git a/city_model_structure/machine.py b/city_model_structure/machine.py new file mode 100644 index 00000000..5c25fc71 --- /dev/null +++ b/city_model_structure/machine.py @@ -0,0 +1,78 @@ +""" +LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Atiya +""" + +class Machine: + """ + Machine class + """ + + def __init__(self, machine_id, name, work_efficiency, work_efficiency_unit, energy_consumption_rate, energy_consumption_unit, + carbon_emission_factor, carbon_emission_unit): + self._machine_id = machine_id + self._name = name + self._work_efficiency = work_efficiency + self._work_efficiency_unit = work_efficiency_unit + self._energy_consumption_rate = energy_consumption_rate + self._energy_consumption_unit = energy_consumption_unit + self._carbon_emission_factor = carbon_emission_factor + self._carbon_emission_unit = carbon_emission_unit + + @property + def id(self): + """ + Get machine id + """ + return self._machine_id + + @property + def name(self): + """ + Get machine name + """ + return self._name + + @property + def work_efficiency(self): + """ + Get machine work efficiency + """ + return self._work_efficiency + + @property + def work_efficiency_unit(self): + """ + Get machine work efficiency unit + """ + return self._work_efficiency_unit + + @property + def energy_consumption_rate(self): + """ + Get energy consumption rate + """ + return self._energy_consumption_rate + + @property + def energy_consumption_unit(self): + """ + Get energy consumption unit + """ + return self._energy_consumption_unit + + @property + def carbon_emission_factor(self): + """ + Get carbon emission factor + """ + return self._carbon_emission_factor + + @property + def carbon_emission_unit(self): + """ + Get carbon emission unit + """ + return self._carbon_emission_unit + diff --git a/city_model_structure/vehicle.py b/city_model_structure/vehicle.py new file mode 100644 index 00000000..95aff94a --- /dev/null +++ b/city_model_structure/vehicle.py @@ -0,0 +1,61 @@ +""" +LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Atiya +""" + +class Vehicle: + """ + Vehicle class + """ + + def __init__(self, vehicle_id, name, fuel_consumption_rate, fuel_consumption_unit, carbon_emission_factor, carbon_emission_factor_unit): + self._vehicle_id = vehicle_id + self._name = name + self._fuel_consumption_rate = fuel_consumption_rate + self._fuel_consumption_unit = fuel_consumption_unit + self._carbon_emission_factor = carbon_emission_factor + self._carbon_emission_factor_unit = carbon_emission_factor_unit + + @property + def id(self): + """ + Get vehicle id + """ + return self._vehicle_id + + @property + def name(self): + """ + Get vehicle name + """ + return self._name + + @property + def fuel_consumption_rate(self): + """ + Get vehicle fuel consumption rate + """ + return self._fuel_consumption_rate + + @property + def fuel_consumption_unit(self): + """ + Get fuel consumption unit + """ + return self._fuel_consumption_unit + + @property + def carbon_emission_factor(self): + """ + Get vehicle carbon emission factor + """ + return self._carbon_emission_factor + + @property + def carbon_emission_unit(self): + """ + Get carbon emission units + """ + return self._carbon_emission_unit + diff --git a/imports/life_cicle_analize/lca_fuel.py b/imports/life_cycle_assessment/lca_fuel.py similarity index 93% rename from imports/life_cicle_analize/lca_fuel.py rename to imports/life_cycle_assessment/lca_fuel.py index c35e0749..2ffbcb37 100644 --- a/imports/life_cicle_analize/lca_fuel.py +++ b/imports/life_cycle_assessment/lca_fuel.py @@ -19,6 +19,6 @@ class LcaFuel: with open(path) as xml: self._lca = xmltodict.parse(xml.read()) - for fuel in self._lca["library"]["Fuels"]['fuel']: + for fuel in self._lca["library"]["fuels"]['fuel']: self._city.fuels.append(Fuel(fuel['@id'], fuel['@name'], fuel['carbon_emission_factor']['#text'], fuel['carbon_emission_factor']['@unit'])) diff --git a/imports/life_cycle_assessment/lca_machine.py b/imports/life_cycle_assessment/lca_machine.py new file mode 100644 index 00000000..ae90c03c --- /dev/null +++ b/imports/life_cycle_assessment/lca_machine.py @@ -0,0 +1,26 @@ +""" +CityGml module parses citygml_classes files and import the geometry into the city model structure +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Atiya +""" +import xmltodict +from pathlib import Path +from city_model_structure.machine import Machine + +class LcaMachine: + def __init__(self, city, base_path): + self._city = city + self._base_path = base_path + self._lca = None + + def enrich(self): + self._city.machines = [] + path = Path(self._base_path / 'lca_data.xml').resolve() + + with open(path) as xml: + self._lca = xmltodict.parse(xml.read()) + for machine in self._lca["library"]["machines"]['machine']: + self._city.machines.append(Machine(machine['@id'], machine['@name'], machine['work_efficiency']['#text'], + machine['work_efficiency']['@unit'], machine['energy_consumption_rate']['#text'], + machine['energy_consumption_rate']['@unit'], machine['carbon_emission_factor']['#text'], + machine['carbon_emission_factor']['@unit'])) diff --git a/imports/life_cycle_assessment/lca_vehicle.py b/imports/life_cycle_assessment/lca_vehicle.py new file mode 100644 index 00000000..79da498f --- /dev/null +++ b/imports/life_cycle_assessment/lca_vehicle.py @@ -0,0 +1,25 @@ +""" +CityGml module parses citygml_classes files and import the geometry into the city model structure +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Atiya +""" +import xmltodict +from pathlib import Path +from city_model_structure.vehicle import Vehicle + +class LcaVehicle: + def __init__(self, city, base_path): + self._city = city + self._base_path = base_path + self._lca = None + + def enrich(self): + self._city.vehicles = [] + path = Path(self._base_path / 'lca_data.xml').resolve() + + with open(path) as xml: + self._lca = xmltodict.parse(xml.read()) + for vehicle in self._lca["library"]["vehicles"]['vehicle']: + self._city.vehicles.append(Vehicle(vehicle['@id'], vehicle['@name'], vehicle['fuel_consumption_rate']['#text'], + vehicle['fuel_consumption_rate']['@unit'], vehicle['carbon_emission_factor']['#text'], + vehicle['carbon_emission_factor']['@unit'])) diff --git a/imports/life_cicle_analyze_factory.py b/imports/life_cycle_assessment_factory.py similarity index 56% rename from imports/life_cicle_analyze_factory.py rename to imports/life_cycle_assessment_factory.py index 7a09097a..3aff1fe4 100644 --- a/imports/life_cicle_analyze_factory.py +++ b/imports/life_cycle_assessment_factory.py @@ -5,16 +5,18 @@ Copyright © 2020 Project Author Atiya """ from pathlib import Path -from imports.life_cicle_analize.lca_fuel import LcaFuel +from imports.life_cycle_assessment.lca_fuel import LcaFuel +from imports.life_cycle_assessment.lca_vehicle import LcaVehicle +from imports.life_cycle_assessment.lca_machine import LcaMachine -class LifeCicleAnalizeFactory: +class LifeCycleAssessment: """ Life cicle analize factory class """ def __init__(self, handler, city, base_path=None): if base_path is None: - base_path = Path(Path(__file__).parent.parent / 'data/construction') + base_path = Path(Path(__file__).parent.parent / 'data/life_cycle_assessment') self._handler = '_' + handler.lower().replace(' ', '_') self._city = city self._base_path = base_path @@ -25,6 +27,18 @@ class LifeCicleAnalizeFactory: """ LcaFuel(self._city, self._base_path).enrich() + def _vehicle(self): + """ + Enrich the city by adding the vehicle carbon information + """ + LcaVehicle(self._city, self._base_path).enrich() + + def _machine(self): + """ + Enrich the city by adding the machine carbon information + """ + LcaMachine(self._city, self._base_path).enrich() + def enrich(self): """ Enrich the city given to the class using the class given handler diff --git a/unittests/test_life_cycle_assessment_factory.py b/unittests/test_life_cycle_assessment_factory.py new file mode 100644 index 00000000..32e3453e --- /dev/null +++ b/unittests/test_life_cycle_assessment_factory.py @@ -0,0 +1,50 @@ +""" +Building test +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Guille Gutierrez Morote Guillermo.GutierrezMorote@concordia.ca +""" +from pathlib import Path +from unittest import TestCase +from imports.geometry_factory import GeometryFactory +from imports.life_cycle_assessment_factory import LifeCycleAssessment + + +class TestLifeCycleAssessment(TestCase): + """ + TestBuilding TestCase 1 + """ + def setUp(self) -> None: + """ + Test setup + :return: None + """ + self._city_gml = None + self._example_path = (Path(__file__).parent / 'tests_data').resolve() + + def test_fuel(self): + city_file = "../unittests/tests_data/C40_Final.gml" + city = GeometryFactory('citygml', city_file).city + LifeCycleAssessment('fuel', city).enrich() + for fuel in city.fuels: + # print(fuel.name) + self.assertTrue(len(city.fuels) > 0) + + def test_vehicle(self): + city_file = "../unittests/tests_data/C40_Final.gml" + city = GeometryFactory('citygml', city_file).city + LifeCycleAssessment('vehicle', city).enrich() + for vehicle in city.vehicles: + # print(vehicle.name) + self.assertTrue(len(city.vehicles) > 0) + + def test_machine(self): + city_file = "../unittests/tests_data/C40_Final.gml" + city = GeometryFactory('citygml', city_file).city + LifeCycleAssessment('machine', city).enrich() + for machine in city.machines: + # print(machine.name) + self.assertTrue(len(city.machines) > 0) + + + + From 1d9498cf26f52566ae204e7b4c1292ba7e6d58c7 Mon Sep 17 00:00:00 2001 From: atiya Date: Mon, 15 Nov 2021 08:24:03 -0500 Subject: [PATCH 2/3] Added LCA formulas --- imports/life_cycle_assessment_factory.py | 7 +++++++ unittests/test_life_cycle_assessment_factory.py | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/imports/life_cycle_assessment_factory.py b/imports/life_cycle_assessment_factory.py index 3aff1fe4..cb99b981 100644 --- a/imports/life_cycle_assessment_factory.py +++ b/imports/life_cycle_assessment_factory.py @@ -8,6 +8,7 @@ from pathlib import Path from imports.life_cycle_assessment.lca_fuel import LcaFuel from imports.life_cycle_assessment.lca_vehicle import LcaVehicle from imports.life_cycle_assessment.lca_machine import LcaMachine +from imports.life_cycle_assessment.lca_material import LcaMaterial class LifeCycleAssessment: @@ -39,6 +40,12 @@ class LifeCycleAssessment: """ LcaMachine(self._city, self._base_path).enrich() + def _material(self): + """ + Enrich the city by adding the material carbon information + """ + LcaMaterial(self._city, self._base_path).enrich() + def enrich(self): """ Enrich the city given to the class using the class given handler diff --git a/unittests/test_life_cycle_assessment_factory.py b/unittests/test_life_cycle_assessment_factory.py index 32e3453e..3245d56b 100644 --- a/unittests/test_life_cycle_assessment_factory.py +++ b/unittests/test_life_cycle_assessment_factory.py @@ -45,6 +45,14 @@ class TestLifeCycleAssessment(TestCase): # print(machine.name) self.assertTrue(len(city.machines) > 0) + def test_material(self): + city_file = "../unittests/tests_data/C40_Final.gml" + city = GeometryFactory('citygml', city_file).city + LifeCycleAssessment('material', city).enrich() + for material in city.materials: + print(material.material_name) + self.assertTrue(len(city.materials) > 0) + From 075e03396d3420df352fc683e4f55aeb71e599b6 Mon Sep 17 00:00:00 2001 From: atiya Date: Mon, 15 Nov 2021 08:24:03 -0500 Subject: [PATCH 3/3] Added LCA formulas --- city_model_structure/lca_calculations.py | 23 ++++ city_model_structure/material.py | 118 ++++++++++++++++++ imports/life_cycle_assessment_factory.py | 7 ++ .../test_life_cycle_assessment_factory.py | 8 ++ 4 files changed, 156 insertions(+) create mode 100644 city_model_structure/lca_calculations.py create mode 100644 city_model_structure/material.py diff --git a/city_model_structure/lca_calculations.py b/city_model_structure/lca_calculations.py new file mode 100644 index 00000000..032edcd6 --- /dev/null +++ b/city_model_structure/lca_calculations.py @@ -0,0 +1,23 @@ +""" +LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Atiya +""" +from city_model_structure.machine import Machine + +class LcaCalculations: + """ + LCA Calculations class + """ + + def __init__(self): + print("lca calculations class") + + def emission_disposal_machines(self, ): + return Machine.work_efficiency * Machine.energy_consumption_rate * Machine.carbon_emission_factor + + def emission_transportation(self, weight, distance ): + return weight * distance * Machine.energy_consumption_rate * Machine.carbon_emission_factor + + + diff --git a/city_model_structure/material.py b/city_model_structure/material.py new file mode 100644 index 00000000..d0ef2c53 --- /dev/null +++ b/city_model_structure/material.py @@ -0,0 +1,118 @@ +""" +LifeCycleAssessment retrieve the specific Life Cycle Assessment module for the given region +SPDX - License - Identifier: LGPL - 3.0 - or -later +Copyright © 2020 Project Author Atiya +""" + +class Material: + """ + LCA Material class + """ + + def __init__(self, material_name, material_id, type, density, density_unit, embodied_carbon, embodied_carbon_unit, recycling_ratio, + onsite_recycling_ratio, company_recycling_ratio, landfilling_ratio, cost, cost_unit): + self._material_name = material_name + self._material_id = material_id + self._type = type + self._density = density + self._density_unit = density_unit + self._embodied_carbon = embodied_carbon + self._embodied_carbon_unit = embodied_carbon_unit + self._recycling_ratio = recycling_ratio + self._onsite_recycling_ratio = onsite_recycling_ratio + self._company_recycling_ratio = company_recycling_ratio + self._landfilling_ratio = landfilling_ratio + self._cost = cost + self._cost_unit = cost_unit + + @property + def material_name(self): + """ + Get material name + """ + return self._material_name + + @property + def id(self): + """ + Get material id + """ + return self._material_id + + @property + def type(self): + """ + Get material type + """ + return self._type + + @property + def density(self): + """ + Get material density + """ + return self._density + + @property + def density_unit(self): + """ + Get material density unit + """ + return self._density_unit + + @property + def embodied_carbon(self): + """ + Get material embodied carbon + """ + return self._embodied_carbon + + @property + def embodied_carbon_unit(self): + """ + Get material embodied carbon unit + """ + return self._embodied_carbon_unit + + @property + def recycling_ratio(self): + """ + Get material recycling ratio + """ + return self._recycling_ratio + + @property + def onsite_recycling_ratio(self): + """ + Get material onsite recycling ratio + """ + return self._onsite_recycling_ratio + + @property + def company_recycling_ratio(self): + """ + Get material company recycling ratio + """ + return self._company_recycling_ratio + + @property + def landfilling_ratio(self): + """ + Get material landfilling ratio + """ + return self._landfilling_ratio + + @property + def cost(self): + """ + Get material cost + """ + return self._cost + + @property + def cost_unit(self): + """ + Get material cost unit + """ + return self._cost_unit + diff --git a/imports/life_cycle_assessment_factory.py b/imports/life_cycle_assessment_factory.py index 3aff1fe4..cb99b981 100644 --- a/imports/life_cycle_assessment_factory.py +++ b/imports/life_cycle_assessment_factory.py @@ -8,6 +8,7 @@ from pathlib import Path from imports.life_cycle_assessment.lca_fuel import LcaFuel from imports.life_cycle_assessment.lca_vehicle import LcaVehicle from imports.life_cycle_assessment.lca_machine import LcaMachine +from imports.life_cycle_assessment.lca_material import LcaMaterial class LifeCycleAssessment: @@ -39,6 +40,12 @@ class LifeCycleAssessment: """ LcaMachine(self._city, self._base_path).enrich() + def _material(self): + """ + Enrich the city by adding the material carbon information + """ + LcaMaterial(self._city, self._base_path).enrich() + def enrich(self): """ Enrich the city given to the class using the class given handler diff --git a/unittests/test_life_cycle_assessment_factory.py b/unittests/test_life_cycle_assessment_factory.py index 32e3453e..3245d56b 100644 --- a/unittests/test_life_cycle_assessment_factory.py +++ b/unittests/test_life_cycle_assessment_factory.py @@ -45,6 +45,14 @@ class TestLifeCycleAssessment(TestCase): # print(machine.name) self.assertTrue(len(city.machines) > 0) + def test_material(self): + city_file = "../unittests/tests_data/C40_Final.gml" + city = GeometryFactory('citygml', city_file).city + LifeCycleAssessment('material', city).enrich() + for material in city.materials: + print(material.material_name) + self.assertTrue(len(city.materials) > 0) +