hestia-earth-models 0.73.8__py3-none-any.whl → 0.74.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.

Potentially problematic release.


This version of hestia-earth-models might be problematic. Click here for more details.

Files changed (59) hide show
  1. hestia_earth/models/aware/scarcityWeightedWaterUse.py +7 -6
  2. hestia_earth/models/aware2_0/__init__.py +14 -0
  3. hestia_earth/models/aware2_0/scarcityWeightedWaterUse.py +115 -0
  4. hestia_earth/models/config/Cycle.json +5 -3
  5. hestia_earth/models/config/ImpactAssessment.json +1 -1
  6. hestia_earth/models/config/__init__.py +26 -2
  7. hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +2 -2
  8. hestia_earth/models/cycle/animal/input/properties.py +6 -5
  9. hestia_earth/models/cycle/animal/milkYield.py +8 -3
  10. hestia_earth/models/cycle/utils.py +6 -6
  11. hestia_earth/models/data/ecoinventV3/__init__.py +8 -26
  12. hestia_earth/models/ecoalimV9/cycle.py +26 -10
  13. hestia_earth/models/ecoalimV9/impact_assessment.py +30 -10
  14. hestia_earth/models/ecoalimV9/utils.py +12 -72
  15. hestia_earth/models/ecoinventV3/__init__.py +8 -140
  16. hestia_earth/models/ecoinventV3/cycle.py +140 -0
  17. hestia_earth/models/ecoinventV3/utils.py +28 -1
  18. hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +8 -137
  19. hestia_earth/models/ecoinventV3AndEmberClimate/cycle.py +144 -0
  20. hestia_earth/models/emepEea2019/utils.py +2 -3
  21. hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +5 -7
  22. hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +41 -43
  23. hestia_earth/models/geospatialDatabase/awareWaterBasinId.py +2 -2
  24. hestia_earth/models/geospatialDatabase/awareWaterBasinId_v1.py +45 -0
  25. hestia_earth/models/hestia/default_emissions.py +5 -1
  26. hestia_earth/models/hestia/default_resourceUse.py +5 -1
  27. hestia_earth/models/hestia/landCover.py +110 -12
  28. hestia_earth/models/hestia/utils.py +1 -0
  29. hestia_earth/models/hestia/waterSalinity.py +2 -3
  30. hestia_earth/models/impact_assessment/emissions.py +1 -1
  31. hestia_earth/models/linkedImpactAssessment/emissions.py +2 -2
  32. hestia_earth/models/log.py +8 -3
  33. hestia_earth/models/mocking/search-results.json +1562 -1558
  34. hestia_earth/models/transformation/product/excreta.py +2 -2
  35. hestia_earth/models/utils/__init__.py +3 -0
  36. hestia_earth/models/utils/background_emissions.py +109 -9
  37. hestia_earth/models/utils/blank_node.py +1 -11
  38. hestia_earth/models/utils/feedipedia.py +2 -2
  39. hestia_earth/models/utils/impact_assessment.py +1 -3
  40. hestia_earth/models/utils/lookup.py +1 -1
  41. hestia_earth/models/version.py +1 -1
  42. hestia_earth/orchestrator/log.py +8 -3
  43. {hestia_earth_models-0.73.8.dist-info → hestia_earth_models-0.74.1.dist-info}/METADATA +2 -2
  44. {hestia_earth_models-0.73.8.dist-info → hestia_earth_models-0.74.1.dist-info}/RECORD +59 -50
  45. tests/models/aware2_0/__init__.py +0 -0
  46. tests/models/aware2_0/test_scarcityWeightedWaterUse.py +58 -0
  47. tests/models/ecoinventV3/__init__.py +0 -0
  48. tests/models/{test_ecoinventV3.py → ecoinventV3/test_cycle.py} +5 -5
  49. tests/models/ecoinventV3AndEmberClimate/__init__.py +0 -0
  50. tests/models/{test_ecoinventV3AndEmberClimate.py → ecoinventV3AndEmberClimate/test_cycle.py} +6 -4
  51. tests/models/environmentalFootprintV3_1/test_environmentalFootprintSingleOverallScore.py +2 -2
  52. tests/models/frischknechtEtAl2000/test_ionisingRadiationKbqU235Eq.py +18 -27
  53. tests/models/hestia/test_landCover.py +16 -6
  54. tests/models/site/pre_checks/test_cache_geospatialDatabase.py +4 -4
  55. tests/models/test_config.py +53 -7
  56. tests/models/{ecoalimV9/test_utils.py → utils/test_background_emissions.py} +2 -2
  57. {hestia_earth_models-0.73.8.dist-info → hestia_earth_models-0.74.1.dist-info}/LICENSE +0 -0
  58. {hestia_earth_models-0.73.8.dist-info → hestia_earth_models-0.74.1.dist-info}/WHEEL +0 -0
  59. {hestia_earth_models-0.73.8.dist-info → hestia_earth_models-0.74.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,58 @@
1
+ from unittest.mock import patch
2
+ import json
3
+ from tests.utils import fixtures_path, fake_new_indicator, fake_load_impacts
4
+
5
+ from hestia_earth.models.aware2_0 import MODEL_FOLDER
6
+ from hestia_earth.models.aware2_0.scarcityWeightedWaterUse import TERM_ID, run
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
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
13
+ def test_run(*args):
14
+ with open(f"{fixtures_folder}/impact-assessment.jsonld", encoding='utf-8') as f:
15
+ impact = json.load(f)
16
+
17
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
18
+ expected = json.load(f)
19
+
20
+ value = run(impact)
21
+ assert value == expected
22
+
23
+
24
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
25
+ def test_run_site_cropland(*args):
26
+ with open(f"{fixtures_folder}/with-site-cropland/impact-assessment.jsonld", encoding='utf-8') as f:
27
+ impact = json.load(f)
28
+
29
+ with open(f"{fixtures_folder}/with-site-cropland/result.jsonld", encoding='utf-8') as f:
30
+ expected = json.load(f)
31
+
32
+ value = run(impact)
33
+ assert value == expected
34
+
35
+
36
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
37
+ def test_run_country(*args):
38
+ with open(f"{fixtures_folder}/with-country/impact-assessment.jsonld", encoding='utf-8') as f:
39
+ impact = json.load(f)
40
+
41
+ with open(f"{fixtures_folder}/with-country/result.jsonld", encoding='utf-8') as f:
42
+ expected = json.load(f)
43
+
44
+ value = run(impact)
45
+ assert value == expected
46
+
47
+
48
+ @patch('hestia_earth.models.utils.input.load_impacts', side_effect=fake_load_impacts)
49
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
50
+ def test_run_with_inputs(*args):
51
+ with open(f"{fixtures_folder}/with-inputs/impact-assessment.jsonld", encoding='utf-8') as f:
52
+ impact = json.load(f)
53
+
54
+ with open(f"{fixtures_folder}/with-inputs/result.jsonld", encoding='utf-8') as f:
55
+ expected = json.load(f)
56
+
57
+ value = run(impact)
58
+ assert value == expected
File without changes
@@ -3,10 +3,10 @@ import json
3
3
  from unittest.mock import patch
4
4
 
5
5
  from tests.utils import fixtures_path, fake_new_emission
6
- from hestia_earth.models.ecoinventV3 import MODEL, run
6
+ from hestia_earth.models.ecoinventV3.cycle import MODEL, run
7
7
 
8
- class_path = f"hestia_earth.models.{MODEL}"
9
- fixtures_folder = os.path.join(fixtures_path, MODEL)
8
+ class_path = f"hestia_earth.models.{MODEL}.cycle"
9
+ fixtures_folder = os.path.join(fixtures_path, MODEL, 'cycle')
10
10
 
11
11
  TERMS_BY_ID = {
12
12
  '24EpibrassinolideTgai': {
@@ -53,7 +53,7 @@ def test_run(*args):
53
53
  with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
54
54
  expected = json.load(f)
55
55
 
56
- result = run('all', cycle)
56
+ result = run(cycle)
57
57
  assert result == expected
58
58
 
59
59
 
@@ -65,5 +65,5 @@ def test_run_ember(*args):
65
65
  with open(f"{fixtures_folder}/ember-comparison/result.jsonld", encoding='utf-8') as f:
66
66
  expected = json.load(f)
67
67
 
68
- result = run('all', cycle)
68
+ result = run(cycle)
69
69
  assert result == expected
File without changes
@@ -1,11 +1,12 @@
1
+ import os
1
2
  import json
2
3
  from unittest.mock import patch
3
4
 
4
5
  from tests.utils import fixtures_path, fake_new_emission
5
- from hestia_earth.models.ecoinventV3AndEmberClimate import MODEL, run
6
+ from hestia_earth.models.ecoinventV3AndEmberClimate.cycle import MODEL, run
6
7
 
7
- class_path = f"hestia_earth.models.{MODEL}"
8
- fixtures_folder = f"{fixtures_path}/{MODEL}"
8
+ class_path = f"hestia_earth.models.{MODEL}.cycle"
9
+ fixtures_folder = os.path.join(fixtures_path, MODEL, 'cycle')
9
10
 
10
11
  ELECTRICITY_TERMS = [
11
12
  'electricityGridMarketMix',
@@ -22,5 +23,6 @@ def test_run(*args):
22
23
  with open(f"{fixtures_folder}/result.jsonld", encoding="utf-8") as f:
23
24
  expected = json.load(f)
24
25
 
25
- result = run('all', cycle)
26
+ result = run(cycle)
27
+ print(json.dumps(result, indent=2))
26
28
  assert result == expected
@@ -72,7 +72,7 @@ ionising_radiation_indicator_radon = {
72
72
  "@type": "Indicator",
73
73
  "term": {"@id": "ionisingRadiationKbqU235Eq", "termType": "characterisedIndicator"},
74
74
  "value": 0.11156637927360424,
75
- "inputs": [{"@id": "radon222"}],
75
+ "key": {"@id": "radon222"},
76
76
  "methodModel": methodModelfrischknechtEtAl2000
77
77
  }
78
78
 
@@ -80,7 +80,7 @@ ionising_radiation_indicator_plutonium238 = {
80
80
  "@type": "Indicator",
81
81
  "term": {"@id": "ionisingRadiationKbqU235Eq", "termType": "characterisedIndicator"},
82
82
  "value": 8.567909489437642e-13,
83
- "inputs": [{"@id": "plutonium238"}],
83
+ "key": {"@id": "plutonium238"},
84
84
  "methodModel": methodModelfrischknechtEtAl2000
85
85
  }
86
86
 
@@ -22,55 +22,48 @@ wrong_indicator = {
22
22
  "termType": "emission",
23
23
  },
24
24
  "value": 3,
25
- "inputs": [hydrogen3_input],
25
+ "key": hydrogen3_input
26
26
  }
27
27
 
28
- indicator_no_inputs = {
28
+ indicator_no_key = {
29
29
  "term": {"@id": "ionisingCompoundsToAirInputsProduction", "termType": "emission"},
30
- "value": 3,
31
- "inputs": [],
32
- }
33
-
34
- indicator_2_inputs = {
35
- "term": {"@id": "ionisingCompoundsToWaterInputsProduction", "termType": "emission"},
36
- "value": 3,
37
- "inputs": [cesium134_input, cesium137_input],
30
+ "value": 3
38
31
  }
39
32
 
40
33
  indicator_no_unit = {
41
34
  "term": {"@id": "ionisingCompoundsToAirInputsProduction", "termType": "emission"},
42
35
  "value": 3,
43
- "inputs": [{"@id": "hydrogen3", "termType": "waste"}],
36
+ "key": {"@id": "hydrogen3", "termType": "waste"}
44
37
  }
45
38
 
46
39
  indicator_wrong_unit = {
47
40
  "term": {"@id": "ionisingCompoundsToAirInputsProduction", "termType": "emission"},
48
41
  "value": 3,
49
- "inputs": [{"@id": "hydrogen3", "termType": "waste", "units": "not_a_unit"}],
42
+ "key": {"@id": "hydrogen3", "termType": "waste", "units": "not_a_unit"}
50
43
  }
51
44
 
52
45
  indicator_no_cf_input = {
53
46
  "term": {"@id": "ionisingCompoundsToAirInputsProduction", "termType": "emission"},
54
47
  "value": 3,
55
- "inputs": [no_cf_input],
48
+ "key": no_cf_input
56
49
  }
57
50
 
58
51
  indicator_hydrogen3_input = {
59
52
  "term": {"@id": "ionisingCompoundsToAirInputsProduction", "termType": "emission"},
60
53
  "value": 3,
61
- "inputs": [hydrogen3_input],
54
+ "key": hydrogen3_input
62
55
  }
63
56
 
64
57
  indicator_cesium137_water = {
65
58
  "term": {"@id": "ionisingCompoundsToWaterInputsProduction", "termType": "emission"},
66
59
  "value": 3,
67
- "inputs": [cesium137_input],
60
+ "key": cesium137_input
68
61
  }
69
62
 
70
63
  indicator_cesium137_air = {
71
64
  "term": {"@id": "ionisingCompoundsToAirInputsProduction", "termType": "emission"},
72
65
  "value": 3,
73
- "inputs": [cesium137_input],
66
+ "key": cesium137_input
74
67
  }
75
68
 
76
69
  indicator_cesium137_salt_water = {
@@ -79,7 +72,7 @@ indicator_cesium137_salt_water = {
79
72
  "termType": "emission",
80
73
  },
81
74
  "value": 3,
82
- "inputs": [cesium137_input],
75
+ "key": cesium137_input
83
76
  }
84
77
 
85
78
  indicator_uranium234_input = {
@@ -88,17 +81,16 @@ indicator_uranium234_input = {
88
81
  "termType": "emission",
89
82
  },
90
83
  "value": 3,
91
- "inputs": [uranium234_input],
84
+ "key": uranium234_input
92
85
  }
93
86
 
94
87
 
95
88
  @pytest.mark.parametrize(
96
- "resources, expected, num_inputs",
89
+ "resources, expected, num_key",
97
90
  [
98
- ([], True, 0),
99
- ([wrong_indicator], True, 0),
100
- ([indicator_no_inputs], False, 0),
101
- ([indicator_2_inputs], False, 0),
91
+ ([], False, 0),
92
+ ([wrong_indicator], False, 0),
93
+ ([indicator_no_key], False, 0),
102
94
  ([indicator_no_unit], False, 0),
103
95
  ([indicator_wrong_unit], False, 0),
104
96
  ([indicator_no_cf_input], True, 0),
@@ -111,8 +103,7 @@ indicator_uranium234_input = {
111
103
  ],
112
104
  ids=["No emissionsResourceUse => run, empty input",
113
105
  "Wrong indicator termid => run, empty input",
114
- "Indicator no inputs => no run",
115
- "Indicator 2 inputs => no run",
106
+ "Indicator no key => no run",
116
107
  "Missing unit => no run",
117
108
  "Wrong unit => no run",
118
109
  "Input with no cf => run, empty input",
@@ -124,7 +115,7 @@ indicator_uranium234_input = {
124
115
  "3 different indicators common input => run 3 input",
125
116
  ]
126
117
  )
127
- def test_should_run(resources, expected, num_inputs):
118
+ def test_should_run(resources, expected, num_key):
128
119
  with open(f"{fixtures_folder}/impact-assessment.jsonld", encoding='utf-8') as f:
129
120
  impactassessment = json.load(f)
130
121
 
@@ -132,7 +123,7 @@ def test_should_run(resources, expected, num_inputs):
132
123
 
133
124
  should_run, resources_with_cf = _should_run(impactassessment)
134
125
  assert should_run is expected
135
- assert len(resources_with_cf) == num_inputs
126
+ assert len(resources_with_cf) == num_key
136
127
 
137
128
 
138
129
  @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
@@ -12,7 +12,7 @@ from hestia_earth.models.faostat2018.utils import MODEL as FAOSTAT_MODEL
12
12
  from hestia_earth.models.hestia.landCover import (
13
13
  MODEL, MODEL_KEY, _get_changes, _estimate_maximum_forest_change,
14
14
  run, site_area_sum_to_100, _get_sums_of_crop_expansion, _get_sum_for_land_category, scale_values_to_one,
15
- _get_most_common_or_alphabetically_first, _get_land_cover_lookup_suffix
15
+ _get_most_common_or_alphabetically_first, _get_land_cover_lookup_suffix, _get_ratio_between_land_use_types
16
16
  )
17
17
 
18
18
  CLASS_PATH = f"hestia_earth.models.{MODEL}.{MODEL_KEY}"
@@ -263,6 +263,16 @@ def test_get_land_cover_lookup_suffix(land_type: str, expected: str):
263
263
  assert _get_land_cover_lookup_suffix(land_type=land_type) == expected, land_type
264
264
 
265
265
 
266
+ def test_get_ratio_between_land_use_types():
267
+ result = _get_ratio_between_land_use_types(
268
+ country_id="GADM-ZWE",
269
+ end_year=2004,
270
+ first_land_use_term="Arable land",
271
+ second_land_use_term="Permanent crops"
272
+ )
273
+ assert result == (3800.0, 58.843)
274
+
275
+
266
276
  @pytest.mark.parametrize("subfolder", _folders)
267
277
  @patch(f"{CLASS_PATH}._new_management", side_effect=fake_new_management)
268
278
  def test_run(mock, subfolder: str):
@@ -303,10 +313,10 @@ def test_landCover_from_lookup_run(mock_mgmt, mock_region_lookup, caplog):
303
313
  )
304
314
  expected_message = ("site=Brazil-example, requirements=true, model=hestia, model_key=landCover, "
305
315
  "has_management_nodes=True, land_use_type=Arable land, allowed_land_use_types=Arable land;"
306
- "Permanent crops;Permanent meadows and pastures, has_no_prior_land_cover_data=True, "
307
- "management_nodes=value:100_id:maizePlant_land-use-type:Arable land_endDate:2010-12-31"
308
- "_startDate:2010-01-01, landCover_from_lookups=Forest land:0.55;Arable land:0.55;"
309
- "Permanent crops:0.55;Permanent meadows and pastures:0.55;Other land:0.55, "
310
- "should_run_nodes=True")
316
+ "Permanent crops;Permanent meadows and pastures;Cropland, has_no_prior_land_cover_data=True, "
317
+ "management_nodes=value:100_id:maizePlant_land-use-type:Arable land"
318
+ "_endDate:2010-12-31_startDate:2010-01-01, landCover_from_lookups=Forest land:0.55;"
319
+ "Arable land:0.55;Permanent crops:0.55;Permanent meadows and pastures:0.55;Other land:0.55,"
320
+ " should_run_nodes=True")
311
321
  assert expected_message in [r.msg for r in caplog.records]
312
322
  assert result == expected
@@ -11,10 +11,10 @@ def test_list_rasters():
11
11
  @pytest.mark.parametrize(
12
12
  'name,site,expected_len',
13
13
  [
14
- ('without values', {}, 3),
15
- ('with region', {'region': 'region'}, 2),
16
- ('with ecoregion', {'ecoregion': 'ecoregion'}, 2),
17
- ('with awareWaterBasinId', {'awareWaterBasinId': 'awareWaterBasinId'}, 2),
14
+ ('without values', {}, 4),
15
+ ('with region', {'region': 'region'}, 3),
16
+ ('with ecoregion', {'ecoregion': 'ecoregion'}, 3),
17
+ ('with awareWaterBasinId', {'awareWaterBasinId': 'awareWaterBasinId'}, 3),
18
18
  ]
19
19
  )
20
20
  def test_list_vectors(name: str, site: dict, expected_len: int):
@@ -4,8 +4,15 @@ import pytest
4
4
  from hestia_earth.utils.tools import flatten
5
5
 
6
6
  from hestia_earth.models.config import (
7
- load_config, config_max_stage, _is_aggregated_model, _remove_aggregated, load_run_config, load_trigger_config,
8
- get_max_stage
7
+ load_config,
8
+ config_max_stage,
9
+ _is_aggregated_model,
10
+ _remove_aggregated,
11
+ _use_aware_1,
12
+ load_run_config,
13
+ load_trigger_config,
14
+ get_max_stage,
15
+ AWARE_VERSION
9
16
  )
10
17
 
11
18
  _aggregated_model = {
@@ -29,6 +36,27 @@ def test_load_config_error():
29
36
  load_config(node_type)
30
37
 
31
38
 
39
+ def test_load_config_skip_aggregated_models():
40
+ node_type = 'Cycle'
41
+ all_models = load_config(node_type, skip_aggregated_models=False).get('models')
42
+ models_no_aggregated = load_config(node_type, skip_aggregated_models=True).get('models')
43
+ assert all_models != models_no_aggregated
44
+
45
+
46
+ def test_load_config_use_aware_v1_site():
47
+ node_type = 'Site'
48
+ v1_models = load_config(node_type, use_aware_version=AWARE_VERSION.V1).get('models')
49
+ v2_models = load_config(node_type, use_aware_version=AWARE_VERSION.V2).get('models')
50
+ assert v1_models != v2_models
51
+
52
+
53
+ def test_load_config_use_aware_v1_impact_assessment():
54
+ node_type = 'ImpactAssessment'
55
+ v1_models = load_config(node_type, use_aware_version=AWARE_VERSION.V1).get('models')
56
+ v2_models = load_config(node_type, use_aware_version=AWARE_VERSION.V2).get('models')
57
+ assert v1_models != v2_models
58
+
59
+
32
60
  def test_config_max_stage():
33
61
  node_type = 'Cycle'
34
62
  config = load_config(node_type)
@@ -48,11 +76,29 @@ def test_remove_aggregated():
48
76
  assert _remove_aggregated(models) == [[_other_model], _other_model]
49
77
 
50
78
 
51
- def test_load_config_skip_aggregated_models():
52
- node_type = 'Cycle'
53
- all_models = load_config(node_type, skip_aggregated_models=False).get('models')
54
- models_no_aggregated = load_config(node_type, skip_aggregated_models=True).get('models')
55
- assert all_models != models_no_aggregated
79
+ def test_use_aware_1():
80
+ scarcity_model = {
81
+ "model": "aware2-0",
82
+ "value": "scarcityWeightedWaterUse"
83
+ }
84
+ basinid_model = {
85
+ "model": "geospatialDatabase",
86
+ "value": "awareWaterBasinId"
87
+ }
88
+ models = [
89
+ [scarcity_model],
90
+ basinid_model
91
+ ]
92
+ assert _use_aware_1(models) == [
93
+ [{
94
+ "model": "aware",
95
+ "value": "scarcityWeightedWaterUse"
96
+ }],
97
+ {
98
+ "model": "geospatialDatabase",
99
+ "value": "awareWaterBasinId_v1"
100
+ }
101
+ ]
56
102
 
57
103
 
58
104
  def test_load_run_config():
@@ -1,9 +1,9 @@
1
- from hestia_earth.models.ecoalimV9.utils import _values_from_column
1
+ from hestia_earth.models.utils.background_emissions import _values_from_column
2
2
 
3
3
 
4
4
  def test_values_from_column():
5
5
  column = 'landTransformation+landCover[pond]+previousLandCover[permanentCropland]+country[GADM-BRA]'
6
- assert _values_from_column(column, '10') == {
6
+ assert _values_from_column('', column, '10') == {
7
7
  'landTransformation': {
8
8
  'value': 10,
9
9
  'landCover': 'pond',