hestia-earth-models 0.65.10__py3-none-any.whl → 0.66.0__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 (59) hide show
  1. hestia_earth/models/cache_sites.py +7 -9
  2. hestia_earth/models/config/Cycle.json +34 -16
  3. hestia_earth/models/config/ImpactAssessment.json +12 -0
  4. hestia_earth/models/config/Site.json +4 -1
  5. hestia_earth/models/cycle/completeness/freshForage.py +10 -2
  6. hestia_earth/models/cycle/cropResidueManagement.py +3 -1
  7. hestia_earth/models/ecoinventV3/__init__.py +2 -1
  8. hestia_earth/models/environmentalFootprintV3/environmentalFootprintSingleOverallScore.py +135 -0
  9. hestia_earth/models/environmentalFootprintV3/soilQualityIndexLandTransformation.py +17 -6
  10. hestia_earth/models/geospatialDatabase/{aware.py → awareWaterBasinId.py} +1 -1
  11. hestia_earth/models/hestia/landCover.py +57 -39
  12. hestia_earth/models/hestia/residueRemoved.py +80 -0
  13. hestia_earth/models/hestia/resourceUse_utils.py +64 -38
  14. hestia_earth/models/hestia/utils.py +1 -2
  15. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +33 -12
  16. hestia_earth/models/ipcc2019/animal/pastureGrass.py +1 -1
  17. hestia_earth/models/ipcc2019/belowGroundBiomass.py +32 -11
  18. hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +17 -8
  19. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +5 -3
  20. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +27 -17
  21. hestia_earth/models/ipcc2019/pastureGrass.py +1 -1
  22. hestia_earth/models/ipcc2019/pastureGrass_utils.py +8 -1
  23. hestia_earth/models/log.py +1 -1
  24. hestia_earth/models/mocking/search-results.json +34 -34
  25. hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py +0 -1
  26. hestia_earth/models/pooreNemecek2018/landOccupationDuringCycle.py +13 -10
  27. hestia_earth/models/site/defaultMethodClassification.py +9 -2
  28. hestia_earth/models/site/defaultMethodClassificationDescription.py +4 -2
  29. hestia_earth/models/site/management.py +49 -31
  30. hestia_earth/models/site/pre_checks/cache_geospatialDatabase.py +19 -14
  31. hestia_earth/models/utils/blank_node.py +10 -4
  32. hestia_earth/models/utils/crop.py +1 -1
  33. hestia_earth/models/utils/cycle.py +3 -3
  34. hestia_earth/models/utils/lookup.py +1 -1
  35. hestia_earth/models/version.py +1 -1
  36. hestia_earth/orchestrator/strategies/merge/merge_list.py +17 -6
  37. {hestia_earth_models-0.65.10.dist-info → hestia_earth_models-0.66.0.dist-info}/METADATA +1 -1
  38. {hestia_earth_models-0.65.10.dist-info → hestia_earth_models-0.66.0.dist-info}/RECORD +59 -54
  39. tests/models/environmentalFootprintV3/test_environmentalFootprintSingleOverallScore.py +92 -0
  40. tests/models/environmentalFootprintV3/test_soilQualityIndexLandTransformation.py +4 -19
  41. tests/models/faostat2018/product/test_price.py +1 -1
  42. tests/models/geospatialDatabase/{test_aware.py → test_awareWaterBasinId.py} +1 -1
  43. tests/models/hestia/test_landCover.py +4 -2
  44. tests/models/hestia/test_landTransformation20YearAverageDuringCycle.py +3 -1
  45. tests/models/hestia/test_residueRemoved.py +20 -0
  46. tests/models/ipcc2019/test_aboveGroundBiomass.py +3 -1
  47. tests/models/ipcc2019/test_belowGroundBiomass.py +4 -2
  48. tests/models/ipcc2019/test_organicCarbonPerHa.py +94 -1
  49. tests/models/pooreNemecek2018/test_landOccupationDuringCycle.py +1 -3
  50. tests/models/site/pre_checks/test_cache_geospatialDatabase.py +22 -0
  51. tests/models/site/test_defaultMethodClassification.py +6 -0
  52. tests/models/site/test_defaultMethodClassificationDescription.py +6 -0
  53. tests/models/site/test_management.py +4 -4
  54. tests/models/test_cache_sites.py +2 -2
  55. tests/models/utils/test_crop.py +14 -2
  56. tests/orchestrator/strategies/merge/test_merge_list.py +11 -1
  57. {hestia_earth_models-0.65.10.dist-info → hestia_earth_models-0.66.0.dist-info}/LICENSE +0 -0
  58. {hestia_earth_models-0.65.10.dist-info → hestia_earth_models-0.66.0.dist-info}/WHEEL +0 -0
  59. {hestia_earth_models-0.65.10.dist-info → hestia_earth_models-0.66.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,20 @@
1
+ from unittest.mock import patch
2
+ import json
3
+
4
+ from tests.utils import fixtures_path, fake_new_practice
5
+ from hestia_earth.models.hestia.residueRemoved import MODEL, TERM_ID, run
6
+
7
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
+
10
+
11
+ @patch(f"{class_path}._new_practice", side_effect=fake_new_practice)
12
+ def test_run(*args):
13
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
14
+ cycle = json.load(f)
15
+
16
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
17
+ expected = json.load(f)
18
+
19
+ value = run(cycle)
20
+ assert value == expected
@@ -53,7 +53,9 @@ PARAMS_SHOULD_RUN = [
53
53
  ("historical-argentina-pasture", True),
54
54
  ("historical-brazil-maize", True),
55
55
  ("perennial-to-grassland-with-pasture-condition", True),
56
- ("with-gapfilled-start-date-end-date", False) # Closes #972
56
+ ("with-gapfilled-start-date-end-date", False), # Closes #972
57
+ ("forest-to-cropland-with-missing-equilibrium-year-a", True), # Closes #1076
58
+ ("forest-to-cropland-with-missing-equilibrium-year-b", True) # Closes #1076
57
59
  ]
58
60
  IDS_SHOULD_RUN = [p[0] for p in PARAMS_SHOULD_RUN]
59
61
 
@@ -47,13 +47,15 @@ PARAMS_SHOULD_RUN = [
47
47
  ("forest-to-cropland-lcc-q4", True),
48
48
  ("forest-to-gohac", False),
49
49
  ("forest-to-orchard", True),
50
- ("forest-to-orchard-with-ground-cover", True), # Closes 989
50
+ ("forest-to-orchard-with-ground-cover", True), # Closes 989
51
51
  ("forest-to-orchard-with-in-category-lcc", True),
52
52
  ("historical-land-cover-mix", True),
53
53
  ("historical-argentina-pasture", True),
54
54
  ("historical-brazil-maize", True),
55
55
  ("perennial-to-grassland-with-pasture-condition", True),
56
- ("with-gapfilled-start-date-end-date", False) # Closes #972
56
+ ("with-gapfilled-start-date-end-date", False), # Closes #972
57
+ ("forest-to-cropland-with-missing-equilibrium-year-a", True), # Closes #1076
58
+ ("forest-to-cropland-with-missing-equilibrium-year-b", True) # Closes #1076
57
59
  ]
58
60
  IDS_SHOULD_RUN = [p[0] for p in PARAMS_SHOULD_RUN]
59
61
 
@@ -71,6 +71,93 @@ DEFAULT_PROPERTIES = {
71
71
  },
72
72
  "ligninContent": {
73
73
  "value": 9.67
74
+ },
75
+ "dryMatter": {
76
+ "value": 100
77
+ }
78
+ },
79
+ "cattleSolidManureDryKgMass": {
80
+ "carbonContent": {
81
+ "value": 46.4
82
+ },
83
+ "nitrogenContent": {
84
+ "value": 2.65
85
+ },
86
+ "ligninContent": {
87
+ "value": 11
88
+ },
89
+ "dryMatter": {
90
+ "value": 100
91
+ }
92
+ },
93
+ "cattleSolidManureFreshKgMass": {
94
+ "carbonContent": {
95
+ "value": 9.27
96
+ },
97
+ "nitrogenContent": {
98
+ "value": 0.53
99
+ },
100
+ "ligninContent": {
101
+ "value": 2.2
102
+ },
103
+ "dryMatter": {
104
+ "value": 20
105
+ }
106
+ },
107
+ "cattleLiquidManureKgMass": {
108
+ "carbonContent": {
109
+ "value": 4.3
110
+ },
111
+ "nitrogenContent": {
112
+ "value": 0.245
113
+ },
114
+ "ligninContent": {
115
+ "value": 1.02
116
+ },
117
+ "dryMatter": {
118
+ "value": 9.18
119
+ }
120
+ },
121
+ "cattleSolidManureDryKgN": {
122
+ "carbonContent": {
123
+ "value": 1750
124
+ },
125
+ "nitrogenContent": {
126
+ "value": 100
127
+ },
128
+ "ligninContent": {
129
+ "value": 415
130
+ },
131
+ "dryMatter": {
132
+ "value": 3773.585
133
+ }
134
+ },
135
+ "cattleSolidManureFreshKgN": {
136
+ "carbonContent": {
137
+ "value": 1750
138
+ },
139
+ "nitrogenContent": {
140
+ "value": 100
141
+ },
142
+ "ligninContent": {
143
+ "value": 415
144
+ },
145
+ "dryMatter": {
146
+ "value": 3775.611
147
+ }
148
+ },
149
+ "cattleLiquidManureKgN": {
150
+ "carbonContent": {
151
+ "value": 1750
152
+ },
153
+ "nitrogenContent": {
154
+ "value": 100
155
+ },
156
+ "ligninContent": {
157
+ "value": 415
158
+ },
159
+ "dryMatter": {
160
+ "value": 3738.968
74
161
  }
75
162
  }
76
163
  }
@@ -111,6 +198,7 @@ PARAMS_SHOULD_RUN = [
111
198
  ("tier-1/with-gapfilled-start-date-end-date", False), # Closes issue 972
112
199
  ("tier-1/forest-to-orchard-with-ground-cover", True), # Closes 989
113
200
  ("tier-1/forest-to-other-with-ground-cover", True), # Closes 989
201
+ ("tier-1/land-use-change-with-unknown-management", True), # Closes issue 1007
114
202
  ("tier-2/with-generalised-monthly-measurements", False), # Closes issue 600
115
203
  ("tier-2/with-incomplete-climate-data", False), # Closes issue 599
116
204
  ("tier-2/with-initial-soc", True),
@@ -123,7 +211,12 @@ PARAMS_SHOULD_RUN = [
123
211
  ("tier-2/with-paddy-rice", False), # Closes issue 718
124
212
  ("tier-2/with-sand-without-date", True), # Closes issue 739
125
213
  ("tier-2/with-irrigated-upland-rice", False), # Closes issue 718
126
- ("tier-1/land-use-change-with-unknown-management", True) # Closes issue 1007
214
+ ("tier-2/with-manure-dry-kg-mass", True), # Closes issue 763
215
+ ("tier-2/with-manure-fresh-kg-mass", True), # Closes issue 763
216
+ ("tier-2/with-manure-liquid-kg-mass", True), # Closes issue 763
217
+ ("tier-2/with-manure-dry-kg-n", True), # Closes issue 763
218
+ ("tier-2/with-manure-fresh-kg-n", True), # Closes issue 763
219
+ ("tier-2/with-manure-liquid-kg-n", True) # Closes issue 763
127
220
  ]
128
221
  IDS_SHOULD_RUN = [p[0] for p in PARAMS_SHOULD_RUN]
129
222
 
@@ -9,7 +9,7 @@ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
9
9
  fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
10
10
 
11
11
 
12
- @patch(f"{class_path}.get_land_cover_term_id", return_value='cropland')
12
+ @patch(f"{class_path}.get_landCover_term_id", return_value='cropland')
13
13
  @patch(f"{class_path}.land_occupation_per_kg", return_value=None)
14
14
  def test_should_run(mock_land_occupation, *args):
15
15
  # with a cycle and functionalUnit = 1 ha => no run
@@ -23,7 +23,6 @@ def test_should_run(mock_land_occupation, *args):
23
23
  assert should_run is True
24
24
 
25
25
 
26
- @patch(f"{class_path}.get_land_cover_term_id", return_value='cropland')
27
26
  @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
28
27
  def test_run(*args):
29
28
  with open(f"{fixtures_folder}/impact-assessment.jsonld", encoding='utf-8') as f:
@@ -36,7 +35,6 @@ def test_run(*args):
36
35
  assert value == expected
37
36
 
38
37
 
39
- @patch(f"{class_path}.get_land_cover_term_id", return_value='cropland')
40
38
  @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
41
39
  def test_run_with_plantation(*args):
42
40
  with open(f"{fixtures_folder}/with-orchard-crop/impact-assessment.jsonld", encoding='utf-8') as f:
@@ -0,0 +1,22 @@
1
+ import pytest
2
+
3
+ from hestia_earth.models.site.pre_checks.cache_geospatialDatabase import list_rasters, list_vectors
4
+
5
+
6
+ def test_list_rasters():
7
+ rasters = list_rasters(years=[2010])
8
+ assert len(rasters) == 72
9
+
10
+
11
+ @pytest.mark.parametrize(
12
+ 'name,site,expected_len',
13
+ [
14
+ ('without values', {}, 3),
15
+ ('with region', {'region': 'region'}, 2),
16
+ ('with ecoregion', {'ecoregion': 'ecoregion'}, 2),
17
+ ('with awareWaterBasinId', {'awareWaterBasinId': 'awareWaterBasinId'}, 2),
18
+ ]
19
+ )
20
+ def test_list_vectors(name: str, site: dict, expected_len: int):
21
+ vectors = list_vectors([site])
22
+ assert len(vectors) == expected_len, name
@@ -16,3 +16,9 @@ def test_run():
16
16
 
17
17
  result = run(site)
18
18
  assert result == expected
19
+
20
+
21
+ def test_run_no_value():
22
+ site = {'management': [{'@type': 'Management'}]}
23
+ result = run(site)
24
+ assert result == 'modelled'
@@ -16,3 +16,9 @@ def test_run():
16
16
 
17
17
  result = run(site)
18
18
  assert result == expected
19
+
20
+
21
+ def test_run_no_value():
22
+ site = {'management': [{'@type': 'Management'}]}
23
+ result = run(site)
24
+ assert result == 'Data calculated by merging real land use histories and modelled land use histories for each Site.'
@@ -29,10 +29,10 @@ _folders = [d for d in os.listdir(fixtures_folder) if os.path.isdir(os.path.join
29
29
  @patch(f"{class_path}._new_management", side_effect=fake_new_management)
30
30
  @patch(f"{class_path}.related_cycles")
31
31
  def test_run(
32
- mock_related_cycles: Mock,
33
- mock_new_management: Mock,
34
- mock_land_cover_lookup: Mock,
35
- folder: str
32
+ mock_related_cycles: Mock,
33
+ mock_new_management: Mock,
34
+ mock_land_cover_lookup: Mock,
35
+ folder: str
36
36
  ):
37
37
  fixture_path = os.path.join(fixtures_folder, folder)
38
38
 
@@ -30,7 +30,7 @@ def test_run(mock_run_query, *args):
30
30
  [10] * len(rasters_years)
31
31
  ]
32
32
 
33
- sites = run(sites=data.get('nodes', []), years=[2019, 2020], include_region=False)
33
+ sites = run(sites=data.get('nodes', []), years=[2019, 2020])
34
34
 
35
35
  mock_run_query.assert_has_calls([
36
36
  call({
@@ -72,7 +72,7 @@ def test_run_include_region(mock_run_query, *args):
72
72
  [10] * len(rasters_years)
73
73
  ]
74
74
 
75
- run(sites=data.get('nodes', []), years=[2019, 2020], include_region=True)
75
+ run(sites=data.get('nodes', []), years=[2019, 2020])
76
76
 
77
77
  mock_run_query.assert_has_calls([
78
78
  call({
@@ -1,6 +1,7 @@
1
- from hestia_earth.schema import SiteSiteType
1
+ import pytest
2
+ from hestia_earth.schema import SiteSiteType, TermTermType
2
3
 
3
- from hestia_earth.models.utils.crop import valid_site_type
4
+ from hestia_earth.models.utils.crop import valid_site_type, get_landCover_term_id
4
5
 
5
6
  class_path = 'hestia_earth.models.utils.crop'
6
7
 
@@ -13,3 +14,14 @@ def test_valid_site_type():
13
14
  cycle['site']['siteType'] = SiteSiteType.PERMANENT_PASTURE.value
14
15
  assert not valid_site_type(cycle)
15
16
  assert not valid_site_type(site, True) is True
17
+
18
+
19
+ @pytest.mark.parametrize(
20
+ 'term,expected',
21
+ [
22
+ ({'termType': TermTermType.CROP.value, '@id': 'wheatGrain'}, 'wheatPlant'),
23
+ ({'termType': TermTermType.SEED.value, '@id': 'saplings'}, None),
24
+ ]
25
+ )
26
+ def test_get_landCover_term_id(term: dict, expected: str):
27
+ assert get_landCover_term_id(term) == expected, term.get('@id')
@@ -1,12 +1,22 @@
1
1
  from unittest.mock import patch
2
2
  import pydash
3
3
 
4
- from hestia_earth.orchestrator.strategies.merge.merge_list import merge
4
+ from hestia_earth.orchestrator.strategies.merge.merge_list import merge, _get_value
5
5
 
6
6
  class_path = 'hestia_earth.orchestrator.strategies.merge.merge_list'
7
7
  version = '1'
8
8
 
9
9
 
10
+ def test_get_value():
11
+ assert _get_value({'startDate': '2020-01-01'}, 'startDate', {}) == '2020-01-01'
12
+ assert _get_value({'startDate': '2020-01-01'}, 'startDate', {'matchDatesFormat': '%Y'}) == '2020'
13
+ assert _get_value({'startDate': '2020-01-01'}, 'startDate', {'matchDatesFormat': '%Y-%m'}) == '2020-01'
14
+ assert _get_value({'startDate': '2020-01-01'}, 'startDate', {'matchDatesFormat': '%Y-%m-%d'}) == '2020-01-01'
15
+ assert _get_value({'value': 500}, 'value') == 500
16
+ assert _get_value({'value': 500}, 'value', {'matchDatesFormat': '%Y-%m-%d'}) == 500
17
+ assert _get_value({'value': 'test'}, 'value') == 'test'
18
+
19
+
10
20
  def _default_merge(a, b, *args): return pydash.objects.merge({}, a, b)
11
21
 
12
22