hestia-earth-models 0.62.1__py3-none-any.whl → 0.62.2__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 (25) hide show
  1. hestia_earth/models/cycle/coldCarcassWeightPerHead.py +4 -2
  2. hestia_earth/models/cycle/coldDressedCarcassWeightPerHead.py +2 -2
  3. hestia_earth/models/cycle/concentrateFeed.py +3 -3
  4. hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioNitrogen.py +2 -1
  5. hestia_earth/models/cycle/readyToCookWeightPerHead.py +2 -2
  6. hestia_earth/models/ipcc2019/animal/pastureGrass.py +50 -40
  7. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +208 -39
  8. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +2 -6
  9. hestia_earth/models/ipcc2019/pastureGrass.py +43 -41
  10. hestia_earth/models/ipcc2019/pastureGrass_utils.py +63 -109
  11. hestia_earth/models/mocking/search-results.json +393 -249
  12. hestia_earth/models/site/management.py +52 -29
  13. hestia_earth/models/utils/blank_node.py +38 -0
  14. hestia_earth/models/utils/property.py +6 -6
  15. hestia_earth/models/utils/site.py +7 -0
  16. hestia_earth/models/utils/term.py +21 -1
  17. hestia_earth/models/version.py +1 -1
  18. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.2.dist-info}/METADATA +1 -1
  19. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.2.dist-info}/RECORD +25 -25
  20. tests/models/ipcc2019/test_organicCarbonPerHa.py +9 -20
  21. tests/models/ipcc2019/test_organicCarbonPerHa_tier_2_utils.py +0 -8
  22. tests/models/site/test_management.py +31 -3
  23. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.2.dist-info}/LICENSE +0 -0
  24. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.2.dist-info}/WHEEL +0 -0
  25. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.2.dist-info}/top_level.txt +0 -0
@@ -18,13 +18,14 @@ from functools import reduce
18
18
  from hestia_earth.schema import SchemaType, TermTermType
19
19
  from hestia_earth.utils.api import download_hestia
20
20
  from hestia_earth.utils.model import filter_list_term_type, linked_node
21
- from hestia_earth.utils.tools import flatten, safe_parse_float
21
+ from hestia_earth.utils.tools import safe_parse_float
22
22
  from hestia_earth.utils.blank_node import get_node_value
23
23
 
24
24
  from hestia_earth.models.log import logRequirements, logShouldRun, log_blank_nodes_id
25
25
  from hestia_earth.models.utils.term import get_lookup_value
26
26
  from hestia_earth.models.utils.blank_node import condense_nodes
27
27
  from hestia_earth.models.utils.site import related_cycles
28
+ from hestia_earth.models.utils.site import get_land_cover_term_id as get_landCover_term_id_from_site_type
28
29
  from . import MODEL
29
30
 
30
31
  REQUIREMENTS = {
@@ -130,14 +131,16 @@ def _extract_node_value(node: dict) -> dict:
130
131
  return node | {'value': get_node_value(node)}
131
132
 
132
133
 
133
- def _include(value: dict, keys: list): return {k: v for k, v in value.items() if k in keys}
134
+ def _include(value: dict, keys: list) -> dict: return {k: v for k, v in value.items() if k in keys}
134
135
 
135
136
 
136
- def _default_dates(cycle: dict, values: list):
137
+ def _default_dates(cycle: dict, values: list) -> list:
138
+ """Only uses the dates from the cycle if they are missing from the item."""
137
139
  return [(_include(cycle, ["startDate", "endDate"]) | v) for v in values]
138
140
 
139
141
 
140
142
  def _overwrite_dates(cycle: dict, values: list) -> list:
143
+ """Always uses the dates from the cycle."""
141
144
  return [v | _include(cycle, ["startDate", "endDate"]) for v in values]
142
145
 
143
146
 
@@ -149,22 +152,21 @@ def _copy_item_if_exists(source: dict, keys: list[str] = None, dest: dict = None
149
152
 
150
153
  def _get_landCover_term_id(product: dict) -> str:
151
154
  value = get_lookup_value(product.get('term', {}), LAND_COVER_KEY, model=MODEL, model_key=LAND_COVER_KEY)
152
- # TODO: what should happen when there are multiple values?
153
155
  return value.split(';')[0] if value else None
154
156
 
155
157
 
156
- def _get_items_with_relevant_term_type(
157
- cycles: list[dict], item_name: str, relevant_values: list, date_fill: callable = _default_dates
158
- ):
159
- """Get items from the list of cycles with any of the relevant values. Also adds dates if missing."""
160
- return flatten(
161
- [
162
- date_fill(
163
- cycle=cycle,
164
- values=filter_list_term_type(cycle.get(item_name, []), relevant_values)
165
- ) for cycle in cycles
166
- ]
167
- )
158
+ def _get_relevant_items(
159
+ cycles: list[dict], item_name: str, relevant_terms: list, date_fill: callable = _default_dates
160
+ ) -> list[tuple]:
161
+ """
162
+ Get items (optionally in tuples with site_type) from the list of cycles with any of the relevant terms.
163
+ Also adds dates if missing.
164
+ """
165
+ return [
166
+ (item, cycle.get("site", {}).get("siteType", ""))
167
+ for cycle in cycles
168
+ for item in date_fill(cycle=cycle, values=filter_list_term_type(cycle.get(item_name, []), relevant_terms))
169
+ ]
168
170
 
169
171
 
170
172
  def _get_lookup_with_debug(term: dict, column: str) -> any:
@@ -211,27 +213,23 @@ def _get_relevant_inputs(cycles: list[dict]) -> list:
211
213
  return relevant_inputs
212
214
 
213
215
 
214
- def _should_run(site: dict):
215
- # Only get related cycles once.
216
- cycles = related_cycles(site)
217
-
216
+ def _should_run_all_products(cycles):
218
217
  products_land_cover = [
219
218
  _extract_node_value(
220
219
  _include(
221
220
  value=product,
222
221
  keys=["term", "value", "startDate", "endDate", "properties"]
223
222
  )
224
- ) for product in _get_items_with_relevant_term_type(
223
+ ) for product, _ in _get_relevant_items(
225
224
  cycles=cycles,
226
225
  item_name="products",
227
- relevant_values=[TermTermType.LANDCOVER]
226
+ relevant_terms=[TermTermType.LANDCOVER]
228
227
  )
229
228
  ]
230
-
231
- products_crop_forage = _get_items_with_relevant_term_type(
229
+ products_crop_forage = _get_relevant_items(
232
230
  cycles=cycles,
233
231
  item_name="products",
234
- relevant_values=[TermTermType.CROP, TermTermType.FORAGE],
232
+ relevant_terms=[TermTermType.CROP, TermTermType.FORAGE],
235
233
  date_fill=_overwrite_dates
236
234
  )
237
235
  products_crop_forage = [
@@ -243,9 +241,33 @@ def _should_run(site: dict):
243
241
  "value": 100
244
242
  }
245
243
  )
246
- for product in list(filter(_get_landCover_term_id, products_crop_forage))
244
+ for product in list(filter(_get_landCover_term_id, [i[0] for i in products_crop_forage]))
247
245
  ]
248
- all_products = products_land_cover + products_crop_forage
246
+ products_animal_with_site_type = _get_relevant_items(
247
+ cycles=cycles,
248
+ item_name="products",
249
+ relevant_terms=[TermTermType.LIVEANIMAL, TermTermType.ANIMALPRODUCT]
250
+ )
251
+ products_animal = [
252
+ _copy_item_if_exists(
253
+ source=product,
254
+ keys=["startDate", "endDate", "properties"],
255
+ dest={
256
+ "term": linked_node(download_hestia(get_landCover_term_id_from_site_type(site_type))),
257
+ "value": 100
258
+ }
259
+ )
260
+ for product, site_type in products_animal_with_site_type if product
261
+ ]
262
+
263
+ return products_animal, products_crop_forage, products_land_cover
264
+
265
+
266
+ def _should_run(site: dict):
267
+ cycles = related_cycles(site)
268
+
269
+ products_animal, products_crop_forage, products_land_cover = _should_run_all_products(cycles)
270
+ all_products = products_land_cover + products_crop_forage + products_animal
249
271
  all_products = condense_nodes(all_products)
250
272
 
251
273
  practices = [
@@ -254,10 +276,10 @@ def _should_run(site: dict):
254
276
  value=practice,
255
277
  keys=["term", "value", "startDate", "endDate"]
256
278
  )
257
- ) for practice in _get_items_with_relevant_term_type(
279
+ ) for practice, _ in _get_relevant_items(
258
280
  cycles=cycles,
259
281
  item_name="practices",
260
- relevant_values=[
282
+ relevant_terms=[
261
283
  TermTermType.WATERREGIME,
262
284
  TermTermType.TILLAGE,
263
285
  TermTermType.CROPRESIDUEMANAGEMENT,
@@ -275,6 +297,7 @@ def _should_run(site: dict):
275
297
  model_key=MODEL_KEY,
276
298
  products_crop_forage_ids=log_blank_nodes_id(products_crop_forage),
277
299
  products_land_cover_ids=log_blank_nodes_id(products_land_cover),
300
+ products_animal=log_blank_nodes_id(products_animal),
278
301
  practice_ids=log_blank_nodes_id(practices),
279
302
  inputs=log_blank_nodes_id(relevant_inputs)
280
303
  )
@@ -41,6 +41,44 @@ from .lookup import (
41
41
  from .term import get_lookup_value
42
42
 
43
43
 
44
+ def lookups_logs(model: str, blank_nodes: list, lookups_per_termType: dict, **log_args):
45
+ def mapper(blank_node: dict):
46
+ term = blank_node.get('term', {})
47
+ term_id = term.get('@id')
48
+ term_type = term.get('termType')
49
+ lookups = lookups_per_termType.get(term_type, [])
50
+ lookups = lookups if isinstance(lookups, list) else [lookups]
51
+
52
+ def _reduce_lookups_logs(logs: dict, column: str):
53
+ lookup_value = get_lookup_value(term, column, model=model, **log_args)
54
+ return logs | {column: lookup_value}
55
+
56
+ return reduce(_reduce_lookups_logs, lookups, {'id': term_id})
57
+
58
+ logs = list(map(mapper, blank_nodes))
59
+
60
+ return log_as_table(logs)
61
+
62
+
63
+ def properties_logs(blank_nodes: list, properties: Union[dict, list]):
64
+ def mapper(blank_node: dict):
65
+ term = blank_node.get('term', {})
66
+ term_id = term.get('@id')
67
+ term_type = term.get('termType')
68
+ props = properties.get(term_type, []) if isinstance(properties, dict) else properties
69
+ props = props if isinstance(props, list) else [props]
70
+
71
+ def _reduce_properties_logs(logs: dict, prop: str):
72
+ value = get_node_property(term, prop).get('value')
73
+ return logs | {prop: value}
74
+
75
+ return reduce(_reduce_properties_logs, properties, {'id': term_id})
76
+
77
+ logs = list(map(mapper, blank_nodes))
78
+
79
+ return log_as_table(logs)
80
+
81
+
44
82
  def group_by_keys(group_keys: list = ['term']):
45
83
  def run(group: dict, node: dict):
46
84
  group_key = '-'.join(non_empty_list(map(lambda v: node.get(v, {}).get('@id'), group_keys)))
@@ -87,17 +87,17 @@ def node_has_property(term_id: str):
87
87
  return lambda product: find_term_match(product.get('properties', []), term_id, None) is not None
88
88
 
89
89
 
90
- def node_property_lookup_value(model: str, term: dict, prop_id: str, default=None, **log_args):
90
+ def node_property_lookup_value(model: str, node_term: dict, prop_id: str, default=None, **log_args):
91
91
  # as the lookup table might not exist, we are making sure we return `0` in thise case
92
92
  try:
93
- lookup_name = f"{term.get('termType')}-property.csv"
93
+ lookup_name = f"{node_term.get('termType')}-property.csv"
94
94
  lookup = download_lookup(lookup_name)
95
- term_id = term.get('@id')
95
+ term_id = node_term.get('@id')
96
96
  lookup_value = get_table_value(lookup, 'termid', term_id, column_name(prop_id))
97
97
  value = extract_grouped_data(lookup_value, 'Avg') if (
98
98
  isinstance(lookup_value, str) and 'Avg' in lookup_value
99
99
  ) else lookup_value
100
- debugMissingLookup(lookup_name, 'termid', term_id, prop_id, value, model=model, term=term_id, **log_args)
100
+ debugMissingLookup(lookup_name, 'termid', term_id, prop_id, value, model=model, **log_args)
101
101
  return safe_parse_float(value, default=None)
102
102
  except Exception:
103
103
  return default
@@ -111,9 +111,9 @@ def get_node_property_value(model: str, node: dict, prop_id: str, default=None,
111
111
  return default if value is None else (value / 100 if units == '%' else value)
112
112
 
113
113
 
114
- def get_node_property_value_converted(model: str, node: dict, prop_id: str, default=None):
114
+ def get_node_property_value_converted(model: str, node: dict, prop_id: str, default=None, **log_args):
115
115
  node_value = list_sum(node.get('value', []))
116
- prop_value = get_node_property_value(model, node, prop_id)
116
+ prop_value = get_node_property_value(model, node, prop_id, **log_args)
117
117
  return default if prop_value is None else node_value * prop_value
118
118
 
119
119
 
@@ -5,6 +5,7 @@ from hestia_earth.utils.tools import non_empty_list, flatten, safe_parse_date
5
5
 
6
6
  from hestia_earth.models.log import debugMissingLookup
7
7
  from . import cached_value, _load_calculated_node
8
+ from .term import get_land_cover_siteTypes
8
9
 
9
10
  CACHE_YEARS_KEY = 'years'
10
11
  WATER_TYPES = [
@@ -120,3 +121,9 @@ def region_factor(model: str, region_id: str, term_id: str, termType: TermTermTy
120
121
  value = get_table_value(download_lookup(lookup_name), 'termid', region_id, column_name(term_id))
121
122
  debugMissingLookup(lookup_name, 'termid', region_id, term_id, value, model=model, term=term_id)
122
123
  return value
124
+
125
+
126
+ def get_land_cover_term_id(site_type: str):
127
+ land_cover_terms = get_land_cover_siteTypes()
128
+ term = next((term for term in land_cover_terms if term["name"].lower() == site_type.lower()), {})
129
+ return term.get('@id')
@@ -1,4 +1,4 @@
1
- from hestia_earth.schema import SchemaType, TermTermType
1
+ from hestia_earth.schema import SchemaType, TermTermType, SiteSiteType
2
2
  from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
3
3
  from hestia_earth.utils.api import find_node, search
4
4
 
@@ -625,3 +625,23 @@ def get_electricity_grid_mix_terms():
625
625
  ],
626
626
  }
627
627
  }, limit=LIMIT, fields=['@type', '@id', 'name', 'termType', 'units'])
628
+
629
+
630
+ def get_land_cover_siteTypes():
631
+ """
632
+ Find all `Land Cover` terms with siteTypes
633
+
634
+ Returns
635
+ -------
636
+ List of landCover terms with associated siteTypes.
637
+ """
638
+ return search({
639
+ "bool": {
640
+ "must": [
641
+ {"match": {"@type": "Term"}},
642
+ {"match": {"termType": "landCover"}}
643
+ ],
644
+ "should": [{"match": {"name": siteType.value}} for siteType in SiteSiteType],
645
+ "minimum_should_match": 1
646
+ },
647
+ })
@@ -1 +1 @@
1
- VERSION = '0.62.1'
1
+ VERSION = '0.62.2'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hestia-earth-models
3
- Version: 0.62.1
3
+ Version: 0.62.2
4
4
  Summary: Hestia's set of modules for filling gaps in the activity data using external datasets (e.g. populating soil properties with a geospatial dataset using provided coordinates) and internal lookups (e.g. populating machinery use from fuel use). Includes rules for when gaps should be filled versus not (e.g. never gap fill yield, gap fill crop residue if yield provided etc.).
5
5
  Home-page: https://gitlab.com/hestia-earth/hestia-engine-models
6
6
  Author: Hestia Team
@@ -4,7 +4,7 @@ hestia_earth/models/cache_sites.py,sha256=KQp9cUKE-aIcYJoMWEtKFYS8gBFfsx5LKQhqoW
4
4
  hestia_earth/models/log.py,sha256=b63I3qyTtQs17xxbq8RI0Fv2lvZ1oDZ9k0njhxqiFFk,3459
5
5
  hestia_earth/models/preload_requests.py,sha256=elhYQTxBVuFlZROWvZ3yErDzzMLdMUIjBhmpdaTUSi8,1012
6
6
  hestia_earth/models/requirements.py,sha256=znNZJAhwX2iYiKcAQXPftY7z_1MsNa0QxCXkXyHm_U0,17363
7
- hestia_earth/models/version.py,sha256=PWB3A1c15lnJ0vIqLFnOlwunRfvIyeg_7b4mAWh_mKI,19
7
+ hestia_earth/models/version.py,sha256=EWenFVQCLj6zgrn-xqhR8lwtUw0XKd0Vbw0vYPdiKVc,19
8
8
  hestia_earth/models/agribalyse2016/__init__.py,sha256=WvK0qCQbnYtg9oZxrACd1wGormZyXibPtpCnIQeDqbw,415
9
9
  hestia_earth/models/agribalyse2016/fuelElectricity.py,sha256=mrh8seYSYdTgcMDCETLiknuPeJehg071YoG4UiyW0yU,4404
10
10
  hestia_earth/models/agribalyse2016/machineryInfrastructureDepreciatedAmountPerCycle.py,sha256=_Rbngu0DzHKa62JwBl58ZC_ui1zLF2que_nB7ukhOQc,3392
@@ -35,9 +35,9 @@ hestia_earth/models/cml2001NonBaseline/eutrophicationPotentialIncludingFateAvera
35
35
  hestia_earth/models/cml2001NonBaseline/terrestrialAcidificationPotentialExcludingFate.py,sha256=y6aIHefYOBiw_9HeH_jLozxej9p3LVQAPYJz6Cz6zig,1029
36
36
  hestia_earth/models/cycle/__init__.py,sha256=VowO3kOHb0LpURsljNaJsYO7s6vgjhul6bF_85UjUEI,406
37
37
  hestia_earth/models/cycle/aboveGroundCropResidueTotal.py,sha256=9swq4YEeJQ2YjVOmghgBYWkMZWdNU4MKCUBY5FsmBSU,3088
38
- hestia_earth/models/cycle/coldCarcassWeightPerHead.py,sha256=SaTHq8AC3o8HylfN0LE1ird2e5ylz4Jo5pcGL2MJCEI,2913
39
- hestia_earth/models/cycle/coldDressedCarcassWeightPerHead.py,sha256=9i52CQHiqZjFYcW1IwKUAgJvFkUvp0BZT_z3Ik-HiSM,3041
40
- hestia_earth/models/cycle/concentrateFeed.py,sha256=TBhBuh98WYrzMEajXyuFRTdVq_pnp0fokCCqL67nfmk,5594
38
+ hestia_earth/models/cycle/coldCarcassWeightPerHead.py,sha256=fQ7huuxyS5PQkRmR_tRCOz9rV3LJwLfLQJjH_TcTz6k,2955
39
+ hestia_earth/models/cycle/coldDressedCarcassWeightPerHead.py,sha256=k0xg5SIfJGwEKteFr2Fh-lh8yDC_sqQw_lBnnfwl9zU,3069
40
+ hestia_earth/models/cycle/concentrateFeed.py,sha256=wiq9KLRuipHz_2_CVfXDuUek0JN1ZPSyKSimtJntG9E,5636
41
41
  hestia_earth/models/cycle/cropResidueManagement.py,sha256=QTRCCFu9VvD_a3_8aAj216vsuhAJEhlAwTJH7ifMkDo,2237
42
42
  hestia_earth/models/cycle/cycleDuration.py,sha256=9EvmdBdyjgKqiMi643PMVPvlrzRInP00WKiB2hv96NQ,3016
43
43
  hestia_earth/models/cycle/energyContentLowerHeatingValue.py,sha256=AyVKCQbb3Pto3Ca__F0KJ_wlwTxbPd7mUyehZW7AJPM,2212
@@ -50,7 +50,7 @@ hestia_earth/models/cycle/liveAnimal.py,sha256=LWAMnNKRoLDdChrGApVIN-Ns7em0Lspz5
50
50
  hestia_earth/models/cycle/milkYield.py,sha256=RhzePjkvEAGicTzRA4eatc0K_4NSGHhyEhYF0EbbGXw,5820
51
51
  hestia_earth/models/cycle/pastureGrass.py,sha256=7PrmDMJPtsbKGa8WIOh_4NXNtbH3Pxb23pmjawQuY9o,1226
52
52
  hestia_earth/models/cycle/pastureSystem.py,sha256=uksVgl_3bp_t2niwZ5BvS3VT-Kndx26Se6GpzqG0bX8,2709
53
- hestia_earth/models/cycle/readyToCookWeightPerHead.py,sha256=F4UtK1gSsIYqbQ1V2hSUszSrq2HFN5LdMB33Yc-bfTQ,2927
53
+ hestia_earth/models/cycle/readyToCookWeightPerHead.py,sha256=R1Rt3WsTzwnI2Bqljx03RpdG0A1-bGV4M7EqmcP7Dzg,2955
54
54
  hestia_earth/models/cycle/residueBurnt.py,sha256=HwU1D9ibiIul-FlXDUcEMDEc_KxpB8ug0SLz-4rXxKk,2106
55
55
  hestia_earth/models/cycle/residueIncorporated.py,sha256=9_s2RMOy5D20eq9ziDBEA_Y7RiFFMeK0bDJ65CW4qlE,2763
56
56
  hestia_earth/models/cycle/residueLeftOnField.py,sha256=qYxKGAdUORN7Vjqj7AZC2VGV_rM3MN0-padDGhgjiNU,2175
@@ -79,7 +79,7 @@ hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioCarbon.py,sha25
79
79
  hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioDryMatter.py,sha256=zf-v-cAPLpSe7sr1auzUUXkjXwpXRTVvsCrzbZrwBI8,2388
80
80
  hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioEnergy.py,sha256=C6ZyjZDUHU4UlIr6tlvHoCQfsC5jRQ87U7stSn95jzA,1984
81
81
  hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioFedWeight.py,sha256=7Dss1AIbG7GimQ3-Ecv2wsx1PrblZhHFYhMHWoyvPc4,2140
82
- hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioNitrogen.py,sha256=Mgur-o_ki1deMukBS5-ngeqdCIYVBE36kOiY-jB42EY,2581
82
+ hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioNitrogen.py,sha256=RV7lLd4PiFRCkH83-DvuZKnOCA9bXbYOcDHea8Wz4LY,2603
83
83
  hestia_earth/models/cycle/input/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
84
84
  hestia_earth/models/cycle/input/hestiaAggregatedData.py,sha256=7WhSOTUKq9A6mrDwOu5gMOHtkhK0oby8n-DAO4LaWLs,5035
85
85
  hestia_earth/models/cycle/input/properties.py,sha256=r5EF18b_KW8evmdlev0mLQyqwBVgSicKEyilGaBRF6I,3017
@@ -246,13 +246,13 @@ hestia_earth/models/ipcc2019/noxToAirInorganicFertiliser.py,sha256=fmmFgjtvOD2Tr
246
246
  hestia_earth/models/ipcc2019/noxToAirOrganicFertiliser.py,sha256=9dx_MRTwJGxJRq6mj2EJQMdQ2w6j7lw0fQk0If_cIGc,4152
247
247
  hestia_earth/models/ipcc2019/organicCarbonPerHa.py,sha256=8rQifRZYQdoBz9HpoSbmrKiGP7ayQUZT78KEErgqtwc,8658
248
248
  hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py,sha256=B7pwVkpt2YTo49yImTAQ4rr_Lu03zaPb5LEDKm0WJJI,82431
249
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py,sha256=Zb3c5Wby1ZrRXs4n9qPgP04oIRZn9EUjkH65uRSk8Dc,58015
250
- hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py,sha256=CrQWsDhW--wNQ2HEc_zxdFKuIdBHEwOQnVJGA3HgPpQ,10856
251
- hestia_earth/models/ipcc2019/pastureGrass.py,sha256=VXUqbvNmRWJy-oTD2ENj8wxhZ-YWivNMxjk4znt5t74,9344
252
- hestia_earth/models/ipcc2019/pastureGrass_utils.py,sha256=ITQSFQ0zLCqbrKoMuYQ9MaP_-F768uNKdltf5zZCwUs,15833
249
+ hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py,sha256=m_8eJGKENUBs6oXnGpCXecUe7T5ke_jUoREKRsJV4_0,63542
250
+ hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py,sha256=jIhRks8ewCtQNIIN89N_4A4Tp529YMQnk4YmZV6FOCY,10668
251
+ hestia_earth/models/ipcc2019/pastureGrass.py,sha256=Dg94o-tMVR-SWW6dIK5kwbV4pcMBHEWtcSS2JhAtpXY,9491
252
+ hestia_earth/models/ipcc2019/pastureGrass_utils.py,sha256=TqGHj4yZmEO6cVV3VeqSTl11TGRpipnliMMUIOqTy1k,13744
253
253
  hestia_earth/models/ipcc2019/utils.py,sha256=MSDMu15D9DnilFUgi4_6jYXC0FaKso3OODauGTMB6hs,6229
254
254
  hestia_earth/models/ipcc2019/animal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
255
- hestia_earth/models/ipcc2019/animal/pastureGrass.py,sha256=ej1cyJKUqSFP5CsdV0iU_ucpGxN4VWbaw2caKi0rtoE,10966
255
+ hestia_earth/models/ipcc2019/animal/pastureGrass.py,sha256=QyT0qRO0lAJJU0Tp3PlDtXzbs7J6BXSX9kWo57T9GMw,11417
256
256
  hestia_earth/models/ipcc2019/animal/weightAtMaturity.py,sha256=5smSAmKVCIlELCD6S_3I16YuSWNFhcClGDOdvrIuYsE,3657
257
257
  hestia_earth/models/ipcc2021/__init__.py,sha256=VTgGFKhwMmk_nuI1RRq0in27fHYVPBonlXlPK00K8no,409
258
258
  hestia_earth/models/ipcc2021/gwp100.py,sha256=v-DYU-11XnWI1Ns1GEiKrJqL3JafxvhTsLmuBuFcxJU,1021
@@ -366,7 +366,7 @@ hestia_earth/models/linkedImpactAssessment/landTransformationFromPermanentPastur
366
366
  hestia_earth/models/linkedImpactAssessment/utils.py,sha256=dGwGc2d-8_WQElTpfyPmz5vQtL-LHQRmiZnCTuPXMDs,1876
367
367
  hestia_earth/models/mocking/__init__.py,sha256=n3Fkkrvh8zHNWiJZmnfQ7WZ91JRzAO9P6pSG1JpwtXo,687
368
368
  hestia_earth/models/mocking/mock_search.py,sha256=dBCDRfbZmbMLKP21u_VYkxyimomqs-zztjX-_ZNKuuM,2036
369
- hestia_earth/models/mocking/search-results.json,sha256=GyPI-u-c5vWqHmSgPI2684DgFvpNJgLRNiZb91wu3uE,43624
369
+ hestia_earth/models/mocking/search-results.json,sha256=b5j1ibEDk4nfn9QJf9d_C6ZQoAvEKkUpHkbcWFHYqC4,46685
370
370
  hestia_earth/models/pooreNemecek2018/__init__.py,sha256=nPboL7ULJzL5nJD5q7q9VOZt_fxbKVm8fmn1Az5YkVY,417
371
371
  hestia_earth/models/pooreNemecek2018/aboveGroundCropResidueTotal.py,sha256=Qt-mel4dkhK6N5uUOutNOinCTFjbjtGzITaaI0LvYc4,2396
372
372
  hestia_earth/models/pooreNemecek2018/belowGroundCropResidue.py,sha256=JT0RybbvWVlo01FO8K0Yj41HrEaJT3Kj1xfayr2X-xw,2315
@@ -465,7 +465,7 @@ hestia_earth/models/site/brackishWater.py,sha256=vLEhIZv5PUKwzwvIuYrWi7K---fq7ZX
465
465
  hestia_earth/models/site/cationExchangeCapacityPerKgSoil.py,sha256=0eH4A-tXJ0hvIkiYXWxlx8TfrdbIKUGYUDk97-yQJgg,3653
466
466
  hestia_earth/models/site/flowingWater.py,sha256=v3g5722GIA4zQAUQI9yGFiZvFvI1QAVZqlQrY-6_B3A,1731
467
467
  hestia_earth/models/site/freshWater.py,sha256=FXs3Vt8V4e-wn325_dwSTOKlZtn5ksNUpvYGDeLJShY,1255
468
- hestia_earth/models/site/management.py,sha256=iljb0YjZqQcilXNlYIffjfEqszvMaLRKJlgv0TKIe-M,9627
468
+ hestia_earth/models/site/management.py,sha256=ithImDcKKNvSk3ACxChQCasy_KLPcBWlQa4wo4hQLqU,10666
469
469
  hestia_earth/models/site/netPrimaryProduction.py,sha256=UIIQkYd911qVzrWjxBLrC37e-RARIVgDwLdARY9BuLw,1849
470
470
  hestia_earth/models/site/organicCarbonPerHa.py,sha256=O6t4D3Jj1kjMIBOpnIrJ58kzUP_FIlpMUEFKQAeS77c,14916
471
471
  hestia_earth/models/site/organicCarbonPerKgSoil.py,sha256=t--wAshiAKS-JvEKhLFRadGvgSBv5NFZ68jdyms_wh4,1945
@@ -528,7 +528,7 @@ hestia_earth/models/utils/aggregated.py,sha256=sz6usleZmo_tC_hIvmGgYsX8-H0dulXmm
528
528
  hestia_earth/models/utils/animalProduct.py,sha256=M5IunAKGY6oZv3j1Ascl34ywyeLWApqOIlBzbtlA2FE,721
529
529
  hestia_earth/models/utils/aquacultureManagement.py,sha256=dxrbC1Xf140cohxTbSw6TxLAnAASWTdNZwBBam4yQnw,171
530
530
  hestia_earth/models/utils/array_builders.py,sha256=0_Ik0gKoh1QBijyb-55odh8_dIs-CWQ3lgUN1Hnc4Y8,18749
531
- hestia_earth/models/utils/blank_node.py,sha256=TpjIepoRvHnffOjmv-N4HjYyMLCdUBGVrzwoPVCB3S8,43013
531
+ hestia_earth/models/utils/blank_node.py,sha256=XpuFGyXGC_0TrilR2JM7NI6Na2mlUgx7hcAQt8ke7nQ,44415
532
532
  hestia_earth/models/utils/completeness.py,sha256=2-GusD9UycobDZq8y5jar0ZcOjyqnSbzPRT_5XMc4YA,1259
533
533
  hestia_earth/models/utils/constant.py,sha256=7wn5LBdsqlLdCrPaVASYjsxNtbaOSdqVWKedOFgyzfY,3249
534
534
  hestia_earth/models/utils/crop.py,sha256=kG054fryqPSBpmzvJFBy_CLiOdjrt7RMk5uTItO5ADg,2246
@@ -555,11 +555,11 @@ hestia_earth/models/utils/pesticideAI.py,sha256=6f8b-dFm3qr-eY049_eOvj_iDk4XBam6
555
555
  hestia_earth/models/utils/practice.py,sha256=tNadOzsrNlCEt801B815XaruJXzZ5yPASam7B3sWpXE,1091
556
556
  hestia_earth/models/utils/product.py,sha256=H9UqJNzTqtMWXDQnbRkZlTpv_hg4s-Tya469fBk8InA,10143
557
557
  hestia_earth/models/utils/productivity.py,sha256=bUBVCZInGqHuHZvHDSYPQkjWXQxOtTjEk-1-f_BsFOo,594
558
- hestia_earth/models/utils/property.py,sha256=gHPEmy3Sw599ox64Gv-LCvjhP1THlBXBaBlTOK5lvog,5060
559
- hestia_earth/models/utils/site.py,sha256=yei3qk7edxb_boag9h8j713r06KGstjTBWdb1KjqMus,3602
558
+ hestia_earth/models/utils/property.py,sha256=_9Wy0oZIBLsa-jOiGLokKehYLNdz-_7LfLaE4fb6SWM,5085
559
+ hestia_earth/models/utils/site.py,sha256=uPOA6uLLqVQdHIY2LynaiXWL4FHxfDQWcPBk3v7Jby8,3870
560
560
  hestia_earth/models/utils/source.py,sha256=Y-CcO5Y3q5Hz4A4RdX35C1EUjL9w1NKnOrzVfOWQ7nU,1748
561
561
  hestia_earth/models/utils/temperature.py,sha256=ljlG4-yCgFFb6LRZweb18cZKLrr7K2mqd4E4Hz_D1f8,476
562
- hestia_earth/models/utils/term.py,sha256=n_T1Qp_0z9ZUgrbVACNKue-5yDePOCkDw8g8dlMKSTM,17763
562
+ hestia_earth/models/utils/term.py,sha256=YBUu1QVGOt4FieSDp0aF4U6F-LTuyBGdci6LkEypi48,18278
563
563
  hestia_earth/models/utils/transformation.py,sha256=nyT5Mz4_VgFwhkL8JoNX9kxxow0zuxzsYl3W8xOu2p0,370
564
564
  hestia_earth/models/webbEtAl2012AndSintermannEtAl2012/__init__.py,sha256=Niv7ZFMBCwThlbCKGOwA17QdkpOUDFrqrFItGNqnZAA,434
565
565
  hestia_earth/models/webbEtAl2012AndSintermannEtAl2012/nh3ToAirOrganicFertiliser.py,sha256=TGXyusrRd9shT842iqbrI6MkQhICgw7uYdrl4jsDrg8,4193
@@ -795,9 +795,9 @@ tests/models/ipcc2019/test_no3ToGroundwaterInorganicFertiliser.py,sha256=e7REnQ9
795
795
  tests/models/ipcc2019/test_no3ToGroundwaterOrganicFertiliser.py,sha256=e1ZViD12qB3bLdH3TJw3GbBP8iqMen-UJbcFkytb3VQ,1609
796
796
  tests/models/ipcc2019/test_noxToAirInorganicFertiliser.py,sha256=NZBSBJLM_j2PEpHRON2ysgKNF8x5sHfQVoAKQdGsfzk,1537
797
797
  tests/models/ipcc2019/test_noxToAirOrganicFertiliser.py,sha256=LR5pjV5vRbgSSQAw8kYRp_ij4CHInzgaDS6EggQuBiw,1104
798
- tests/models/ipcc2019/test_organicCarbonPerHa.py,sha256=PJ3l2LexjybgA3IIYzYYZ01akYq5EjmCT4y6JYavL54,13989
798
+ tests/models/ipcc2019/test_organicCarbonPerHa.py,sha256=9i1xEv5QEc8C9e0c0iVGwLOWisZVYwwlnAsEVmMv5Lg,13245
799
799
  tests/models/ipcc2019/test_organicCarbonPerHa_tier_1_utils.py,sha256=e5RpK4GlH9tNxbwEyPQkO2lMwYBtGNp8ha8j4bZF9eg,20699
800
- tests/models/ipcc2019/test_organicCarbonPerHa_tier_2_utils.py,sha256=gHAi0qr9vE2_TtyJOqOc5Wc8ZRIflQz8vKBOcvKTzCE,7020
800
+ tests/models/ipcc2019/test_organicCarbonPerHa_tier_2_utils.py,sha256=6YXLqH5wz_cvYlJjCacCv9UTYpnXYxURLKQz6N9ZMPg,6807
801
801
  tests/models/ipcc2019/test_organicCarbonPerHa_utils.py,sha256=Zd2QlN_Q3k9djuByOH62A00tryVzlvNtsd46N79TTeU,1778
802
802
  tests/models/ipcc2019/test_pastureGrass.py,sha256=xcFXpszkqgeJImWOp-JlJxpcSHQKC-Pi0zdaKfai4a4,2660
803
803
  tests/models/ipcc2019/animal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1008,7 +1008,7 @@ tests/models/site/test_brackishWater.py,sha256=YGCp4glaWudKklYBSp-50KbfvIRtp3F4Q
1008
1008
  tests/models/site/test_cationExchangeCapacityPerKgSoil.py,sha256=tNMhN998vcjQ15I-5mNnFh2d7mHzEBIBO6o1VSfQNUE,1075
1009
1009
  tests/models/site/test_flowingWater.py,sha256=t_rxvdlmUVDsFBoDF20_zDM-0iiLKkNCV7knO9l1T7o,1370
1010
1010
  tests/models/site/test_freshWater.py,sha256=GOeAxHhPW_2E1wQdQRX4W-r7mnb_LgmiAVLImitoApw,982
1011
- tests/models/site/test_management.py,sha256=1ecEbbHNmzA-qSw9-d_sGi-j64FXOCxUm1WLSEmPJHU,12659
1011
+ tests/models/site/test_management.py,sha256=lQKPxzP3pmGTeIjlGb-191BlPLRV_2uUDBi9fMOFMIg,13458
1012
1012
  tests/models/site/test_netPrimaryProduction.py,sha256=JCxG0MODbKVvl3hOqmKzh4FjHYn3Xs9KsVod6LvKQII,1108
1013
1013
  tests/models/site/test_organicCarbonPerHa.py,sha256=XtGrE7ZqthTF0x8lDxJ1slNd_GvYHEyEydcRgA46jEc,3207
1014
1014
  tests/models/site/test_organicCarbonPerKgSoil.py,sha256=0M-NMg_T3UXzGT_VlKOKhSxg4cZ0_zhd3FRgY5Hpj6o,1087
@@ -1087,8 +1087,8 @@ tests/models/utils/test_source.py,sha256=mv3vHZV5cjpoLA2I1109-YUkuzAiuhbRSnv_76_
1087
1087
  tests/models/utils/test_term.py,sha256=M5Sa26v2gzQYbZ4H_fo7DspnaCx__-WtL-MULGapCWk,3509
1088
1088
  tests/models/webbEtAl2012AndSintermannEtAl2012/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1089
1089
  tests/models/webbEtAl2012AndSintermannEtAl2012/test_nh3ToAirOrganicFertiliser.py,sha256=qi2FNXS5Af2WDtm7nq_FsprH3BfCF0XxnE0XHmC4aIY,2244
1090
- hestia_earth_models-0.62.1.dist-info/LICENSE,sha256=AC7h7GAgCZGJK_Tzh6LUCrML9gQEfowWwecEw2w54QM,1154
1091
- hestia_earth_models-0.62.1.dist-info/METADATA,sha256=qY8BwGkgTl3hz-Z_6-hq_wEHb2H6bnDiHbC2MdBwu1Q,3350
1092
- hestia_earth_models-0.62.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1093
- hestia_earth_models-0.62.1.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1094
- hestia_earth_models-0.62.1.dist-info/RECORD,,
1090
+ hestia_earth_models-0.62.2.dist-info/LICENSE,sha256=AC7h7GAgCZGJK_Tzh6LUCrML9gQEfowWwecEw2w54QM,1154
1091
+ hestia_earth_models-0.62.2.dist-info/METADATA,sha256=epzR-hLk8p2bP7MCqfgrEir5gUJGU4eJjuDnSL7TX0U,3350
1092
+ hestia_earth_models-0.62.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1093
+ hestia_earth_models-0.62.2.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1094
+ hestia_earth_models-0.62.2.dist-info/RECORD,,
@@ -28,13 +28,6 @@ COVER_CROP_PROPERTY_TERM_IDS = [
28
28
  "shortFallowCrop"
29
29
  ]
30
30
 
31
- CROP_RESIDUE_INCORP_TERM_IDS = [
32
- "aboveGroundCropResidueIncorporated",
33
- "aboveGroundCropResidueLeftOnField",
34
- "belowGroundCropResidue",
35
- "discardedCropIncorporated",
36
- "discardedCropLeftOnField"
37
- ]
38
31
 
39
32
  IRRIGATED_TERM_IDS = [
40
33
  "rainfedDeepWater",
@@ -104,6 +97,7 @@ def order_list(values: list[dict]) -> list[dict]:
104
97
  PARAMS_SHOULD_RUN = [
105
98
  ("tier-1-and-2/cropland", True),
106
99
  ("tier-1-and-2/with-zero-carbon-input", True), # Closes issue 777
100
+ ("tier-1-and-2/with-residues-removed", True), # Closes issue #758 and #846
107
101
  ("tier-1/cropland-depth-as-float", True),
108
102
  ("tier-1/cropland-with-measured-soc", True),
109
103
  ("tier-1/cropland-without-measured-soc", True),
@@ -130,6 +124,7 @@ PARAMS_SHOULD_RUN = [
130
124
  IDS_SHOULD_RUN = [p[0] for p in PARAMS_SHOULD_RUN]
131
125
 
132
126
 
127
+ # TODO: update mocks
133
128
  @mark.parametrize("subfolder, should_run", PARAMS_SHOULD_RUN, ids=IDS_SHOULD_RUN)
134
129
  @patch(f"{term_path}.search")
135
130
  @patch(f"{property_path}.download_hestia")
@@ -138,13 +133,11 @@ IDS_SHOULD_RUN = [p[0] for p in PARAMS_SHOULD_RUN]
138
133
  @patch(f"{utils_path}.get_upland_rice_crop_terms", return_value=UPLAND_RICE_CROP_TERM_IDS)
139
134
  @patch(f"{utils_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
140
135
  @patch(f"{utils_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
141
- @patch(f"{utils_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
142
136
  @patch(f"{utils_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
143
137
  @patch(f"{tier_2_path}.related_cycles")
144
138
  def test_should_run(
145
139
  mock_related_cycles: MagicMock,
146
140
  mock_get_cover_crop_property_terms: MagicMock, # utils mocks
147
- mock_get_crop_residue_incorporated_or_left_on_field_terms: MagicMock,
148
141
  mock_get_irrigated_terms: MagicMock,
149
142
  mock_get_residue_removed_or_burnt_terms: MagicMock,
150
143
  mock_get_upland_rice_crop_terms: MagicMock,
@@ -172,7 +165,6 @@ def test_should_run(
172
165
 
173
166
  # Ensure that API calls to retrieve term IDs are properly cached.
174
167
  mock_get_cover_crop_property_terms.call_count <= 1
175
- mock_get_crop_residue_incorporated_or_left_on_field_terms.call_count <= 1
176
168
  mock_get_irrigated_terms.call_count <= 1
177
169
  mock_get_residue_removed_or_burnt_terms.call_count <= 1
178
170
  mock_get_upland_rice_crop_terms.call_count <= 1
@@ -206,6 +198,7 @@ def test_should_run_no_data(
206
198
  PARAMS_RUN = [subfolder for subfolder, should_run in PARAMS_SHOULD_RUN if should_run]
207
199
 
208
200
 
201
+ # TODO: update mocks
209
202
  @mark.parametrize("subfolder", PARAMS_RUN)
210
203
  @patch(f"{term_path}.search")
211
204
  @patch(f"{property_path}.download_hestia")
@@ -214,7 +207,6 @@ PARAMS_RUN = [subfolder for subfolder, should_run in PARAMS_SHOULD_RUN if should
214
207
  @patch(f"{utils_path}.get_upland_rice_crop_terms", return_value=UPLAND_RICE_CROP_TERM_IDS)
215
208
  @patch(f"{utils_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
216
209
  @patch(f"{utils_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
217
- @patch(f"{utils_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
218
210
  @patch(f"{utils_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
219
211
  @patch(f"{tier_2_path}.related_cycles")
220
212
  @patch(f"{tier_2_path}.calc_descriptive_stats", side_effect=fake_calc_descriptive_stats)
@@ -232,7 +224,6 @@ def test_run(
232
224
  _mock_calc_descriptive_stats_t2: MagicMock,
233
225
  mock_related_cycles: MagicMock,
234
226
  mock_get_cover_crop_property_terms: MagicMock, # utils mocks
235
- mock_get_crop_residue_incorporated_or_left_on_field_terms: MagicMock,
236
227
  mock_get_irrigated_terms: MagicMock,
237
228
  mock_get_residue_removed_or_burnt_terms: MagicMock,
238
229
  mock_get_upland_rice_crop_terms: MagicMock,
@@ -263,7 +254,6 @@ def test_run(
263
254
 
264
255
  # Ensure that API calls to retrieve term IDs are properly cached.
265
256
  mock_get_cover_crop_property_terms.call_count <= 1
266
- mock_get_crop_residue_incorporated_or_left_on_field_terms.call_count <= 1
267
257
  mock_get_irrigated_terms.call_count <= 1
268
258
  mock_get_residue_removed_or_burnt_terms.call_count <= 1
269
259
  mock_get_upland_rice_crop_terms.call_count <= 1
@@ -277,13 +267,15 @@ def test_run(
277
267
 
278
268
 
279
269
  PARAMS_RUN_WITH_STATS = [
280
- "tier-1-and-2/with-stats", # Closes issue 753
281
- "tier-1/cropland-with-stats", # Closes issue 753
282
- "tier-1/land-use-change-with-stats", # Closes issue 753
283
- "tier-2/with-stats" # Closes issue 753
270
+ "tier-1-and-2/with-stats", # Closes issue 753
271
+ "tier-1-and-2/with-residues-removed-with-stats", # Closes issue #758 and #846
272
+ "tier-1/cropland-with-stats", # Closes issue 753
273
+ "tier-1/land-use-change-with-stats", # Closes issue 753
274
+ "tier-2/with-stats" # Closes issue 753
284
275
  ]
285
276
 
286
277
 
278
+ # TODO: update mocks
287
279
  @mark.parametrize("subfolder", PARAMS_RUN_WITH_STATS)
288
280
  @patch(f"{term_path}.search")
289
281
  @patch(f"{property_path}.download_hestia")
@@ -292,7 +284,6 @@ PARAMS_RUN_WITH_STATS = [
292
284
  @patch(f"{utils_path}.get_upland_rice_crop_terms", return_value=UPLAND_RICE_CROP_TERM_IDS)
293
285
  @patch(f"{utils_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
294
286
  @patch(f"{utils_path}.get_irrigated_terms", return_value=IRRIGATED_TERM_IDS)
295
- @patch(f"{utils_path}.get_crop_residue_incorporated_or_left_on_field_terms", return_value=CROP_RESIDUE_INCORP_TERM_IDS)
296
287
  @patch(f"{utils_path}.get_cover_crop_property_terms", return_value=COVER_CROP_PROPERTY_TERM_IDS)
297
288
  @patch(f"{tier_2_path}.related_cycles")
298
289
  @patch(f"{tier_2_path}._new_measurement", side_effect=fake_new_measurement)
@@ -302,7 +293,6 @@ def test_run_with_stats(
302
293
  _mock_new_measurement_t2: MagicMock,
303
294
  mock_related_cycles: MagicMock,
304
295
  mock_get_cover_crop_property_terms: MagicMock, # utils mocks
305
- mock_get_crop_residue_incorporated_or_left_on_field_terms: MagicMock,
306
296
  mock_get_irrigated_terms: MagicMock,
307
297
  mock_get_residue_removed_or_burnt_terms: MagicMock,
308
298
  mock_get_upland_rice_crop_terms: MagicMock,
@@ -333,7 +323,6 @@ def test_run_with_stats(
333
323
 
334
324
  # Ensure that API calls to retrieve term IDs are properly cached.
335
325
  mock_get_cover_crop_property_terms.call_count <= 1
336
- mock_get_crop_residue_incorporated_or_left_on_field_terms.call_count <= 1
337
326
  mock_get_irrigated_terms.call_count <= 1
338
327
  mock_get_residue_removed_or_burnt_terms.call_count <= 1
339
328
  mock_get_upland_rice_crop_terms.call_count <= 1
@@ -25,14 +25,6 @@ YEARS = 100
25
25
  MONTHS = 12
26
26
 
27
27
 
28
- CROP_RESIDUE_INCORP_TERM_IDS = [
29
- "aboveGroundCropResidueIncorporated",
30
- "aboveGroundCropResidueLeftOnField",
31
- "belowGroundCropResidue",
32
- "discardedCropIncorporated",
33
- "discardedCropLeftOnField"
34
- ]
35
-
36
28
  IRRIGATED_TERM_IDS = [
37
29
  "rainfedDeepWater",
38
30
  "rainfedDeepWaterWaterDepth100Cm",
@@ -17,8 +17,24 @@ TERM_BY_ID = {
17
17
  'oatPlant': {'@type': 'Term', '@id': 'oatPlant', 'termType': TermTermType.LANDCOVER.value},
18
18
  'agatiTree': {'@type': 'Term', '@id': 'agatiTree', 'termType': TermTermType.LANDCOVER.value},
19
19
  'wildGarlicPlant': {'@type': 'Term', '@id': 'wildGarlicPlant', 'termType': TermTermType.LANDCOVER.value},
20
+ 'permanentPasture': {
21
+ "@type": "Term",
22
+ "@id": "permanentPasture",
23
+ "name": "Permanent pasture",
24
+ "termType": TermTermType.LANDCOVER.value,
25
+ "units": "% area"
26
+ },
27
+ 'animalHousing': {
28
+ "@type": "Term",
29
+ "@id": "animalHousing",
30
+ "name": "Animal housing",
31
+ "termType": TermTermType.LANDCOVER.value,
32
+ "units": "% area"
33
+ }
20
34
  }
21
35
 
36
+ LAND_COVER_TERM_BY_SITE_TYPE = {"permanent pasture": "permanentPasture", "animal housing": "animalHousing"}
37
+
22
38
 
23
39
  def lookup_side_effect(*args, **kwargs):
24
40
  # Values taken from real lookups.
@@ -270,7 +286,7 @@ def test_should_run(mock_related_cycles, *args):
270
286
  ("Example 2", f"{fixtures_folder}/inputs/example2"),
271
287
  ("Example 3", f"{fixtures_folder}/inputs/example3"),
272
288
  ("Example 4", f"{fixtures_folder}/inputs/example4"),
273
- ("Condense Nodes", f"{fixtures_folder}/inputs/condense_nodes")
289
+ ("Condense Nodes", f"{fixtures_folder}/inputs/condense_nodes"),
274
290
  # Expected:
275
291
  # - appleTree (81) x 3 condenses 2020-03-01 to 2021-02-15
276
292
  # - animalManureUsed (true) x 2 condenses 2001-04-01 to 2001-12-31
@@ -282,12 +298,24 @@ def test_should_run(mock_related_cycles, *args):
282
298
  # - sassafrasTree (86) x 2 condenses 2001-01-01 to 2004-12-31
283
299
  # - bananaPlant (87) does not condense [non-consecutive years]
284
300
  # - durianTree (89) does not condense [dates overwritten See 808]
301
+ ("Site Type", f"{fixtures_folder}/inputs/site_type")
285
302
  ]
286
303
  )
287
- @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda id, *args: TERM_BY_ID[id])
304
+ @patch(
305
+ f"{CLASS_PATH}.get_landCover_term_id_from_site_type",
306
+ side_effect=lambda site_type: LAND_COVER_TERM_BY_SITE_TYPE[site_type]
307
+ )
308
+ @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda term_id, *args: TERM_BY_ID[term_id])
288
309
  @patch(f"{CLASS_PATH}.related_cycles")
289
310
  @patch(f"{CLASS_PATH}._get_lookup_with_debug", side_effect=lookup_side_effect)
290
- def test_run(mock_get_lookup_with_debug, mock_related_cycles, mock_download, test_name, fixture_path):
311
+ def test_run(
312
+ mock_get_lookup_with_debug,
313
+ mock_related_cycles,
314
+ mock_download,
315
+ mock_land_cover_lookup,
316
+ test_name,
317
+ fixture_path
318
+ ):
291
319
  with open(f"{fixture_path}/cycles.jsonld", encoding='utf-8') as f:
292
320
  cycles = json.load(f)
293
321
  mock_related_cycles.return_value = cycles