hestia-earth-models 0.66.0__py3-none-any.whl → 0.67.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +23 -54
  2. hestia_earth/models/cml2001Baseline/resourceUseEnergyDepletionDuringCycle.py +147 -0
  3. hestia_earth/models/cml2001Baseline/resourceUseEnergyDepletionInputsProduction.py +40 -0
  4. hestia_earth/models/cml2001Baseline/resourceUseMineralsAndMetalsDuringCycle.py +80 -0
  5. hestia_earth/models/cml2001Baseline/resourceUseMineralsAndMetalsInputsProduction.py +40 -0
  6. hestia_earth/models/config/ImpactAssessment.json +1869 -1846
  7. hestia_earth/models/cycle/completeness/freshForage.py +7 -3
  8. hestia_earth/models/cycle/inorganicFertiliser.py +67 -17
  9. hestia_earth/models/cycle/input/hestiaAggregatedData.py +13 -10
  10. hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/__init__.py +4 -3
  11. hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/environmentalFootprintSingleOverallScore.py +42 -37
  12. hestia_earth/models/environmentalFootprintV3_1/marineEutrophicationPotential.py +36 -0
  13. hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +40 -0
  14. hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/soilQualityIndexLandTransformation.py +22 -14
  15. hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/soilQualityIndexTotalLandUseEffects.py +17 -15
  16. hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +1 -1
  17. hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +1 -1
  18. hestia_earth/models/impact_assessment/product/value.py +1 -1
  19. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +2 -2
  20. hestia_earth/models/ipcc2019/belowGroundBiomass.py +2 -2
  21. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +2 -1
  22. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +6 -5
  23. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +3 -2
  24. hestia_earth/models/mocking/search-results.json +1200 -1068
  25. hestia_earth/models/site/management.py +2 -2
  26. hestia_earth/models/utils/__init__.py +6 -0
  27. hestia_earth/models/utils/aggregated.py +13 -10
  28. hestia_earth/models/utils/array_builders.py +4 -3
  29. hestia_earth/models/utils/blank_node.py +78 -21
  30. hestia_earth/models/utils/ecoClimateZone.py +2 -2
  31. hestia_earth/models/utils/impact_assessment.py +5 -4
  32. hestia_earth/models/utils/lookup.py +5 -5
  33. hestia_earth/models/utils/property.py +5 -2
  34. hestia_earth/models/version.py +1 -1
  35. hestia_earth/orchestrator/log.py +11 -0
  36. hestia_earth/orchestrator/models/__init__.py +8 -3
  37. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.1.dist-info}/METADATA +1 -1
  38. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.1.dist-info}/RECORD +64 -52
  39. tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +51 -87
  40. tests/models/cml2001Baseline/test_resourceUseEnergyDepletionDuringCycle.py +136 -0
  41. tests/models/cml2001Baseline/test_resourceUseEnergyDepletionInputsProduction.py +23 -0
  42. tests/models/cml2001Baseline/test_resourceUseMineralsAndMetalsDuringCycle.py +58 -0
  43. tests/models/cml2001Baseline/test_resourceUseMineralsAndMetalsInputsProduction.py +23 -0
  44. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_environmentalFootprintSingleOverallScore.py +43 -12
  45. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_freshwaterEcotoxicityPotentialCtue.py +6 -5
  46. tests/models/environmentalFootprintV3_1/test_marineEutrophicationPotential.py +27 -0
  47. tests/models/environmentalFootprintV3_1/test_scarcityWeightedWaterUse.py +32 -0
  48. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_soilQualityIndexLandOccupation.py +4 -3
  49. tests/models/environmentalFootprintV3_1/test_soilQualityIndexLandTransformation.py +194 -0
  50. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_soilQualityIndexTotalLandUseEffects.py +4 -4
  51. tests/models/impact_assessment/test_emissions.py +0 -1
  52. tests/models/site/test_management.py +1 -4
  53. tests/models/test_config.py +3 -3
  54. tests/models/test_ecoinventV3.py +0 -1
  55. tests/models/utils/test_array_builders.py +2 -2
  56. tests/models/utils/test_blank_node.py +13 -165
  57. tests/orchestrator/models/test_transformations.py +4 -1
  58. tests/models/environmentalFootprintV3/test_soilQualityIndexLandTransformation.py +0 -164
  59. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/freshwaterEcotoxicityPotentialCtue.py +0 -0
  60. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/soilQualityIndexLandOccupation.py +0 -0
  61. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/utils.py +0 -0
  62. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.1.dist-info}/LICENSE +0 -0
  63. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.1.dist-info}/WHEEL +0 -0
  64. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.1.dist-info}/top_level.txt +0 -0
  65. /tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/__init__.py +0 -0
@@ -0,0 +1,136 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ import pytest
5
+
6
+ from hestia_earth.models.cml2001Baseline.resourceUseEnergyDepletionDuringCycle import MODEL, TERM_ID, run, _should_run
7
+ from tests.utils import fixtures_path, fake_new_indicator
8
+
9
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
10
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
11
+
12
+ diesel_input = {
13
+ "term": {"termType": "fuel", "units": "kg", "@id": "diesel"},
14
+ "value": 2,
15
+ "properties": [{"term": {"@id": "energyContentLowerHeatingValue", }, "value": 70}]
16
+ }
17
+ diesel_input_in_mj = {
18
+ "term": {"termType": "fuel", "units": "MJ", "@id": "diesel"},
19
+ "value": 111
20
+ }
21
+ diesel_input_wrong_unit = {
22
+ "term": {"termType": "fuel", "units": "foobedoos", "@id": "diesel"},
23
+ "value": 2
24
+ }
25
+ diesel_input_no_unit = {
26
+ "term": {"termType": "fuel", "@id": "diesel"},
27
+ "value": 2
28
+ }
29
+ diesel_input_with_properties = {
30
+ "term": {"termType": "fuel", "units": "kg", "@id": "diesel"},
31
+ "value": 2,
32
+ "properties": [{"term": {"@id": "energyContentLowerHeatingValue", }, "value": 70}]
33
+ }
34
+ diesel_input_with_properties2 = {
35
+ "term": {"termType": "fuel", "units": "kg", "@id": "diesel"},
36
+ "value": 2,
37
+ "properties": [{"term": {"@id": "energyContentLowerHeatingValue", }, "value": 4}]
38
+ }
39
+
40
+ electricity_input = {
41
+ "term": {"termType": "electricity", "units": "kWh", "@id": "electricityGridOil"},
42
+ "value": 30
43
+ }
44
+
45
+ input_coal_tar_kg = {
46
+ "term": {"@id": "coalTar", "termType": "fuel", "units": "kg", "name": "Coal tar unknown energy Content"},
47
+ "value": 5
48
+ }
49
+
50
+ input_crude_oil_kg_property = {
51
+ "term": {"@id": "conventionalCrudeOil", "termType": "fuel", "units": "kg"},
52
+ "value": 5,
53
+ "properties": [{
54
+ "@type": "Property",
55
+ "value": 45.8,
56
+ "term": {"@type": "Term", "@id": "energyContentLowerHeatingValue", "units": "MJ / kg"},
57
+ }]
58
+ }
59
+
60
+ input_natural_gas_m3 = {
61
+ "term": {"@id": "naturalGas", "termType": "fuel", "units": "m3"},
62
+ "value": 5,
63
+ "properties": [{
64
+ "@type": "Property",
65
+ "value": 45.8,
66
+ "term": {"@type": "Term", "@id": "energyContentLowerHeatingValue", "units": "MJ / kg"},
67
+ }, {
68
+ "@type": "Property",
69
+ "value": 45.8,
70
+ "term": {"@type": "Term", "@id": "density", "units": "kg / m3"},
71
+ }]
72
+ }
73
+
74
+ input_nuclear_fuel_kwh = {
75
+ "term": {"@id": "electricityGridNuclear", "termType": "electricity", "units": "kWh"},
76
+ "value": 1.3889
77
+ }
78
+
79
+
80
+ @pytest.mark.parametrize(
81
+ "inputs, expected, num_inputs",
82
+ [
83
+ ([], False, 0),
84
+ ([diesel_input_wrong_unit], False, 0),
85
+ ([diesel_input_no_unit], False, 0),
86
+ ([diesel_input], True, 1),
87
+ ([diesel_input, diesel_input, diesel_input_in_mj], True, 1),
88
+ ([diesel_input, diesel_input_with_properties], True, 1),
89
+ ([diesel_input_with_properties, diesel_input_with_properties], True, 1),
90
+ ([diesel_input_with_properties2, diesel_input_with_properties], True, 1),
91
+ ([electricity_input], True, 1),
92
+ ([electricity_input, electricity_input, electricity_input], True, 1),
93
+ ([input_crude_oil_kg_property], True, 1),
94
+ ([input_natural_gas_m3], True, 1),
95
+ ([input_nuclear_fuel_kwh], True, 1),
96
+ ([input_coal_tar_kg], False, 0),
97
+ ],
98
+ ids=[
99
+ "No inputs => no run, empty input",
100
+ "bad input unit => no run, empty input",
101
+ "bad input no unit => no run, empty input",
102
+ "good fuel input => run",
103
+ "multiple good merg-able fuel inputs => run",
104
+ "multiple good distinct fuel inputs => run",
105
+ "multiple good fuel inputs with same prop=> run",
106
+ "multiple good fuel inputs with distinct prop=> run",
107
+ "good electric input => run",
108
+ "multiple good merg-able electric inputs => run",
109
+ "good fuel with input property",
110
+ "good fuel in m^3",
111
+ "good nuclear fuel use indicator in kWh",
112
+ "bad indicator input in kg no property to convert to mj"
113
+ ]
114
+ )
115
+ @patch('hestia_earth.models.utils.property.download_hestia', return_value={})
116
+ def test_should_run(mock_download, inputs, expected, num_inputs):
117
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
118
+ cycle = json.load(f)
119
+
120
+ cycle['inputs'] = inputs
121
+
122
+ should_run, grouped_energy_terms = _should_run(cycle)
123
+ assert should_run is expected
124
+ assert len(grouped_energy_terms.keys()) == num_inputs
125
+
126
+
127
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
128
+ def test_run(*args):
129
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
130
+ cycle = json.load(f)
131
+
132
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
133
+ expected = json.load(f)
134
+
135
+ value = run(cycle)
136
+ assert value == expected
@@ -0,0 +1,23 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ from hestia_earth.models.cml2001Baseline import MODEL
5
+ from hestia_earth.models.cml2001Baseline.resourceUseEnergyDepletionInputsProduction import TERM_ID, run
6
+ from tests.utils import fixtures_path, fake_new_indicator, fake_load_impacts
7
+
8
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
9
+ utils_class_path = "hestia_earth.models.linkedImpactAssessment.utils"
10
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
11
+
12
+
13
+ @patch(f"{utils_class_path}.load_impacts", side_effect=fake_load_impacts)
14
+ @patch(f"{utils_class_path}._new_indicator", side_effect=fake_new_indicator)
15
+ def test_run(*args):
16
+ with open(f"{fixtures_folder}/impact-assessment.jsonld", encoding='utf-8') as f:
17
+ impact = json.load(f)
18
+
19
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
20
+ expected = json.load(f)
21
+
22
+ value = run(impact)
23
+ assert value == expected
@@ -0,0 +1,58 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ import pytest
5
+
6
+ from hestia_earth.models.cml2001Baseline.resourceUseMineralsAndMetalsDuringCycle import MODEL, TERM_ID, run, _should_run
7
+ from tests.utils import fixtures_path, fake_new_indicator
8
+
9
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
10
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
11
+
12
+ antimony = {"term": {"termType": "material", "@id": "antimony", "units": "kg"}, "value": [3]}
13
+ antimony_bad_unit = {"term": {"termType": "material", "@id": "antimony", "units": "boogiewoogiw"}, "value": [3]}
14
+ boron = {"term": {"termType": "soilAmendment", "@id": "boron", "units": "kg"}, "value": [3]}
15
+ tellurium = {"term": {"termType": "otherInorganicChemical", "@id": "CAS-13494-80-9", "units": "kg"}, "value": [30]}
16
+
17
+
18
+ @pytest.mark.parametrize(
19
+ "cycle_inputs, expected, num_inputs",
20
+ [
21
+ ([], False, 0),
22
+ ([antimony_bad_unit], False, 0),
23
+ ([antimony], True, 1),
24
+ ([antimony, antimony, antimony], True, 1),
25
+ ([antimony, boron], True, 2),
26
+ ([antimony, boron, tellurium], True, 3),
27
+
28
+ ],
29
+ ids=[
30
+ "No inputs => no run, empty input",
31
+ "bad input => no run, empty input",
32
+ "good fuel input => run",
33
+ "multiple good merg-able material inputs => run",
34
+ "multiple good non merg-able material inputs => run",
35
+ "all termTypes inputs => run",
36
+ ]
37
+ )
38
+ def test_should_run(cycle_inputs, expected, num_inputs):
39
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
40
+ cycle = json.load(f)
41
+
42
+ cycle['inputs'] = cycle_inputs
43
+
44
+ should_run, grouped_energy_terms = _should_run(cycle)
45
+ assert should_run is expected
46
+ assert len(grouped_energy_terms.keys()) == num_inputs
47
+
48
+
49
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
50
+ def test_run(*args):
51
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
52
+ cycle = json.load(f)
53
+
54
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
55
+ expected = json.load(f)
56
+
57
+ value = run(cycle)
58
+ assert value == expected
@@ -0,0 +1,23 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ from hestia_earth.models.cml2001Baseline import MODEL
5
+ from hestia_earth.models.cml2001Baseline.resourceUseMineralsAndMetalsInputsProduction import TERM_ID, run
6
+ from tests.utils import fixtures_path, fake_new_indicator, fake_load_impacts
7
+
8
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
9
+ utils_class_path = "hestia_earth.models.linkedImpactAssessment.utils"
10
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
11
+
12
+
13
+ @patch(f"{utils_class_path}.load_impacts", side_effect=fake_load_impacts)
14
+ @patch(f"{utils_class_path}._new_indicator", side_effect=fake_new_indicator)
15
+ def test_run(*args):
16
+ with open(f"{fixtures_folder}/impact-assessment.jsonld", encoding='utf-8') as f:
17
+ impact = json.load(f)
18
+
19
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
20
+ expected = json.load(f)
21
+
22
+ value = run(impact)
23
+ assert value == expected
@@ -3,12 +3,13 @@ from unittest.mock import patch, Mock
3
3
 
4
4
  from pytest import mark
5
5
 
6
- from hestia_earth.models.environmentalFootprintV3.environmentalFootprintSingleOverallScore import MODEL, TERM_ID, run, \
7
- _should_run
6
+ from hestia_earth.models.environmentalFootprintV3_1 import MODEL_FOLDER
7
+ from hestia_earth.models.environmentalFootprintV3_1.environmentalFootprintSingleOverallScore import MODEL, TERM_ID, \
8
+ run, _should_run
8
9
  from tests.utils import fixtures_path, fake_new_indicator
9
10
 
10
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
11
+ class_path = f"hestia_earth.models.{MODEL_FOLDER}.{TERM_ID}"
12
+ fixtures_folder = f"{fixtures_path}/{MODEL_FOLDER}/{TERM_ID}"
12
13
 
13
14
 
14
15
  def fake_rounded_indicator(value: float):
@@ -17,31 +18,55 @@ def fake_rounded_indicator(value: float):
17
18
  return indicator
18
19
 
19
20
 
21
+ methodModelEFV31 = {"@type": "Term", "@id": "environmentalFootprintV3-1"}
22
+ methodModelFantkeEtAl2016 = {"@type": "Term", "@id": "fantkeEtAl2016"}
23
+
20
24
  ozone_indicator = {"@type": "Indicator",
21
25
  "term": {"@id": "ozoneDepletionPotential", "termType": "characterisedIndicator"},
22
- "value": 0}
26
+ "value": 0,
27
+ "methodModel": {"@type": "Term", "@id": "edip2003"}}
23
28
 
29
+ other_valid_ozone_indicator = {"@type": "Indicator",
30
+ "term": {"@id": "ozoneDepletionPotential", "termType": "characterisedIndicator"},
31
+ "value": 0,
32
+ "methodModel": {"@type": "Term", "@id": "recipe2016Hierarchist"}}
24
33
  acid_indicator = {
25
34
  "@type": "Indicator",
26
35
  "term": {"@id": "terrestrialAcidificationPotentialAccumulatedExceedance", "termType": "characterisedIndicator"},
27
- "value": 0.000420443840380047}
36
+ "value": 0.000420443840380047,
37
+ "methodModel": {"@type": "Term", "@id": "poschEtAl2008"}
38
+ }
28
39
 
29
40
  bad_indicator_id = {"@type": "Indicator",
30
41
  "term": {"@id": "no_a_real_id", "termType": "characterisedIndicator"},
31
- "value": 0.000420443840380047}
42
+ "value": 0.000420443840380047,
43
+ "methodModel": methodModelEFV31
44
+ }
32
45
 
33
46
  not_pef_indicator = {"@type": "Indicator",
34
47
  "term": {"@id": "gwpStar", "termType": "characterisedIndicator"},
35
- "value": 0.000420443840380047}
48
+ "value": 0.000420443840380047,
49
+ "methodModel": methodModelEFV31
50
+ }
36
51
 
37
52
  bad_indicator_no_val = {"@type": "Indicator",
38
53
  "term": {"@id": "damageToHumanHealthParticulateMatterFormation",
39
- "termType": "characterisedIndicator"}}
54
+ "termType": "characterisedIndicator"},
55
+ "methodModel": methodModelFantkeEtAl2016
56
+ }
40
57
 
41
58
  bad_indicator_bad_val = {"@type": "Indicator",
42
59
  "term": {"@id": "damageToHumanHealthParticulateMatterFormation",
43
60
  "termType": "characterisedIndicator"},
44
- "value": None}
61
+ "value": None,
62
+ "methodModel": methodModelFantkeEtAl2016
63
+ }
64
+
65
+ bad_indicator_no_method_model = {
66
+ "@type": "Indicator",
67
+ "term": {"@id": "terrestrialAcidificationPotentialAccumulatedExceedance", "termType": "characterisedIndicator"},
68
+ "value": 0.000420443840380047
69
+ }
45
70
 
46
71
 
47
72
  @mark.parametrize(
@@ -52,10 +77,13 @@ bad_indicator_bad_val = {"@type": "Indicator",
52
77
  ([not_pef_indicator], False, 0),
53
78
  ([bad_indicator_no_val], False, 0),
54
79
  ([bad_indicator_bad_val], False, 0),
80
+ ([bad_indicator_no_method_model], False, 0),
81
+ ([other_valid_ozone_indicator], False, 0),
55
82
  ([ozone_indicator], True, 1),
56
83
  ([ozone_indicator, ozone_indicator], False, 2),
57
84
  ([ozone_indicator, acid_indicator], True, 2),
58
- ([bad_indicator_no_val, acid_indicator], False, 1)
85
+ ([ozone_indicator, other_valid_ozone_indicator], True, 1),
86
+ ([bad_indicator_no_val, acid_indicator], False, 1),
59
87
  ],
60
88
  ids=[
61
89
  "No indicators => no run",
@@ -63,9 +91,12 @@ bad_indicator_bad_val = {"@type": "Indicator",
63
91
  "not_pef_indicator => no run",
64
92
  "bad_indicator_no_val => no run",
65
93
  "bad_indicator_bad_val => no run",
66
- "ozone_indicator => run",
94
+ "bad_indicator_no_method_model => no run",
95
+ "ozone_indicator not pef=> no run",
96
+ "ozone_indicator pef => run",
67
97
  "2 ozone_indicator => no run",
68
98
  "2 good indicators => run",
99
+ "2 ozone_indicator different methodModel => run with 1",
69
100
  "one bad one good indicator => no run",
70
101
  ]
71
102
  )
@@ -1,11 +1,12 @@
1
- from unittest.mock import patch
2
1
  import json
3
- from tests.utils import fixtures_path, fake_new_indicator
2
+ from unittest.mock import patch
4
3
 
5
- from hestia_earth.models.environmentalFootprintV3.freshwaterEcotoxicityPotentialCtue import MODEL, TERM_ID, run
4
+ from hestia_earth.models.environmentalFootprintV3_1 import MODEL_FOLDER
5
+ from hestia_earth.models.environmentalFootprintV3_1.freshwaterEcotoxicityPotentialCtue import TERM_ID, run
6
+ from tests.utils import fixtures_path, fake_new_indicator
6
7
 
7
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
8
+ class_path = f"hestia_earth.models.{MODEL_FOLDER}.{TERM_ID}"
9
+ fixtures_folder = f"{fixtures_path}/{MODEL_FOLDER}/{TERM_ID}"
9
10
 
10
11
 
11
12
  with open(f"{fixtures_path}/impact_assessment/emissions/impact-assessment.jsonld", encoding='utf-8') as f:
@@ -0,0 +1,27 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ from hestia_earth.models.environmentalFootprintV3_1 import MODEL_FOLDER
5
+ from hestia_earth.models.environmentalFootprintV3_1.marineEutrophicationPotential import MODEL, TERM_ID, run
6
+ from tests.utils import fixtures_path, fake_new_indicator
7
+
8
+ class_path = f"hestia_earth.models.{MODEL_FOLDER}.{TERM_ID}"
9
+ fixtures_folder = f"{fixtures_path}/{MODEL_FOLDER}/{TERM_ID}"
10
+
11
+
12
+ def fake_rounded_indicator(value: float):
13
+ indicator = fake_new_indicator(TERM_ID, MODEL)
14
+ indicator['value'] = round(value, 7)
15
+ return indicator
16
+
17
+
18
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
19
+ def test_run(*args):
20
+ with open(f"{fixtures_folder}/impact-assessment.jsonld", encoding='utf-8') as f:
21
+ impactassessment = json.load(f)
22
+
23
+ with open(f"{fixtures_folder}/region-world/result.jsonld", encoding='utf-8') as f:
24
+ expected = json.load(f)
25
+
26
+ value = run(impactassessment)
27
+ assert value == expected
@@ -0,0 +1,32 @@
1
+ import json
2
+ import os
3
+ from unittest.mock import patch
4
+
5
+ from pytest import mark
6
+
7
+ from hestia_earth.models.environmentalFootprintV3_1 import MODEL_FOLDER
8
+ from hestia_earth.models.environmentalFootprintV3_1.scarcityWeightedWaterUse import MODEL, TERM_ID, run
9
+ from tests.utils import fixtures_path, fake_new_indicator
10
+
11
+ class_path = f"hestia_earth.models.{MODEL_FOLDER}.{TERM_ID}"
12
+ fixtures_folder = f"{fixtures_path}/{MODEL_FOLDER}/{TERM_ID}"
13
+ _folders = [d for d in os.listdir(fixtures_folder) if os.path.isdir(os.path.join(fixtures_folder, d))]
14
+
15
+
16
+ def fake_rounded_indicator(value: float):
17
+ indicator = fake_new_indicator(TERM_ID, MODEL)
18
+ indicator['value'] = round(value, 13)
19
+ return indicator
20
+
21
+
22
+ @mark.parametrize("folder", _folders)
23
+ @patch(f"{class_path}._indicator", side_effect=fake_rounded_indicator)
24
+ def test_run(mock_indicator, folder):
25
+ with open(f"{fixtures_folder}/{folder}/impactassessment.jsonld", encoding='utf-8') as f:
26
+ impactassessment = json.load(f)
27
+
28
+ with open(f"{fixtures_folder}/{folder}/result.jsonld", encoding='utf-8') as f:
29
+ expected = json.load(f)
30
+
31
+ value = run(impactassessment)
32
+ assert value == expected, folder
@@ -3,12 +3,13 @@ from unittest.mock import patch
3
3
 
4
4
  import pytest
5
5
 
6
- from hestia_earth.models.environmentalFootprintV3.soilQualityIndexLandOccupation import MODEL, TERM_ID, run, \
6
+ from hestia_earth.models.environmentalFootprintV3_1 import MODEL_FOLDER
7
+ from hestia_earth.models.environmentalFootprintV3_1.soilQualityIndexLandOccupation import TERM_ID, run, \
7
8
  _should_run
8
9
  from tests.utils import fixtures_path, fake_new_indicator
9
10
 
10
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
11
+ class_path = f"hestia_earth.models.{MODEL_FOLDER}.{TERM_ID}"
12
+ fixtures_folder = f"{fixtures_path}/{MODEL_FOLDER}/{TERM_ID}"
12
13
 
13
14
  crop_land = {"@id": "cropland", "termType": "landCover"}
14
15
  sea_land_cover = {"@id": "seaOrOcean", "termType": "landCover"}
@@ -0,0 +1,194 @@
1
+ import json
2
+ from unittest.mock import Mock, patch
3
+
4
+ from pytest import mark
5
+
6
+ from hestia_earth.models.environmentalFootprintV3_1 import MODEL_FOLDER
7
+ from hestia_earth.models.environmentalFootprintV3_1.soilQualityIndexLandTransformation import (
8
+ MODEL, TERM_ID, run, _should_run
9
+ )
10
+ from tests.utils import fixtures_path, fake_new_indicator
11
+
12
+ class_path = f"hestia_earth.models.{MODEL_FOLDER}.{TERM_ID}"
13
+ fixtures_folder = f"{fixtures_path}/{MODEL_FOLDER}/{TERM_ID}"
14
+
15
+
16
+ def fake_rounded_indicator(value: float):
17
+ indicator = fake_new_indicator(TERM_ID, MODEL)
18
+ indicator['value'] = round(value, 7)
19
+ return indicator
20
+
21
+
22
+ crop_land = {"@id": "cropland", "termType": "landCover"}
23
+ sea_land_cover = {"@id": "seaOrOcean", "termType": "landCover"}
24
+ forest = {"@id": "forest", "termType": "landCover"}
25
+
26
+ indicator_inputs_production = {
27
+ "@id": "landTransformation20YearAverageInputsProduction",
28
+ "termType": "resourceUse",
29
+ "units": "m2 / year"
30
+ }
31
+
32
+ indicator_during_cycle = {
33
+ "@id": "landTransformation20YearAverageDuringCycle",
34
+ "termType": "resourceUse",
35
+ "units": "m2 / year"
36
+ }
37
+
38
+ wrong_indicator = {"term": {"@id": "NOT_VALID_INDICATOR_ID", "termType": "resourceUse", "units": "m2 / year"},
39
+ "value": 0.5, "landCover": crop_land, "previousLandCover": forest}
40
+
41
+ indicator_no_land_cover = {
42
+ "term": indicator_during_cycle,
43
+ "previousLandCover": forest,
44
+ "value": 0.5}
45
+
46
+ indicator_no_previous_land_cover = {
47
+ "term": indicator_during_cycle,
48
+ "landCover": crop_land,
49
+ "value": 0.5}
50
+
51
+ indicator_bad_area_value = {
52
+ "term": indicator_during_cycle,
53
+ "value": -10,
54
+ "previousLandCover": forest,
55
+ "landCover": crop_land}
56
+
57
+ indicator_zero_area_value = {
58
+ "term": indicator_during_cycle,
59
+ "value": 0,
60
+ "previousLandCover": forest,
61
+ "landCover": crop_land}
62
+
63
+ inputs_production_indicator_from_forest_to_no_cf = {
64
+ "term": indicator_inputs_production,
65
+ "value": 0.5,
66
+ "previousLandCover": forest,
67
+ "landCover": sea_land_cover}
68
+
69
+ during_cycle_indicator_from_forest_to_no_cf = {
70
+ "term": indicator_during_cycle,
71
+ "value": 0.5,
72
+ "previousLandCover": forest,
73
+ "landCover": sea_land_cover}
74
+
75
+ good_inputs_production_indicator_from_forest_to_cropland = {
76
+ "term": indicator_inputs_production,
77
+ "value": 0.5,
78
+ "previousLandCover": forest,
79
+ "landCover": crop_land}
80
+
81
+ good_inputs_production_indicator_from_forest_to_forest = {
82
+ "term": indicator_inputs_production,
83
+ "value": 0.5,
84
+ "previousLandCover": forest,
85
+ "landCover": forest}
86
+
87
+ good_during_cycle_indicator_from_forest_to_cropland = {
88
+ "term": indicator_during_cycle,
89
+ "value": 0.5,
90
+ "previousLandCover": forest,
91
+ "landCover": crop_land}
92
+
93
+ good_during_cycle_indicator_from_forest_to_forest = {
94
+ "term": indicator_during_cycle,
95
+ "value": 0.5,
96
+ "previousLandCover": forest,
97
+ "landCover": forest}
98
+
99
+
100
+ @mark.parametrize(
101
+ "test_name, resources, expected, num_inputs",
102
+ [
103
+ ("No emissionsResourceUse => no run, 0 dict", [], False, 0),
104
+ ("Wrong indicator termid => no run, 0 dict", [wrong_indicator], False, 0),
105
+ ("Indicator no landcover terms => no run", [indicator_no_land_cover], False, 0),
106
+ ("Indicator no previousLandCover terms => no run", [indicator_no_previous_land_cover], False, 0),
107
+ ("Bad m2 / year area value => no run", [indicator_bad_area_value], False, 0),
108
+ ("One good and one Bad m2 / year area value => no run", [
109
+ good_during_cycle_indicator_from_forest_to_cropland,
110
+ indicator_bad_area_value], False, 1),
111
+ ("One 0 m2 / year area value => filter and run, 0 dict", [indicator_zero_area_value], True, 1),
112
+ ("One good during cycle transformation => run, 1 dict", [good_during_cycle_indicator_from_forest_to_cropland
113
+ ], True, 1),
114
+ ("One 0 during cycle transformation => run, 1 dict", [good_during_cycle_indicator_from_forest_to_forest
115
+ ], True, 1),
116
+ ("Only one good inputs production transformation => no run", [
117
+ good_inputs_production_indicator_from_forest_to_cropland], False, 1),
118
+ ("Good during cycle AND inputs production transformation => run, 2 dict", [
119
+ good_during_cycle_indicator_from_forest_to_cropland,
120
+ good_inputs_production_indicator_from_forest_to_cropland], True, 2),
121
+ ("One 0 inputs production transformation => no run", [
122
+ good_inputs_production_indicator_from_forest_to_forest], False, 1),
123
+ ("Good during cycle AND inputs production 0 transformation => run, 2 dict", [
124
+ good_during_cycle_indicator_from_forest_to_cropland,
125
+ good_inputs_production_indicator_from_forest_to_forest], True, 2),
126
+ ("One transformation with no CF (ocean) => run, 0 dict", [during_cycle_indicator_from_forest_to_no_cf
127
+ ], True, 0),
128
+ ("One good from transformation and One with no CF (ocean) => run, 1 dict", [
129
+ good_inputs_production_indicator_from_forest_to_cropland,
130
+ during_cycle_indicator_from_forest_to_no_cf], True, 1),
131
+ ("Multiple good indicators => run, 2 dict", [good_inputs_production_indicator_from_forest_to_cropland,
132
+ good_during_cycle_indicator_from_forest_to_cropland], True, 2),
133
+ ("One good, one wrong indicator => filter and run, 1 dict", [
134
+ good_during_cycle_indicator_from_forest_to_cropland,
135
+ wrong_indicator], True, 1),
136
+ ]
137
+ )
138
+ def test_should_run(test_name: str, resources: list, expected: bool, num_inputs: int):
139
+ with open(f"{fixtures_folder}/multipleTransformations/impact-assessment.jsonld", encoding='utf-8') as f:
140
+ impact = json.load(f)
141
+
142
+ impact['emissionsResourceUse'] = resources
143
+
144
+ should_run, resources_with_cf = _should_run(impact)
145
+ assert should_run is expected
146
+ assert len(resources_with_cf) == num_inputs
147
+
148
+
149
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
150
+ def test_run(*args):
151
+ with open(f"{fixtures_folder}/multipleTransformations/impact-assessment.jsonld", encoding='utf-8') as f:
152
+ impact = json.load(f)
153
+
154
+ with open(f"{fixtures_folder}/multipleTransformations/result.jsonld", encoding='utf-8') as f:
155
+ expected = json.load(f)
156
+
157
+ value = run(impact)
158
+ assert value == expected
159
+
160
+
161
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
162
+ def test_run_italy(*args):
163
+ with open(f"{fixtures_folder}/Italy/impact-assessment.jsonld", encoding='utf-8') as f:
164
+ impact = json.load(f)
165
+
166
+ with open(f"{fixtures_folder}/Italy/result.jsonld", encoding='utf-8') as f:
167
+ expected = json.load(f)
168
+
169
+ value = run(impact)
170
+ assert value == expected
171
+
172
+
173
+ @mark.parametrize(
174
+ "added_data",
175
+ [
176
+ {"country": {}},
177
+ {"country": {"@id": "region-europe", "@type": "Term", "name": "Europe"}},
178
+ ],
179
+ ids=["No country/region => default to region world",
180
+ "region-europe not in the lookup file => default to region world"]
181
+ )
182
+ @patch(f"{class_path}._indicator", side_effect=fake_rounded_indicator)
183
+ def test_run_with_country_fallback(mocked_indicator: Mock, added_data: dict):
184
+ """
185
+ When given valid sub-region or country not in the lookup file, default to country 'region-world' with value 574.56
186
+ """
187
+
188
+ with open(f"{fixtures_folder}/multipleTransformations/impact-assessment.jsonld", encoding='utf-8') as f:
189
+ impact = json.load(f)
190
+
191
+ impact = impact | added_data
192
+
193
+ value = run(impact)
194
+ assert value['value'] == 574.56
@@ -3,12 +3,12 @@ from unittest.mock import patch
3
3
 
4
4
  from pytest import mark
5
5
 
6
- from hestia_earth.models.environmentalFootprintV3.soilQualityIndexTotalLandUseEffects import MODEL, TERM_ID, run, \
7
- _should_run
6
+ from hestia_earth.models.environmentalFootprintV3_1 import MODEL_FOLDER
7
+ from hestia_earth.models.environmentalFootprintV3_1.soilQualityIndexTotalLandUseEffects import TERM_ID, run, _should_run
8
8
  from tests.utils import fixtures_path, fake_new_indicator
9
9
 
10
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
10
+ class_path = f"hestia_earth.models.{MODEL_FOLDER}.{TERM_ID}"
11
+ fixtures_folder = f"{fixtures_path}/{MODEL_FOLDER}/{TERM_ID}"
12
12
 
13
13
  transform_indicator = {'term': {'@id': 'soilQualityIndexLandTransformation'}, 'value': 10}
14
14
  occupation_indicator = {'term': {'@id': 'soilQualityIndexLandOccupation'}, 'value': 10}
@@ -28,5 +28,4 @@ def test_run(*args):
28
28
  expected = json.load(f)
29
29
 
30
30
  value = run(impact)
31
- print(json.dumps(value))
32
31
  assert value == expected