hestia-earth-models 0.70.2__py3-none-any.whl → 0.70.3__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.
@@ -182,6 +182,14 @@
182
182
  "mergeStrategy": "list",
183
183
  "stage": 1
184
184
  },
185
+ {
186
+ "key": "practices",
187
+ "model": "cycle",
188
+ "value": "practice.landCover",
189
+ "runStrategy": "always",
190
+ "mergeStrategy": "list",
191
+ "stage": 1
192
+ },
185
193
  {
186
194
  "key": "products",
187
195
  "model": "hestia",
@@ -0,0 +1,181 @@
1
+ from functools import reduce
2
+ from hestia_earth.schema import TermTermType, SiteSiteType
3
+ from hestia_earth.utils.model import filter_list_term_type
4
+ from hestia_earth.utils.tools import non_empty_list, flatten, list_sum
5
+
6
+ from hestia_earth.models.log import logRequirements, logShouldRun
7
+ from hestia_earth.models.utils import _omit, _include
8
+ from hestia_earth.models.utils.practice import _new_practice
9
+ from hestia_earth.models.utils.term import get_lookup_value
10
+ from hestia_earth.models.utils.blank_node import condense_nodes
11
+ from hestia_earth.models.utils.crop import get_landCover_term_id
12
+ from .. import MODEL
13
+
14
+ REQUIREMENTS = {
15
+ "Cycle": {
16
+ "endDate": "",
17
+ "products": [
18
+ {
19
+ "@type": "Product",
20
+ "term.termType": ["crop", "forage"],
21
+ "optional": {
22
+ "startDate": "",
23
+ "endDate": ""
24
+ }
25
+ }
26
+ ],
27
+ "site": {
28
+ "@type": "Site",
29
+ "siteType": "cropland"
30
+ },
31
+ "none": {
32
+ "practices": [{"@type": "Practice", "term.termType": "landCover"}]
33
+ },
34
+ "optional": {
35
+ "startDate": ""
36
+ }
37
+ }
38
+ }
39
+ RETURNS = {
40
+ "Practice": [{
41
+ "term.termType": "landCover",
42
+ "value": "",
43
+ "endDate": "",
44
+ "startDate": ""
45
+ }]
46
+ }
47
+ LOOKUPS = {
48
+ "crop": ["landCoverTermId", "maximumCycleDuration"],
49
+ "forage": ["landCoverTermId"],
50
+ "property": ["GAP_FILL_TO_MANAGEMENT", "CALCULATE_TOTAL_LAND_COVER_SHARE_SEPARATELY"]
51
+ }
52
+ MODEL_KEY = 'landCover'
53
+
54
+
55
+ def practice(data: dict):
56
+ node = _new_practice(data.get('id'))
57
+ node['value'] = [data['value']]
58
+ node['endDate'] = data['endDate']
59
+ if data.get('startDate'):
60
+ node['startDate'] = data['startDate']
61
+ if data.get('properties'):
62
+ node['properties'] = data['properties']
63
+ return node
64
+
65
+
66
+ def _should_gap_fill(term: dict):
67
+ value = get_lookup_value(lookup_term=term, column='GAP_FILL_TO_MANAGEMENT')
68
+ return bool(value)
69
+
70
+
71
+ def _filter_properties(blank_node: dict):
72
+ properties = list(filter(lambda p: _should_gap_fill(p.get('term', {})), blank_node.get('properties', [])))
73
+ return _omit(blank_node, ['properties']) | ({'properties': properties} if properties else {})
74
+
75
+
76
+ def _map_to_value(value: dict):
77
+ return {
78
+ 'id': value.get('term', {}).get('@id'),
79
+ 'value': value.get('value'),
80
+ 'startDate': value.get('startDate'),
81
+ 'endDate': value.get('endDate'),
82
+ 'properties': value.get('properties')
83
+ }
84
+
85
+
86
+ def _copy_item_if_exists(source: dict, keys: list[str] = None, dest: dict = None) -> dict:
87
+ return reduce(lambda p, c: p | ({c: source[c]} if source.get(c) else {}), keys or [], dest or {})
88
+
89
+
90
+ def _run(cycle: dict, products: list, total: float):
91
+ # remove any properties that should not get gap-filled
92
+ products = list(map(_filter_properties, products))
93
+
94
+ nodes = [
95
+ _map_to_value(_include(cycle, ["startDate", "endDate"]) | _copy_item_if_exists(
96
+ source=product,
97
+ keys=['properties', 'startDate', 'endDate'],
98
+ dest={
99
+ "term": {'@id': product.get('land-cover-id')},
100
+ "value": round((100 - total) / len(products), 2)
101
+ }
102
+ ))
103
+ for product in products
104
+ ]
105
+
106
+ return condense_nodes(list(map(practice, nodes)))
107
+
108
+
109
+ def _should_group_landCover(term: dict):
110
+ value = get_lookup_value(lookup_term=term, column='CALCULATE_TOTAL_LAND_COVER_SHARE_SEPARATELY')
111
+ return bool(value)
112
+
113
+
114
+ def _has_prop_grouped_with_landCover(product: dict):
115
+ return bool(
116
+ next((
117
+ p
118
+ for p in product.get('properties', [])
119
+ if _should_group_landCover(p.get('term', {}))
120
+ ), None)
121
+ )
122
+
123
+
124
+ def _product_wit_landCover_id(product: dict):
125
+ landCover_id = get_landCover_term_id(product.get('term', {}))
126
+ return product | {'land-cover-id': landCover_id} if landCover_id else None
127
+
128
+
129
+ def _should_run(cycle: dict):
130
+ is_cropland = cycle.get('site', {}).get('siteType') == SiteSiteType.CROPLAND.value
131
+
132
+ practices = filter_list_term_type(cycle.get('practices', []), TermTermType.LANDCOVER)
133
+ # split practices with properties that group with landCover
134
+ practices_max_100 = [
135
+ p for p in practices if _has_prop_grouped_with_landCover(p)
136
+ ]
137
+ total_practices_max_100 = list_sum([
138
+ list_sum(p.get('value', []))
139
+ for p in practices_max_100
140
+ ])
141
+ practices_without_grouped_props = [
142
+ p for p in practices if not _has_prop_grouped_with_landCover(p)
143
+ ]
144
+
145
+ products = filter_list_term_type(cycle.get('products', []), [TermTermType.CROP, TermTermType.FORAGE])
146
+ # only take products with a matching landCover term
147
+ products = non_empty_list(map(_product_wit_landCover_id, products))
148
+
149
+ # Products that can sum up to 100% => run if total is below 100%
150
+ products_max_100 = [
151
+ p for p in products
152
+ if _has_prop_grouped_with_landCover(p)
153
+ ] if total_practices_max_100 < 100 else []
154
+
155
+ # Products that must sum up to 100% => can not run practices already exist as already 100%
156
+ products_is_100 = [
157
+ p for p in products
158
+ if not _has_prop_grouped_with_landCover(p)
159
+ ] if not practices_without_grouped_props else []
160
+
161
+ has_crop_forage_products = bool(products_max_100 + products_is_100)
162
+
163
+ logRequirements(cycle, model=MODEL, model_key=MODEL_KEY,
164
+ is_cropland=is_cropland,
165
+ has_crop_forage_products=has_crop_forage_products)
166
+
167
+ should_run = all([is_cropland, has_crop_forage_products])
168
+ logShouldRun(cycle, MODEL, None, should_run, model_key=MODEL_KEY)
169
+
170
+ return should_run, [
171
+ (products_max_100, total_practices_max_100),
172
+ (products_is_100, 0)
173
+ ]
174
+
175
+
176
+ def run(cycle: dict):
177
+ should_run, products_list = _should_run(cycle)
178
+ return flatten([
179
+ _run(cycle, products, total)
180
+ for products, total in products_list if products
181
+ ]) if should_run else []
@@ -46,7 +46,7 @@ def _run(excreta_EF_input: float):
46
46
  def _should_run(cycle: dict):
47
47
  excreta_complete = _is_term_type_complete(cycle, TermTermType.EXCRETA)
48
48
  excreta_EF_input = get_excreta_inputs_with_factor(
49
- cycle, f"{list(LOOKUPS.keys())[0]}.csv", excreta_convertion_func=total_excreta_tan, model=MODEL, term=TERM_ID
49
+ cycle, f"{list(LOOKUPS.keys())[0]}.csv", excreta_conversion_func=total_excreta_tan, model=MODEL, term=TERM_ID
50
50
  )
51
51
 
52
52
  logRequirements(cycle, model=MODEL, term=TERM_ID,
@@ -1,6 +1,5 @@
1
1
  from typing import List
2
2
  from datetime import timedelta, datetime
3
- from functools import reduce
4
3
  from hestia_earth.schema import SchemaType, TermTermType, SiteSiteType, COMPLETENESS_MAPPING
5
4
  from hestia_earth.utils.lookup import column_name, get_table_value, download_lookup
6
5
  from hestia_earth.utils.model import filter_list_term_type
@@ -8,7 +7,7 @@ from hestia_earth.utils.tools import safe_parse_float, flatten
8
7
  from hestia_earth.utils.blank_node import get_node_value
9
8
 
10
9
  from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
11
- from hestia_earth.models.utils import _include, _omit, group_by
10
+ from hestia_earth.models.utils import _include, group_by
12
11
  from hestia_earth.models.utils.management import _new_management
13
12
  from hestia_earth.models.utils.term import get_lookup_value
14
13
  from hestia_earth.models.utils.blank_node import condense_nodes, DatestrFormat, _gapfill_datestr, DatestrGapfillMode
@@ -24,20 +23,16 @@ REQUIREMENTS = {
24
23
  "Cycle": [{
25
24
  "@type": "Cycle",
26
25
  "endDate": "",
27
- "products": [
28
- {
29
- "@type": "Product",
30
- "term.termType": ["crop", "forage", "landCover"]
31
- }
32
- ],
33
26
  "practices": [
34
27
  {
28
+ "@type": "Practice",
35
29
  "term.termType": [
36
30
  "waterRegime",
37
31
  "tillage",
38
32
  "cropResidueManagement",
39
33
  "landUseManagement",
40
- "system"
34
+ "system",
35
+ "landCover"
41
36
  ],
42
37
  "value": ""
43
38
  }
@@ -62,7 +57,6 @@ REQUIREMENTS = {
62
57
  }
63
58
  RETURNS = {
64
59
  "Management": [{
65
- "@type": "Management",
66
60
  "term.termType": [
67
61
  "landCover", "waterRegime", "tillage", "cropResidueManagement", "landUseManagement", "system"
68
62
  ],
@@ -78,7 +72,7 @@ LOOKUPS = {
78
72
  "organicFertiliser": "ANIMAL_MANURE",
79
73
  "soilAmendment": "PRACTICE_INCREASING_C_INPUT",
80
74
  "landUseManagement": "GAP_FILL_TO_MANAGEMENT",
81
- "property": ["GAP_FILL_TO_MANAGEMENT", "CALCULATE_TOTAL_LAND_COVER_SHARE_SEPARATELY"]
75
+ "property": "GAP_FILL_TO_MANAGEMENT"
82
76
  }
83
77
  MODEL_KEY = 'management'
84
78
 
@@ -87,7 +81,8 @@ _PRACTICES_TERM_TYPES = [
87
81
  TermTermType.TILLAGE,
88
82
  TermTermType.CROPRESIDUEMANAGEMENT,
89
83
  TermTermType.LANDUSEMANAGEMENT,
90
- TermTermType.SYSTEM
84
+ TermTermType.SYSTEM,
85
+ TermTermType.LANDCOVER
91
86
  ]
92
87
  _PRACTICES_COMPLETENESS_MAPPING = COMPLETENESS_MAPPING.get(SchemaType.PRACTICE.value, {})
93
88
  _ANIMAL_MANURE_USED_TERM_ID = "animalManureUsed"
@@ -125,7 +120,6 @@ _INPUT_RULES = {
125
120
  _SKIP_LAND_COVER_SITE_TYPES = [
126
121
  SiteSiteType.CROPLAND.value
127
122
  ]
128
- _CYCLE_DATE_TERM_TYPES = {TermTermType.CROP.value, TermTermType.FORAGE.value}
129
123
 
130
124
 
131
125
  def management(data: dict):
@@ -188,11 +182,6 @@ def _should_gap_fill(term: dict):
188
182
  return bool(value)
189
183
 
190
184
 
191
- def _filter_properties(blank_node: dict):
192
- properties = list(filter(lambda p: _should_gap_fill(p.get('term', {})), blank_node.get('properties', [])))
193
- return _omit(blank_node, ['properties']) | ({'properties': properties} if properties else {})
194
-
195
-
196
185
  def _map_to_value(value: dict):
197
186
  return {
198
187
  'id': value.get('term', {}).get('@id'),
@@ -207,10 +196,6 @@ def _extract_node_value(node: dict) -> dict:
207
196
  return node | {'value': get_node_value(node)}
208
197
 
209
198
 
210
- def _copy_item_if_exists(source: dict, keys: list[str] = None, dest: dict = None) -> dict:
211
- return reduce(lambda p, c: p | ({c: source[c]} if source.get(c) else {}), keys or [], dest or {})
212
-
213
-
214
199
  def _get_relevant_items(cycle: dict, item_name: str, term_types: List[TermTermType], completeness_mapping: dict = {}):
215
200
  """
216
201
  Get items from the list of cycles with any of the relevant terms.
@@ -278,84 +263,6 @@ def _run_from_siteType(site: dict, cycle: dict):
278
263
  }] if should_run else []
279
264
 
280
265
 
281
- def _run_products(cycle: dict, products: list, total_products: int = None, use_cycle_dates: bool = False):
282
- default_dates = _include_with_date_gap_fill(cycle, ["startDate", "endDate"])
283
- return [
284
- _map_to_value(default_dates | _copy_item_if_exists(
285
- source=product,
286
- keys=['properties', 'startDate', 'endDate'],
287
- dest={
288
- "term": {'@id': get_landCover_term_id(product.get('term', {}))},
289
- "value": round(100 / (total_products or len(products)), 2)
290
- }
291
- ) | (
292
- default_dates if use_cycle_dates or product.get("term", {}).get("termType") in _CYCLE_DATE_TERM_TYPES
293
- else {}
294
- ))
295
- for product in products
296
- ]
297
-
298
-
299
- def _run_from_landCover(cycle: dict, crop_forage_products: list):
300
- """
301
- Copy landCover items, and include crop/forage landCover items with properties to count in ratio.
302
- """
303
- land_cover_products = [
304
- _map_to_value(_extract_node_value(
305
- _include_with_date_gap_fill(
306
- value=product,
307
- keys=["term", "value", "startDate", "endDate", "properties"]
308
- )
309
- )) for product in _get_relevant_items(
310
- cycle=cycle,
311
- item_name="products",
312
- term_types=[TermTermType.LANDCOVER]
313
- )
314
- ]
315
- return land_cover_products + _run_products(
316
- cycle,
317
- crop_forage_products,
318
- total_products=len(crop_forage_products) + len(land_cover_products),
319
- use_cycle_dates=True
320
- )
321
-
322
-
323
- def _should_group_landCover(term: dict):
324
- value = get_lookup_value(lookup_term=term, column='CALCULATE_TOTAL_LAND_COVER_SHARE_SEPARATELY')
325
- return bool(value)
326
-
327
-
328
- def _has_prop_grouped_with_landCover(product: dict):
329
- return bool(
330
- next((
331
- p
332
- for p in product.get('properties', [])
333
- if _should_group_landCover(p.get('term', {}))
334
- ), None)
335
- )
336
-
337
-
338
- def _run_from_crop_forage(cycle: dict, site: dict):
339
- products = _get_relevant_items(
340
- cycle=cycle,
341
- item_name="products",
342
- term_types=[TermTermType.CROP, TermTermType.FORAGE]
343
- ) if site.get("siteType", "") == SiteSiteType.CROPLAND.value else []
344
- # only take products with a matching landCover term
345
- products = [p for p in products if get_landCover_term_id(p.get('term', {}))]
346
- # remove any properties that should not get gap-filled
347
- products = list(map(_filter_properties, products))
348
-
349
- # split products with properties that group with landCover
350
- products_with_gap_filled_props = [p for p in products if _has_prop_grouped_with_landCover(p)]
351
- products_without_gap_filled_props = [p for p in products if not _has_prop_grouped_with_landCover(p)]
352
-
353
- return _run_from_landCover(
354
- cycle=cycle,
355
- crop_forage_products=products_with_gap_filled_props
356
- ) + _run_products(cycle, products_without_gap_filled_props, use_cycle_dates=False)
357
-
358
-
359
266
  def _should_run_practice(practice: dict):
360
267
  """
361
268
  Include only landUseManagement practices where GAP_FILL_TO_MANAGEMENT = True
@@ -369,7 +276,7 @@ def _run_from_practices(cycle: dict):
369
276
  _extract_node_value(
370
277
  _include_with_date_gap_fill(
371
278
  value=practice,
372
- keys=["term", "value", "startDate", "endDate"]
279
+ keys=["term", "value", "startDate", "endDate", "properties"]
373
280
  )
374
281
  ) for practice in _get_relevant_items(
375
282
  cycle=cycle,
@@ -378,18 +285,16 @@ def _run_from_practices(cycle: dict):
378
285
  completeness_mapping=_PRACTICES_COMPLETENESS_MAPPING
379
286
  )
380
287
  ]
381
- practices = list(map(_map_to_value, filter(_should_run_practice, practices)))
382
- return practices
288
+ return list(map(_map_to_value, filter(_should_run_practice, practices)))
383
289
 
384
290
 
385
291
  def _run_cycle(site: dict, cycle: dict):
386
292
  inputs = _run_from_inputs(site, cycle)
387
- products = _run_from_crop_forage(site=site, cycle=cycle)
388
293
  site_types = _run_from_siteType(site=site, cycle=cycle)
389
294
  practices = _run_from_practices(cycle)
390
295
  return [
391
296
  node | {'cycle-id': cycle.get('@id')}
392
- for node in inputs + products + site_types + practices
297
+ for node in inputs + site_types + practices
393
298
  ]
394
299
 
395
300
 
@@ -409,5 +314,4 @@ def run(site: dict):
409
314
  )
410
315
  logShouldRun(site, MODEL, id, True, model_key=MODEL_KEY)
411
316
 
412
- management_nodes = condense_nodes(list(map(management, nodes)))
413
- return management_nodes
317
+ return condense_nodes(list(map(management, nodes)))
@@ -98,7 +98,7 @@ def _should_run(cycle: dict):
98
98
 
99
99
  use_excreta_management = _should_run_with_excreta_management(cycle)
100
100
  excreta_EF_input = get_excreta_inputs_with_factor(
101
- cycle, f"{list(LOOKUPS.keys())[0]}.csv", excreta_convertion_func=total_excreta, model=MODEL, term=TERM_ID
101
+ cycle, f"{list(LOOKUPS.keys())[0]}.csv", excreta_conversion_func=total_excreta, model=MODEL, term=TERM_ID
102
102
  ) if use_excreta_management else None
103
103
 
104
104
  logRequirements(cycle, model=MODEL, term=TERM_ID,
@@ -204,11 +204,19 @@ _CARBON_INPUT_PROPERTY_TERM_IDS = [
204
204
  _DRY_MATTER_TERM_ID
205
205
  ]
206
206
 
207
- _CARBON_SOURCE_TERM_TYPES = [
207
+ _INPUT_CARBON_SOURCE_TERM_TYPES = [
208
208
  TermTermType.ORGANICFERTILISER.value,
209
209
  TermTermType.SOILAMENDMENT.value
210
210
  ]
211
211
 
212
+ _PRACTICE_CARBON_SOURCE_TERM_TYPES = [
213
+ TermTermType.LANDCOVER
214
+ ]
215
+
216
+ _PRODUCT_CARBON_SOURCE_TERM_TYPES = [
217
+ TermTermType.CROPRESIDUE
218
+ ]
219
+
212
220
  _VALID_SITE_TYPES = [
213
221
  SiteSiteType.CROPLAND.value
214
222
  ]
@@ -1447,7 +1455,10 @@ def _get_carbon_sources(cycle: dict) -> list[CarbonSource]:
1447
1455
  list[CarbonSource]
1448
1456
  A formatted list of `CarbonSource`s.
1449
1457
  """
1450
- inputs_and_products = cycle.get("inputs", []) + cycle.get("products", [])
1458
+ carbon_source_nodes = filter_list_term_type(
1459
+ cycle.get("inputs", []) + cycle.get("practices", []) + cycle.get("products", []),
1460
+ _INPUT_CARBON_SOURCE_TERM_TYPES + _PRACTICE_CARBON_SOURCE_TERM_TYPES + _PRODUCT_CARBON_SOURCE_TERM_TYPES
1461
+ )
1451
1462
 
1452
1463
  group_fac = cycle.get('fraction_of_group_duration')
1453
1464
  node_fac = cycle.get('fraction_of_node_duration')
@@ -1466,7 +1477,7 @@ def _get_carbon_sources(cycle: dict) -> list[CarbonSource]:
1466
1477
  if validator(node)
1467
1478
  ),
1468
1479
  None
1469
- ) for node in inputs_and_products
1480
+ ) for node in carbon_source_nodes
1470
1481
  ])
1471
1482
 
1472
1483
 
@@ -1603,7 +1614,7 @@ def _should_run_carbon_source(node: dict) -> bool:
1603
1614
  """
1604
1615
  return any([
1605
1616
  node.get("term", {}).get("@id") in _CARBON_SOURCE_TERM_IDS,
1606
- node.get("term", {}).get("termType") in _CARBON_SOURCE_TERM_TYPES
1617
+ node.get("term", {}).get("termType") in _INPUT_CARBON_SOURCE_TERM_TYPES
1607
1618
  ])
1608
1619
 
1609
1620
 
@@ -3925,11 +3925,11 @@
3925
3925
  },
3926
3926
  {
3927
3927
  "@type": "Term",
3928
- "@id": "energyDigestibilityOtherAnimals"
3928
+ "@id": "energyDigestibilityPoultry"
3929
3929
  },
3930
3930
  {
3931
3931
  "@type": "Term",
3932
- "@id": "energyDigestibilityPoultry"
3932
+ "@id": "energyDigestibilityOtherAnimals"
3933
3933
  },
3934
3934
  {
3935
3935
  "@type": "Term",
@@ -3954,27 +3954,27 @@
3954
3954
  },
3955
3955
  {
3956
3956
  "@type": "Term",
3957
- "@id": "excretaDeerKgN"
3957
+ "@id": "excretaPoultryKgN"
3958
3958
  },
3959
3959
  {
3960
3960
  "@type": "Term",
3961
- "@id": "excretaSolidFishCrustaceansKgN"
3961
+ "@id": "excretaBeefCattleExceptFeedlotFedKgN"
3962
3962
  },
3963
3963
  {
3964
3964
  "@type": "Term",
3965
- "@id": "excretaGoatsKgN"
3965
+ "@id": "excretaDucksKgN"
3966
3966
  },
3967
3967
  {
3968
3968
  "@type": "Term",
3969
- "@id": "excretaPoultryKgN"
3969
+ "@id": "excretaDeerKgN"
3970
3970
  },
3971
3971
  {
3972
3972
  "@type": "Term",
3973
- "@id": "excretaBeefCattleExceptFeedlotFedKgN"
3973
+ "@id": "excretaSolidFishCrustaceansKgN"
3974
3974
  },
3975
3975
  {
3976
3976
  "@type": "Term",
3977
- "@id": "excretaDucksKgN"
3977
+ "@id": "excretaGoatsKgN"
3978
3978
  },
3979
3979
  {
3980
3980
  "@type": "Term",
@@ -3996,10 +3996,6 @@
3996
3996
  "@type": "Term",
3997
3997
  "@id": "excretaTurkeysKgN"
3998
3998
  },
3999
- {
4000
- "@type": "Term",
4001
- "@id": "excretaBeefCattleFeedlotFedKgN"
4002
- },
4003
3999
  {
4004
4000
  "@type": "Term",
4005
4001
  "@id": "excretaKgN"
@@ -4012,6 +4008,10 @@
4012
4008
  "@type": "Term",
4013
4009
  "@id": "excretaInsectsKgN"
4014
4010
  },
4011
+ {
4012
+ "@type": "Term",
4013
+ "@id": "excretaBeefCattleFeedlotFedKgN"
4014
+ },
4015
4015
  {
4016
4016
  "@type": "Term",
4017
4017
  "@id": "excretaSheepKgN"
@@ -4067,15 +4067,15 @@
4067
4067
  },
4068
4068
  {
4069
4069
  "@type": "Term",
4070
- "@id": "excretaCamelsKgVs"
4070
+ "@id": "excretaPigsKgVs"
4071
4071
  },
4072
4072
  {
4073
4073
  "@type": "Term",
4074
- "@id": "excretaPigsKgVs"
4074
+ "@id": "excretaDucksKgVs"
4075
4075
  },
4076
4076
  {
4077
4077
  "@type": "Term",
4078
- "@id": "excretaDucksKgVs"
4078
+ "@id": "excretaCamelsKgVs"
4079
4079
  },
4080
4080
  {
4081
4081
  "@type": "Term",
@@ -4111,19 +4111,19 @@
4111
4111
  },
4112
4112
  {
4113
4113
  "@type": "Term",
4114
- "@id": "excretaBeefCattleExceptFeedlotFedKgVs"
4114
+ "@id": "excretaBeefCattleFeedlotFedKgVs"
4115
4115
  },
4116
4116
  {
4117
4117
  "@type": "Term",
4118
- "@id": "excretaDeerKgVs"
4118
+ "@id": "excretaBeefCattleExceptFeedlotFedKgVs"
4119
4119
  },
4120
4120
  {
4121
4121
  "@type": "Term",
4122
- "@id": "excretaBeefCattleFeedlotFedKgVs"
4122
+ "@id": "excretaKgVs"
4123
4123
  },
4124
4124
  {
4125
4125
  "@type": "Term",
4126
- "@id": "excretaKgVs"
4126
+ "@id": "excretaDeerKgVs"
4127
4127
  }
4128
4128
  ]
4129
4129
  },
@@ -4180,7 +4180,7 @@
4180
4180
  "@type": "Term",
4181
4181
  "name": "Generic crop, seed",
4182
4182
  "@id": "genericCropSeed",
4183
- "_score": 22.649164
4183
+ "_score": 22.662407
4184
4184
  }
4185
4185
  ]
4186
4186
  },
@@ -4462,169 +4462,169 @@
4462
4462
  "@type": "Term",
4463
4463
  "name": "Glass or high accessible cover",
4464
4464
  "@id": "glassOrHighAccessibleCover",
4465
- "_score": 61.805214
4465
+ "_score": 61.776108
4466
4466
  },
4467
4467
  {
4468
4468
  "@type": "Term",
4469
4469
  "name": "Sea or ocean",
4470
4470
  "@id": "seaOrOcean",
4471
- "_score": 51.3974
4471
+ "_score": 50.309784
4472
4472
  },
4473
4473
  {
4474
4474
  "@type": "Term",
4475
4475
  "name": "River or stream",
4476
4476
  "@id": "riverOrStream",
4477
- "_score": 48.80929
4477
+ "_score": 48.736115
4478
4478
  },
4479
4479
  {
4480
4480
  "@type": "Term",
4481
- "name": "Other natural vegetation",
4482
- "@id": "otherNaturalVegetation",
4483
- "_score": 41.345604
4481
+ "name": "Agri-food processor",
4482
+ "@id": "agriFoodProcessor",
4483
+ "_score": 41.47336
4484
4484
  },
4485
4485
  {
4486
4486
  "@type": "Term",
4487
- "name": "Agri-food processor",
4488
- "@id": "agriFoodProcessor",
4489
- "_score": 41.200302
4487
+ "name": "Other natural vegetation",
4488
+ "@id": "otherNaturalVegetation",
4489
+ "_score": 41.24772
4490
4490
  },
4491
4491
  {
4492
4492
  "@type": "Term",
4493
4493
  "name": "Food retailer",
4494
4494
  "@id": "foodRetailer",
4495
- "_score": 39.40757
4495
+ "_score": 39.13082
4496
4496
  },
4497
4497
  {
4498
4498
  "@type": "Term",
4499
4499
  "name": "Natural forest",
4500
4500
  "@id": "naturalForest",
4501
- "_score": 30.954716
4501
+ "_score": 30.847563
4502
4502
  },
4503
4503
  {
4504
4504
  "@type": "Term",
4505
4505
  "name": "Permanent pasture",
4506
4506
  "@id": "permanentPasture",
4507
- "_score": 28.733797
4507
+ "_score": 28.668303
4508
4508
  },
4509
4509
  {
4510
4510
  "@type": "Term",
4511
4511
  "name": "Animal housing",
4512
4512
  "@id": "animalHousing",
4513
- "_score": 27.314993
4513
+ "_score": 27.123905
4514
4514
  },
4515
4515
  {
4516
4516
  "@type": "Term",
4517
4517
  "name": "Root or tuber crop plant",
4518
4518
  "@id": "rootOrTuberCropPlant",
4519
- "_score": 25.612892
4519
+ "_score": 25.500269
4520
4520
  },
4521
4521
  {
4522
4522
  "@type": "Term",
4523
4523
  "name": "High intensity grazing pasture",
4524
4524
  "@id": "highIntensityGrazingPasture",
4525
- "_score": 25.085224
4525
+ "_score": 25.064548
4526
4526
  },
4527
4527
  {
4528
4528
  "@type": "Term",
4529
4529
  "name": "Permanent cropland",
4530
4530
  "@id": "permanentCropland",
4531
- "_score": 20.495056
4531
+ "_score": 20.20596
4532
4532
  },
4533
4533
  {
4534
4534
  "@type": "Term",
4535
4535
  "name": "Forest",
4536
4536
  "@id": "forest",
4537
- "_score": 19.183342
4537
+ "_score": 19.290152
4538
4538
  },
4539
4539
  {
4540
4540
  "@type": "Term",
4541
- "name": "Other land",
4542
- "@id": "otherLand",
4543
- "_score": 18.45823
4541
+ "name": "Primary forest",
4542
+ "@id": "primaryForest",
4543
+ "_score": 18.45046
4544
4544
  },
4545
4545
  {
4546
4546
  "@type": "Term",
4547
- "name": "Lake",
4548
- "@id": "lake",
4549
- "_score": 18.216282
4547
+ "name": "Other land",
4548
+ "@id": "otherLand",
4549
+ "_score": 18.418287
4550
4550
  },
4551
4551
  {
4552
4552
  "@type": "Term",
4553
- "name": "Primary forest",
4554
- "@id": "primaryForest",
4555
- "_score": 18.14983
4553
+ "name": "Plantation forest",
4554
+ "@id": "plantationForest",
4555
+ "_score": 18.265854
4556
4556
  },
4557
4557
  {
4558
4558
  "@type": "Term",
4559
- "name": "Plantation forest",
4560
- "@id": "plantationForest",
4561
- "_score": 18.021662
4559
+ "name": "Lake",
4560
+ "@id": "lake",
4561
+ "_score": 18.230291
4562
4562
  },
4563
4563
  {
4564
4564
  "@type": "Term",
4565
4565
  "name": "Improved pasture",
4566
4566
  "@id": "improvedPasture",
4567
- "_score": 17.772917
4567
+ "_score": 17.785988
4568
4568
  },
4569
4569
  {
4570
4570
  "@type": "Term",
4571
4571
  "name": "Secondary forest",
4572
4572
  "@id": "secondaryForest",
4573
- "_score": 17.765026
4573
+ "_score": 17.757538
4574
4574
  },
4575
4575
  {
4576
4576
  "@type": "Term",
4577
4577
  "name": "Native pasture",
4578
4578
  "@id": "nativePasture",
4579
- "_score": 17.518377
4579
+ "_score": 17.527752
4580
4580
  },
4581
4581
  {
4582
4582
  "@type": "Term",
4583
4583
  "name": "Nominally managed pasture",
4584
4584
  "@id": "nominallyManagedPasture",
4585
- "_score": 16.49458
4585
+ "_score": 16.500256
4586
+ },
4587
+ {
4588
+ "@type": "Term",
4589
+ "name": "Sea kale plant",
4590
+ "@id": "seaKalePlant",
4591
+ "_score": 16.128777
4586
4592
  },
4587
4593
  {
4588
4594
  "@type": "Term",
4589
4595
  "name": "Red sea plume alga",
4590
4596
  "@id": "redSeaPlumeAlga",
4591
- "_score": 16.421041
4597
+ "_score": 16.10274
4592
4598
  },
4593
4599
  {
4594
4600
  "@type": "Term",
4595
4601
  "name": "Severely degraded pasture",
4596
4602
  "@id": "severelyDegradedPasture",
4597
- "_score": 16.277512
4598
- },
4599
- {
4600
- "@type": "Term",
4601
- "name": "Sea kale plant",
4602
- "@id": "seaKalePlant",
4603
- "_score": 16.218529
4603
+ "_score": 15.984688
4604
4604
  },
4605
4605
  {
4606
4606
  "@type": "Term",
4607
4607
  "name": "Pond",
4608
4608
  "@id": "pond",
4609
- "_score": 13.82317
4609
+ "_score": 13.815231
4610
4610
  },
4611
4611
  {
4612
4612
  "@type": "Term",
4613
4613
  "name": "River tamarind tree",
4614
4614
  "@id": "riverTamarindTree",
4615
- "_score": 12.985474
4615
+ "_score": 12.997887
4616
4616
  },
4617
4617
  {
4618
4618
  "@type": "Term",
4619
4619
  "name": "Cropland",
4620
4620
  "@id": "cropland",
4621
- "_score": 9.878035
4621
+ "_score": 9.890675
4622
4622
  },
4623
4623
  {
4624
4624
  "@type": "Term",
4625
4625
  "name": "Annual cropland",
4626
4626
  "@id": "annualCropland",
4627
- "_score": 9.241321
4627
+ "_score": 8.967179
4628
4628
  }
4629
4629
  ]
4630
4630
  },
@@ -7449,39 +7449,39 @@
7449
7449
  "results": [
7450
7450
  {
7451
7451
  "@type": "Term",
7452
- "@id": "stripTillage"
7452
+ "@id": "ridgeTillage"
7453
7453
  },
7454
7454
  {
7455
7455
  "@type": "Term",
7456
- "@id": "mulchTillage"
7456
+ "@id": "noTillage"
7457
7457
  },
7458
7458
  {
7459
7459
  "@type": "Term",
7460
- "@id": "deepTillage"
7460
+ "@id": "verticalTillage"
7461
7461
  },
7462
7462
  {
7463
7463
  "@type": "Term",
7464
- "@id": "ridgeTillage"
7464
+ "@id": "stripTillage"
7465
7465
  },
7466
7466
  {
7467
7467
  "@type": "Term",
7468
- "@id": "noTillage"
7468
+ "@id": "mulchTillage"
7469
7469
  },
7470
7470
  {
7471
7471
  "@type": "Term",
7472
- "@id": "fullTillage"
7472
+ "@id": "deepTillage"
7473
7473
  },
7474
7474
  {
7475
7475
  "@type": "Term",
7476
- "@id": "minimumTillage"
7476
+ "@id": "fullInversionTillage"
7477
7477
  },
7478
7478
  {
7479
7479
  "@type": "Term",
7480
- "@id": "verticalTillage"
7480
+ "@id": "fullTillage"
7481
7481
  },
7482
7482
  {
7483
7483
  "@type": "Term",
7484
- "@id": "fullInversionTillage"
7484
+ "@id": "minimumTillage"
7485
7485
  }
7486
7486
  ]
7487
7487
  },
@@ -129,7 +129,9 @@ def _should_run(cycle: dict):
129
129
  logRequirements(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
130
130
  is_liveAquaticSpecies=is_liveAquaticSpecies,
131
131
  product_value=product_value,
132
- nitrogen_content=nitrogen_content)
132
+ nitrogen_content=nitrogen_content,
133
+ inputs_n=inputs_n,
134
+ products_n=products_n)
133
135
 
134
136
  else:
135
137
  logRequirements(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
@@ -434,11 +434,11 @@ def convert_to_nitrogen(node: dict, model: str, blank_nodes: list, **log_args):
434
434
  missing_nitrogen_property = [i.get('term', {}).get('@id') for i, value in values if not value]
435
435
 
436
436
  debugValues(node, model=model,
437
- convertion_details=log_as_table([
437
+ conversion_details=log_as_table([
438
438
  {
439
439
  'id': i.get('term', {}).get('@id'),
440
440
  'value': list_sum(i.get('value', [])),
441
- 'conversion-factor': value
441
+ 'nitrogenContent': value
442
442
  }
443
443
  for i, value in values
444
444
  ]),
@@ -22,7 +22,7 @@ def _get_nh3_factor(lookup_name: str, term_id: str, input: dict, **log_args):
22
22
  return safe_parse_float(value, None)
23
23
 
24
24
 
25
- def get_excreta_inputs_with_factor(cycle: dict, lookup_name: str, excreta_convertion_func, **log_args):
25
+ def get_excreta_inputs_with_factor(cycle: dict, lookup_name: str, excreta_conversion_func, **log_args):
26
26
  practices = filter_list_term_type(cycle.get('practices', []), TermTermType.EXCRETAMANAGEMENT)
27
27
  practice_id = practices[0].get('term', {}).get('@id') if len(practices) > 0 else None
28
28
 
@@ -32,7 +32,7 @@ def get_excreta_inputs_with_factor(cycle: dict, lookup_name: str, excreta_conver
32
32
  excreta_values = [
33
33
  (
34
34
  i.get('term', {}).get('@id'),
35
- excreta_convertion_func([i]),
35
+ excreta_conversion_func([i]),
36
36
  _get_nh3_factor(lookup_name, practice_id, i, **log_args)
37
37
  ) for i in excreta_inputs
38
38
  ]
@@ -77,14 +77,16 @@ def get_node_property(
77
77
  Returns
78
78
  -------
79
79
  dict
80
- The property if found, `None` otherwise.
80
+ The property if found, `{}` otherwise.
81
81
  """
82
- prop = find_term_match(node.get('properties', []), property, None)
83
- return find_term_property(node.get('term', {}), property, {}) if all([
84
- find_default_property,
85
- prop is None
86
- ]) else (
87
- prop or ({'term': download_term(property, TermTermType.PROPERTY)} if download_from_hestia else {})
82
+ return (
83
+ (
84
+ find_term_match(node.get('properties', []), property, None)
85
+ ) or (
86
+ find_term_property(node.get('term', {}), property, None) if find_default_property else None
87
+ ) or (
88
+ {'term': download_term(property, TermTermType.PROPERTY)} if download_from_hestia else None
89
+ ) or {}
88
90
  )
89
91
 
90
92
 
@@ -113,9 +115,12 @@ def node_property_lookup_value(model: str, node_term: dict, prop_id: str, defaul
113
115
 
114
116
  def get_node_property_value(model: str, node: dict, prop_id: str, default=None, handle_percents=True, **log_args):
115
117
  prop = get_node_property(node, prop_id, download_from_hestia=True)
116
- term = (prop or {}).get('term')
118
+ term = prop.get('term')
117
119
  units = (term or {}).get('units')
118
- value = prop.get('value') if prop else node_property_lookup_value(model, node.get('term', {}), prop_id, **log_args)
120
+ value = (
121
+ prop['value'] if 'value' in prop else
122
+ node_property_lookup_value(model, node.get('term', {}), prop_id, **log_args)
123
+ )
119
124
  return default if value is None else (value / 100 if units == '%' and handle_percents else value)
120
125
 
121
126
 
@@ -1 +1 @@
1
- VERSION = '0.70.2'
1
+ VERSION = '0.70.3'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hestia-earth-models
3
- Version: 0.70.2
3
+ Version: 0.70.3
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
@@ -11,7 +11,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
11
  Classifier: Programming Language :: Python :: 3.6
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: hestia-earth-schema==31.*
14
+ Requires-Dist: hestia-earth-schema==32.*
15
15
  Requires-Dist: hestia-earth-utils>=0.14.1
16
16
  Requires-Dist: python-dateutil>=2.8.1
17
17
  Requires-Dist: CurrencyConverter==0.16.8
@@ -4,7 +4,7 @@ hestia_earth/models/cache_sites.py,sha256=BOhLkkdVWLJ-4Z7kxfQ8swqrYgZ43sACn1uzxY
4
4
  hestia_earth/models/log.py,sha256=eRuH86v7Thuw-QXdKqaqVmA_MkwnOCo0UBEwtuDq4Oc,3554
5
5
  hestia_earth/models/preload_requests.py,sha256=vK_G1UzhNMhYy7ymnCtHUz_vv3cfApCSKqv29VREEBQ,1943
6
6
  hestia_earth/models/requirements.py,sha256=eU4yT443fx7BnaokhrLB_PCizJI7Y6m4auyo8vQauNg,17363
7
- hestia_earth/models/version.py,sha256=FXrFGVyUGmPydZ629i9Ewt-kg-xGSch4AgpWPfJW1KM,19
7
+ hestia_earth/models/version.py,sha256=jUQOtVONNdxYTZJhNPAQhnoFAofSEOWuStWZoZfrmEc,19
8
8
  hestia_earth/models/agribalyse2016/__init__.py,sha256=WvK0qCQbnYtg9oZxrACd1wGormZyXibPtpCnIQeDqbw,415
9
9
  hestia_earth/models/agribalyse2016/fuelElectricity.py,sha256=1ngl8pdxeNhlVV8keAeWRwGorr_1uFXM9EoPUWx-uSc,4382
10
10
  hestia_earth/models/agribalyse2016/machineryInfrastructureDepreciatedAmountPerCycle.py,sha256=queToXuzq0tQ9_XuUJ2pJgSywXmbt9uX3ZoIKgqkROM,2660
@@ -33,7 +33,7 @@ hestia_earth/models/cml2001Baseline/terrestrialAcidificationPotentialIncludingFa
33
33
  hestia_earth/models/cml2001NonBaseline/__init__.py,sha256=vI8wp8Og_e8DiJqYYvp33YoI3t4ffAC31LWlnV20JTg,419
34
34
  hestia_earth/models/cml2001NonBaseline/eutrophicationPotentialIncludingFateAverageEurope.py,sha256=lcgyRHY08KCBFPERJNqV4DYGEJCvyHBDnJXD0kEkVqM,1097
35
35
  hestia_earth/models/cml2001NonBaseline/terrestrialAcidificationPotentialExcludingFate.py,sha256=xcrxfs9UoV_EWvV-XzMt35oPWCUsTzqg2SGA3j2MFIw,1091
36
- hestia_earth/models/config/Cycle.json,sha256=AfkdbmDl0rZxl_2Wk8nMKx1QHiOSacemVubBhcvPobQ,58758
36
+ hestia_earth/models/config/Cycle.json,sha256=fJmIc9GK16Ob3m3Qv_jqD7Po5vB1C2R6hPJ9yDfEDCM,58937
37
37
  hestia_earth/models/config/ImpactAssessment.json,sha256=R22Pa6Szl05s13xFGKmrVZ4EgKD4UyUrruxxVujsJt4,56201
38
38
  hestia_earth/models/config/Site.json,sha256=vOjDsstMWe4i6PDDfpJ236Qb7gif5I0MMmscK1-LgKM,13866
39
39
  hestia_earth/models/config/__init__.py,sha256=l1WqL7ezlank86ABP4zUia_hIvM9ba-sOE3z6wNrea8,2333
@@ -75,6 +75,7 @@ hestia_earth/models/cycle/post_checks/cache.py,sha256=UNWR3IxZyv7GvBUZOkdj1HqMDa
75
75
  hestia_earth/models/cycle/post_checks/otherSites.py,sha256=lDiMPWduqpeYn5Z59AgcUH4ffiyLe5B6mg3tIe61hEs,694
76
76
  hestia_earth/models/cycle/post_checks/site.py,sha256=Z6lWAG_R5vTL2tiD5EAHwz2j_bvn-51iG1dq60-62ec,551
77
77
  hestia_earth/models/cycle/practice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
+ hestia_earth/models/cycle/practice/landCover.py,sha256=QDXEaY3Rin9wsXEuoHoCeh7q_1fUM8UAWYYbRoeb-x0,5989
78
79
  hestia_earth/models/cycle/practice/value.py,sha256=WtMLlJLX3O6K2V2EMNp0zgKprYD0iIVzCsYxhg6zWJ0,1773
79
80
  hestia_earth/models/cycle/pre_checks/__init__.py,sha256=T8NfEXznq7Q1VUxqBOBP7Rz_DwoYvWYoYqe-Txznu24,352
80
81
  hestia_earth/models/cycle/pre_checks/cache_sources.py,sha256=fbWmlI0q6z9iVF1YNUOwBl0GeEYDgszozl3NkTxx6GI,184
@@ -108,7 +109,7 @@ hestia_earth/models/edip2003/ozoneDepletionPotential.py,sha256=YkBct4eDUidGukaVd
108
109
  hestia_earth/models/emepEea2019/__init__.py,sha256=l90-pWrqIzt1ap1WNk0gF4iZeF5_TSG62hE83bIi4rQ,412
109
110
  hestia_earth/models/emepEea2019/co2ToAirFuelCombustion.py,sha256=ib_xzEbIg-iQwvW2L4BosD9lV6EYOXAiIs8gYhSD9GE,1431
110
111
  hestia_earth/models/emepEea2019/n2OToAirFuelCombustionDirect.py,sha256=H4dgGqDuvYN4S7TRxYsX3hms1xMWr8clR2gkyyO8T18,1438
111
- hestia_earth/models/emepEea2019/nh3ToAirExcreta.py,sha256=t1qdd6B8DOFOpkdan0kW2PVo7dIgWbsWtOXg8XukD08,2153
112
+ hestia_earth/models/emepEea2019/nh3ToAirExcreta.py,sha256=DssSjl_Kug9jE5laqJs9X4xOdOrJBnsXSnk-uA_anyE,2153
112
113
  hestia_earth/models/emepEea2019/nh3ToAirInorganicFertiliser.py,sha256=7G0_S0G6X9slTykxs6CDb68DvtXB7yfq1iSKg0ReXS8,6036
113
114
  hestia_earth/models/emepEea2019/noxToAirFuelCombustion.py,sha256=2--8lI6C6WaYtd9LQe-WZnhvW1eUsjBVAgzT8jclcsc,1431
114
115
  hestia_earth/models/emepEea2019/pm10ToAirAnimalHousing.py,sha256=7LhOEQokWMWEPspYSQO3PtsmWkygbVAonj_Nq6JAL6c,1384
@@ -204,7 +205,7 @@ hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py,sha256
204
205
  hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py,sha256=1StzrYhMsX-hdwBTeLnLMZWl5EEnCoEYpGPRkqy8a-A,1016
205
206
  hestia_earth/models/hestia/liveAnimal.py,sha256=95HfqgFA_qRhdIeR2X5MJ9zzIm4nMHDvJ0BCnuTYe5Q,3860
206
207
  hestia_earth/models/hestia/longFallowRatio.py,sha256=LkJaER1VNDI5351-oC8tru-LgiPK3sNMg0NhB5ic9RE,1690
207
- hestia_earth/models/hestia/management.py,sha256=qkYAlCwuyrfmgoDx0R23MA6ZXzH9Glf__74SxraUbqM,14758
208
+ hestia_earth/models/hestia/management.py,sha256=e1horZLE0th9hazG1sGod_yWs8Hk8FiHFYzJXLNTzFA,10975
208
209
  hestia_earth/models/hestia/materialAndSubstrate.py,sha256=abmM_7FOY5yaNb2yZEm-ncI4wFFcbzaebtnG9XWEA6M,5130
209
210
  hestia_earth/models/hestia/milkYield.py,sha256=__3AdxRTUTWwS_GsqxFpPGklmTnnpADiN0khlRCMAss,5541
210
211
  hestia_earth/models/hestia/netPrimaryProduction.py,sha256=uU4AZ7X6tbtWgR5YClA_aLpYWtlivq9lPQGZgt3-qoQ,1856
@@ -312,7 +313,7 @@ hestia_earth/models/ipcc2019/nh3ToAirInorganicFertiliser.py,sha256=gvfv4VBHmEkpp
312
313
  hestia_earth/models/ipcc2019/nh3ToAirOrganicFertiliser.py,sha256=Oih-34cGl7AZ_sIYWXktOWrzmj3_onvk3EW5f8-7QKI,4152
313
314
  hestia_earth/models/ipcc2019/nitrogenContent.py,sha256=YxlcDF0D9F79rYHTeuhl5kEtmb01UcspFInKi6I_zKM,7209
314
315
  hestia_earth/models/ipcc2019/no3ToGroundwaterCropResidueDecomposition.py,sha256=8NOjbqJuQ-wnLz3bYmwaygSzKBdaF3N7hoELGNnO4YQ,3115
315
- hestia_earth/models/ipcc2019/no3ToGroundwaterExcreta.py,sha256=07Eb9XmziJjYymyXQowESZklbKbqvjP_ookZKi4_GX0,4517
316
+ hestia_earth/models/ipcc2019/no3ToGroundwaterExcreta.py,sha256=kf8KzTALAQ_pRVNEfpAG-aM94UgP6Q9T47UrXfOp_go,4517
316
317
  hestia_earth/models/ipcc2019/no3ToGroundwaterInorganicFertiliser.py,sha256=eyPfyIi8EqigOTsEA0BSyoUePyy_AjMlQNJ6Z8yyJ_Q,3413
317
318
  hestia_earth/models/ipcc2019/no3ToGroundwaterOrganicFertiliser.py,sha256=px2SN-uaus2cftXzlsYCUAxLuon6BnDXmaFI9xhQrgU,3347
318
319
  hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py,sha256=vvq-GAzFtPw9BTKs7RnwRJwzZJDmU3vPVAzIC7WxrhM,34600
@@ -320,7 +321,7 @@ hestia_earth/models/ipcc2019/noxToAirInorganicFertiliser.py,sha256=fmmFgjtvOD2Tr
320
321
  hestia_earth/models/ipcc2019/noxToAirOrganicFertiliser.py,sha256=9dx_MRTwJGxJRq6mj2EJQMdQ2w6j7lw0fQk0If_cIGc,4152
321
322
  hestia_earth/models/ipcc2019/organicCarbonPerHa.py,sha256=D8Lph5clGjXb5F7sk-jlnqE30C2lokhqndpA0hUMwTk,7791
322
323
  hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py,sha256=8g1kJbxCnXAOFUdbB9zzMsuDOzMgvVy7A5MwtJvGUaY,78547
323
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py,sha256=UVf85mcq-cNqkNEldg7h6RY5qa0RAtlXVKeb-GaFmAA,68913
324
+ hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py,sha256=5_AltohTyRMBT8dFdULOdTS79Ydpbb2CaYZGlYQEFQY,69244
324
325
  hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py,sha256=s_F3fyHhPuqragrHxluqdK0GCGnEor17jGlGKue0UsA,9867
325
326
  hestia_earth/models/ipcc2019/organicSoilCultivation_utils.py,sha256=hRMzbGqscOcIO1MvD_31mbgxhVcPsvHtjJRcOCkEOhI,5405
326
327
  hestia_earth/models/ipcc2019/pastureGrass.py,sha256=_EwlAooSfrkcSy4rl_rk4PpeX1pcIiQcb7HE2lQkyn8,9847
@@ -443,12 +444,12 @@ hestia_earth/models/linkedImpactAssessment/utils.py,sha256=S1zlux02gU2Lajrtoq-zQ
443
444
  hestia_earth/models/mocking/__init__.py,sha256=9VX50c-grz-snfd-7MBS0KfF7AadtbKuj7kK6PqtsgE,687
444
445
  hestia_earth/models/mocking/build_mock_search.py,sha256=p15ccEUmkmLp1RiGNznxMz3OFHbI8P1-29ExuohiQN8,1355
445
446
  hestia_earth/models/mocking/mock_search.py,sha256=ccFe_WrI73JElFmxp4hPNLCX7eeU--lBC1JFR901KJY,1069
446
- hestia_earth/models/mocking/search-results.json,sha256=lDhLUw6th-m6HxfUcTO3kDsCECtQ4qWK2OcwgGrXPek,162881
447
+ hestia_earth/models/mocking/search-results.json,sha256=ENYYYNBFWQ0jSSQpY_cf-ychVMeM6UOT2SQZBVtkF8k,162883
447
448
  hestia_earth/models/pooreNemecek2018/__init__.py,sha256=nPboL7ULJzL5nJD5q7q9VOZt_fxbKVm8fmn1Az5YkVY,417
448
449
  hestia_earth/models/pooreNemecek2018/aboveGroundCropResidueTotal.py,sha256=Qt-mel4dkhK6N5uUOutNOinCTFjbjtGzITaaI0LvYc4,2396
449
450
  hestia_earth/models/pooreNemecek2018/belowGroundCropResidue.py,sha256=JT0RybbvWVlo01FO8K0Yj41HrEaJT3Kj1xfayr2X-xw,2315
450
451
  hestia_earth/models/pooreNemecek2018/ch4ToAirAquacultureSystems.py,sha256=k_dB5iwOg6swQWb4fvfMCZ1dm1PnRff8Rpm1aclKOqA,6517
451
- hestia_earth/models/pooreNemecek2018/excretaKgN.py,sha256=RstXknuNCB-BeCOIV0LHf3QRwOG2gQlxLzaGXWKG4hc,5858
452
+ hestia_earth/models/pooreNemecek2018/excretaKgN.py,sha256=EKVQK_wfDGRvj3lsSYp4xCjVEobOVt04fNhiZZXXfDk,5956
452
453
  hestia_earth/models/pooreNemecek2018/excretaKgVs.py,sha256=eIiiZPWjLya0ZOqiYXFKH10K693cAKFygP2p-WPcLyg,9278
453
454
  hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py,sha256=QWWS9P_q_mPruvCYm4PJ0PNcYJJ8QS3WEV7HN-6MneY,3920
454
455
  hestia_earth/models/pooreNemecek2018/landOccupationDuringCycle.py,sha256=gSUzPuzzLwQsBiX_Tgx6mWJ4pEB5qhlKoOtaEdmDGQ4,3431
@@ -590,7 +591,7 @@ hestia_earth/models/utils/animalProduct.py,sha256=M5IunAKGY6oZv3j1Ascl34ywyeLWAp
590
591
  hestia_earth/models/utils/aquacultureManagement.py,sha256=dxrbC1Xf140cohxTbSw6TxLAnAASWTdNZwBBam4yQnw,171
591
592
  hestia_earth/models/utils/array_builders.py,sha256=ko1pDZKaUudZqxOZ99vJamKAdoR6ND4ZmxVrYH6YjPc,19498
592
593
  hestia_earth/models/utils/background_emissions.py,sha256=R0tCA63q1_2DaZ87oI7FFjZsxAZ4Zds3Rr4fDf9KhkM,1850
593
- hestia_earth/models/utils/blank_node.py,sha256=AveekcsdZz7UNgLPQXrcFq30CjKA7H-WyWB3GbgwffQ,55963
594
+ hestia_earth/models/utils/blank_node.py,sha256=KZizahEIqZafxJ_OXL0za7QILc4AledEnHDQoxyaNI8,55961
594
595
  hestia_earth/models/utils/cache_sources.py,sha256=MBkrPpjwNiC4ApDjeYVHZjWBbpvAerXRDrMHpjasAZ0,377
595
596
  hestia_earth/models/utils/completeness.py,sha256=iRG4uviOAQQ4T2Nr4LlelPVTS_F1felGZNJYxek_JG8,1239
596
597
  hestia_earth/models/utils/constant.py,sha256=DmB3VVuoh7Pz2QDBJqiUG6yAML2i0fOy1BPuPHmhT1w,3442
@@ -602,7 +603,7 @@ hestia_earth/models/utils/cycle.py,sha256=Lx085Eonp2W7EOi9BSlLWqtwY0ocZ5F1KY9dDG
602
603
  hestia_earth/models/utils/descriptive_stats.py,sha256=EMVwFvg2OnZgKRAfireAoWY2EbrSvqR0V0bK9B53p28,1583
603
604
  hestia_earth/models/utils/ecoClimateZone.py,sha256=etsWsAQeYHCnDJJi-ezTrzjoaFILC1e3SMfSNsdRnPs,4241
604
605
  hestia_earth/models/utils/emission.py,sha256=vzQQ4eKiC8KlmwFqT00lSV1V2dmTGMSzddOYNgFyka8,3636
605
- hestia_earth/models/utils/excretaManagement.py,sha256=U8OeSILHMfCGR5x7Pw8R2tpzCv3C_AfSAX8As8WDVlM,2257
606
+ hestia_earth/models/utils/excretaManagement.py,sha256=cez_Rm69n8CzXuoil0fhi8XSOIEh2yfJzYFzhf9T5EM,2257
606
607
  hestia_earth/models/utils/feedipedia.py,sha256=mfGd3EaTQGh9aZaF9pxVJRH_vLEIqktwbwTKQWHv7hs,3967
607
608
  hestia_earth/models/utils/fertiliser.py,sha256=DBO4OBNgnQJ0fCQMDkIk_ZGZX-uKGaTFZCEXfAnJciY,690
608
609
  hestia_earth/models/utils/fuel.py,sha256=XzOELV3dn506PkMKjFQ_ZKVZInd2lL2x6PKdsa6Po4M,1429
@@ -621,7 +622,7 @@ hestia_earth/models/utils/pesticideAI.py,sha256=_mlhKnA1TxF-x39CPNnOGXk6754SoSQq
621
622
  hestia_earth/models/utils/practice.py,sha256=GEu2G2yMPbcIHldOzgv5OFp8bQ1Jt9OFgj0c_0F_kUc,372
622
623
  hestia_earth/models/utils/product.py,sha256=Oha4lMvediC1Lc5DksA6sAUT94Q1Cs9F4LFVe_uaqP4,11177
623
624
  hestia_earth/models/utils/productivity.py,sha256=rTJX_nemxHpOcPN7jiM2hFHknoLUIW8y-hFxVxIkg70,593
624
- hestia_earth/models/utils/property.py,sha256=3jeA__YBHZvIOqcfDmbV1IOLfqtU1pA74aVrEVcHsNE,5340
625
+ hestia_earth/models/utils/property.py,sha256=oz3x-sJkNmORlDwb4o1q5I-azj0hteriUSZBP7S5idc,5390
625
626
  hestia_earth/models/utils/site.py,sha256=ZYCxaBXZ3Zh4judbzOM_E5SNROiMH-S2LEkkklN5HK4,4041
626
627
  hestia_earth/models/utils/source.py,sha256=D_QlW7Ul_NV1iOucMNE3szT64b1RdSdecIEm6OukYhw,2459
627
628
  hestia_earth/models/utils/stats.py,sha256=-0vvhSDAhp4ZYXD1l6sO2hdok8_HgUM6OjCSYGSTHqU,15291
@@ -719,6 +720,7 @@ tests/models/cycle/post_checks/test_cache.py,sha256=5QD8Yk9HbDePHSIXOJUM_ptZCroO
719
720
  tests/models/cycle/post_checks/test_otherSites.py,sha256=SHCA82MvWy-CsuquvLgmiwAhIKJQONIc07z51QH5RpQ,359
720
721
  tests/models/cycle/post_checks/test_site.py,sha256=In0Q0Tw3w_hV8_uAnOcL_iS2FoI_75lsq7MdoWLa5js,621
721
722
  tests/models/cycle/practice/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
723
+ tests/models/cycle/practice/test_landCover.py,sha256=3Fi-p0-ArgTbrBPnm02vikpFrInIFQuXx7VVpPtjmVI,955
722
724
  tests/models/cycle/practice/test_value.py,sha256=sYPoTkllrEt2oB92uA2q37FFtOjSX49749Nv1pUvqdw,1315
723
725
  tests/models/cycle/pre_checks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
724
726
  tests/models/cycle/pre_checks/test_otherSites.py,sha256=IEWvG2hwmladHctZUy6jTg01ZnCvWJUtPgD4GHKcumQ,502
@@ -914,7 +916,7 @@ tests/models/ipcc2019/test_belowGroundCropResidue.py,sha256=no71pfxgOhn_tEWc_Ewu
914
916
  tests/models/ipcc2019/test_biomass_utils.py,sha256=I2q4pDGAD0aY_kpZCMPJoC-KbRYxdzY1rhr4xtJFWIA,3592
915
917
  tests/models/ipcc2019/test_carbonContent.py,sha256=_GWF5nGy-PxiqBZ5V7W_sHMz75YRzmxr79R-sZZg7yk,4146
916
918
  tests/models/ipcc2019/test_ch4ToAirAquacultureSystems.py,sha256=o7bHOS4JkwexRrDhLzpfr8nyYCctgRL32YZbam5RBrI,1891
917
- tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py,sha256=7v0a5CcdpHixRbe4jhhIH2t4hlNsZInlEoHuipUBseg,8571
919
+ tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py,sha256=nmmxxJFX_VFOgvNxmj4q825vVEtEq-B61DVNo3inirs,8567
918
920
  tests/models/ipcc2019/test_ch4ToAirExcreta.py,sha256=e58NXmBW2SNVLUqQO9A66Xq6jiGTyhdFZDZk51JApF8,2902
919
921
  tests/models/ipcc2019/test_ch4ToAirFloodedRice.py,sha256=YRyxNaGPAgsCJBRXhwhEsZ6r44dawHMSN-Qmi-yS0xI,1025
920
922
  tests/models/ipcc2019/test_ch4ToAirOrganicSoilCultivation.py,sha256=HJNE-M38eXCvjTDfOj70XlevSQgXut8w5EDzj1HKeyY,1703
@@ -1241,8 +1243,8 @@ tests/orchestrator/strategies/run/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeR
1241
1243
  tests/orchestrator/strategies/run/test_add_blank_node_if_missing.py,sha256=K4xg4UAXfNhSaLyknKVPO7MGBF44Z_gD7CuZ_pe28gU,3512
1242
1244
  tests/orchestrator/strategies/run/test_add_key_if_missing.py,sha256=hKwvk1ohcBVnQUCTiDhRW99J0xEa29BpwFi1KC0yWLE,329
1243
1245
  tests/orchestrator/strategies/run/test_always.py,sha256=w5-Dhp6yLzgZGAeMRz3OrqZbbAed9gZ1O266a3z9k7w,134
1244
- hestia_earth_models-0.70.2.dist-info/LICENSE,sha256=TD25LoiRJsA5CPUNrcyt1PXlGcbUGFMAeZoBcfCrCNE,1154
1245
- hestia_earth_models-0.70.2.dist-info/METADATA,sha256=vzarmK_NB5tg_ymkLsxwangcpt6RyzbBcGrm81A39BQ,4045
1246
- hestia_earth_models-0.70.2.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
1247
- hestia_earth_models-0.70.2.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1248
- hestia_earth_models-0.70.2.dist-info/RECORD,,
1246
+ hestia_earth_models-0.70.3.dist-info/LICENSE,sha256=TD25LoiRJsA5CPUNrcyt1PXlGcbUGFMAeZoBcfCrCNE,1154
1247
+ hestia_earth_models-0.70.3.dist-info/METADATA,sha256=9u8GduYX4WwwaaEc7Tdis5CggZOQB2YImDLZQSYU2gk,4045
1248
+ hestia_earth_models-0.70.3.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
1249
+ hestia_earth_models-0.70.3.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1250
+ hestia_earth_models-0.70.3.dist-info/RECORD,,
@@ -0,0 +1,27 @@
1
+ import os
2
+ import json
3
+ import pytest
4
+ from unittest.mock import Mock, patch
5
+
6
+ from tests.utils import fixtures_path, fake_new_practice
7
+ from hestia_earth.models.cycle.practice.landCover import MODEL, MODEL_KEY, run
8
+
9
+ class_path = f"hestia_earth.models.{MODEL}.practice.{MODEL_KEY}"
10
+ fixtures_folder = os.path.join(fixtures_path, MODEL, 'practice', MODEL_KEY)
11
+
12
+ _folders = [d for d in os.listdir(fixtures_folder) if os.path.isdir(os.path.join(fixtures_folder, d))]
13
+
14
+
15
+ @pytest.mark.parametrize('folder', _folders)
16
+ @patch(f"{class_path}._new_practice", side_effect=fake_new_practice)
17
+ def test_run(mock_new_practice: Mock, folder: str):
18
+ fixture_path = os.path.join(fixtures_folder, folder)
19
+
20
+ with open(f"{fixture_path}/cycle.jsonld", encoding='utf-8') as f:
21
+ cycle = json.load(f)
22
+
23
+ with open(f"{fixture_path}/result.jsonld", encoding='utf-8') as f:
24
+ expected = json.load(f)
25
+
26
+ result = run(cycle)
27
+ assert result == expected, fixture_path
@@ -55,7 +55,7 @@ def test_should_run(mock_feed, mock_lookup_value, *args):
55
55
  @patch(f"hestia_earth.models.{MODEL}.utils.get_milkYield_terms", return_value=[])
56
56
  @patch("hestia_earth.models.utils.property.download_term", side_effect=fake_download_term)
57
57
  # patch get_node_property to read value from lookups only
58
- @patch('hestia_earth.models.utils.property.get_node_property', return_value=None)
58
+ @patch('hestia_earth.models.utils.property.get_node_property', return_value={})
59
59
  @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
60
60
  def test_run(*args):
61
61
  with open(f"{fixtures_folder}/cycle.jsonld", encoding="utf-8") as f:
@@ -72,7 +72,7 @@ def test_run(*args):
72
72
  @patch(f"hestia_earth.models.{MODEL}.utils.get_milkYield_terms", return_value=[])
73
73
  @patch("hestia_earth.models.utils.property.download_term", side_effect=fake_download_term)
74
74
  # patch get_node_property to read value from lookups only
75
- @patch('hestia_earth.models.utils.property.get_node_property', return_value=None)
75
+ @patch('hestia_earth.models.utils.property.get_node_property', return_value={})
76
76
  @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
77
77
  def test_run_dairy(*args):
78
78
  with open(f"{fixtures_folder}/dairy-buffalo-cows/cycle.jsonld", encoding="utf-8") as f: