hestia-earth-models 0.62.3__py3-none-any.whl → 0.62.4__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.

@@ -77,7 +77,7 @@ def _run_liveAnimal(cycle: dict, product: dict, year: int, country_id: str):
77
77
  product_id = product.get('term', {}).get('@id')
78
78
  animal_product_id = get_liveAnimal_to_animalProduct_id(product_id, LOOKUPS['liveAnimal'][0], term=TERM_ID)
79
79
 
80
- animal_product_term = download_hestia(animal_product_id)
80
+ animal_product_term = download_hestia(animal_product_id) if animal_product_id else {}
81
81
  kg_liveweight, groupingFAO = _product_value({**product, 'term': animal_product_term}, year, country_id)
82
82
 
83
83
  logRequirements(cycle, model=MODEL, term=product_id, property=TERM_ID,
@@ -63,7 +63,7 @@ def logShouldRun(log_node: dict, model: str, term: Union[str, None], should_run:
63
63
 
64
64
 
65
65
  def debugMissingLookup(lookup_name: str, row: str, row_value: str, col: str, value, **kwargs):
66
- if value is None:
66
+ if value is None or value == '':
67
67
  extra = (', ' + _join_args(**kwargs)) if len(kwargs.keys()) > 0 else ''
68
68
  logger.warn('Missing lookup=%s, %s=%s, column=%s' + extra, lookup_name, row, row_value, col)
69
69
 
@@ -1636,6 +1636,150 @@
1636
1636
  }
1637
1637
  ]
1638
1638
  },
1639
+ {
1640
+ "name": "get_land_cover_siteTypes",
1641
+ "query": {
1642
+ "bool": {
1643
+ "must": [
1644
+ {
1645
+ "match": {
1646
+ "@type": "Term"
1647
+ }
1648
+ },
1649
+ {
1650
+ "match": {
1651
+ "termType": "landCover"
1652
+ }
1653
+ }
1654
+ ],
1655
+ "should": [
1656
+ {
1657
+ "match": {
1658
+ "name": "agri-food processor"
1659
+ }
1660
+ },
1661
+ {
1662
+ "match": {
1663
+ "name": "animal housing"
1664
+ }
1665
+ },
1666
+ {
1667
+ "match": {
1668
+ "name": "cropland"
1669
+ }
1670
+ },
1671
+ {
1672
+ "match": {
1673
+ "name": "food retailer"
1674
+ }
1675
+ },
1676
+ {
1677
+ "match": {
1678
+ "name": "forest"
1679
+ }
1680
+ },
1681
+ {
1682
+ "match": {
1683
+ "name": "glass or high accessible cover"
1684
+ }
1685
+ },
1686
+ {
1687
+ "match": {
1688
+ "name": "lake"
1689
+ }
1690
+ },
1691
+ {
1692
+ "match": {
1693
+ "name": "other natural vegetation"
1694
+ }
1695
+ },
1696
+ {
1697
+ "match": {
1698
+ "name": "permanent pasture"
1699
+ }
1700
+ },
1701
+ {
1702
+ "match": {
1703
+ "name": "pond"
1704
+ }
1705
+ },
1706
+ {
1707
+ "match": {
1708
+ "name": "river or stream"
1709
+ }
1710
+ },
1711
+ {
1712
+ "match": {
1713
+ "name": "sea or ocean"
1714
+ }
1715
+ }
1716
+ ],
1717
+ "minimum_should_match": 1
1718
+ }
1719
+ },
1720
+ "results": [
1721
+ {
1722
+ "@type": "Term",
1723
+ "name": "Glass or high accessible cover",
1724
+ "@id": "glassOrHighAccessibleCover",
1725
+ "_score": 60.694187
1726
+ },
1727
+ {
1728
+ "@type": "Term",
1729
+ "name": "River or stream",
1730
+ "@id": "riverOrStream",
1731
+ "_score": 50.06671
1732
+ },
1733
+ {
1734
+ "@type": "Term",
1735
+ "name": "Other natural vegetation",
1736
+ "@id": "otherNaturalVegetation",
1737
+ "_score": 40.722
1738
+ },
1739
+ {
1740
+ "@type": "Term",
1741
+ "name": "Natural forest",
1742
+ "@id": "naturalForest",
1743
+ "_score": 31.252472
1744
+ },
1745
+ {
1746
+ "@type": "Term",
1747
+ "name": "Permanent pasture",
1748
+ "@id": "permanentPasture",
1749
+ "_score": 27.857792
1750
+ },
1751
+ {
1752
+ "@type": "Term",
1753
+ "name": "Animal housing",
1754
+ "@id": "animalHousing",
1755
+ "_score": 26.769783
1756
+ },
1757
+ {
1758
+ "@type": "Term",
1759
+ "name": "Root or tuber crop plant",
1760
+ "@id": "rootOrTuberCropPlant",
1761
+ "_score": 24.781918
1762
+ },
1763
+ {
1764
+ "@type": "Term",
1765
+ "name": "High intensity grazing pasture",
1766
+ "@id": "highIntensityGrazingPasture",
1767
+ "_score": 23.502655
1768
+ },
1769
+ {
1770
+ "@type": "Term",
1771
+ "name": "Permanent cropland",
1772
+ "@id": "permanentCropland",
1773
+ "_score": 20.467493
1774
+ },
1775
+ {
1776
+ "@type": "Term",
1777
+ "name": "Forest",
1778
+ "@id": "forest",
1779
+ "_score": 19.942879
1780
+ }
1781
+ ]
1782
+ },
1639
1783
  {
1640
1784
  "name": "get_liquid_fuel_terms",
1641
1785
  "query": {
@@ -15,16 +15,17 @@ condensed into a single node to aid readability.
15
15
  """
16
16
  from functools import reduce
17
17
 
18
- from hestia_earth.schema import SchemaType, TermTermType
18
+ from hestia_earth.schema import SchemaType, TermTermType, SiteSiteType
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, flatten
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 = {
@@ -119,6 +120,9 @@ INPUT_RULES = {
119
120
  )
120
121
  )
121
122
  }
123
+ _SKIP_LAND_COVER_SITE_TYPES = [
124
+ SiteSiteType.CROPLAND.value
125
+ ]
122
126
 
123
127
 
124
128
  def management(data: dict):
@@ -130,14 +134,15 @@ def _extract_node_value(node: dict) -> dict:
130
134
  return node | {'value': get_node_value(node)}
131
135
 
132
136
 
133
- def _include(value: dict, keys: list): return {k: v for k, v in value.items() if k in keys}
137
+ def _include(value: dict, keys: list) -> dict: return {k: v for k, v in value.items() if k in keys}
134
138
 
135
139
 
136
140
  def _default_dates(cycle: dict, values: list):
137
141
  return [(_include(cycle, ["startDate", "endDate"]) | v) for v in values]
138
142
 
139
143
 
140
- def _overwrite_dates(cycle: dict, values: list) -> list:
144
+ def _dates_from_current_cycle(cycle: dict, values: list) -> list:
145
+ """Always uses the dates from the cycle."""
141
146
  return [v | _include(cycle, ["startDate", "endDate"]) for v in values]
142
147
 
143
148
 
@@ -149,22 +154,21 @@ def _copy_item_if_exists(source: dict, keys: list[str] = None, dest: dict = None
149
154
 
150
155
  def _get_landCover_term_id(product: dict) -> str:
151
156
  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
157
  return value.split(';')[0] if value else None
154
158
 
155
159
 
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
- )
160
+ def _get_relevant_items(
161
+ cycles: list[dict], item_name: str, relevant_terms: list, date_fill: callable = _default_dates
162
+ ) -> list:
163
+ """
164
+ Get items from the list of cycles with any of the relevant terms.
165
+ Also adds dates if missing.
166
+ """
167
+ return [
168
+ item
169
+ for cycle in cycles
170
+ for item in date_fill(cycle=cycle, values=filter_list_term_type(cycle.get(item_name, []), relevant_terms))
171
+ ]
168
172
 
169
173
 
170
174
  def _get_lookup_with_debug(term: dict, column: str) -> any:
@@ -211,28 +215,25 @@ def _get_relevant_inputs(cycles: list[dict]) -> list:
211
215
  return relevant_inputs
212
216
 
213
217
 
214
- def _should_run(site: dict):
215
- # Only get related cycles once.
216
- cycles = related_cycles(site)
217
-
218
+ def _should_run_all_products(cycles: list, site_type: str):
218
219
  products_land_cover = [
219
220
  _extract_node_value(
220
221
  _include(
221
222
  value=product,
222
223
  keys=["term", "value", "startDate", "endDate", "properties"]
223
224
  )
224
- ) for product in _get_items_with_relevant_term_type(
225
+ ) for product in _get_relevant_items(
225
226
  cycles=cycles,
226
227
  item_name="products",
227
- relevant_values=[TermTermType.LANDCOVER]
228
+ relevant_terms=[TermTermType.LANDCOVER]
228
229
  )
229
- ]
230
+ ] if site_type else []
230
231
 
231
- products_crop_forage = _get_items_with_relevant_term_type(
232
+ products_crop_forage = _get_relevant_items(
232
233
  cycles=cycles,
233
234
  item_name="products",
234
- relevant_values=[TermTermType.CROP, TermTermType.FORAGE],
235
- date_fill=_overwrite_dates
235
+ relevant_terms=[TermTermType.CROP, TermTermType.FORAGE],
236
+ date_fill=_dates_from_current_cycle
236
237
  )
237
238
  products_crop_forage = [
238
239
  _copy_item_if_exists(
@@ -243,9 +244,33 @@ def _should_run(site: dict):
243
244
  "value": 100
244
245
  }
245
246
  )
246
- for product in list(filter(_get_landCover_term_id, products_crop_forage))
247
- ]
248
- all_products = products_land_cover + products_crop_forage
247
+ for product in list(filter(_get_landCover_term_id, [i for i in products_crop_forage]))
248
+ ] if site_type else []
249
+ dates = sorted(list(set(
250
+ flatten([[cycle.get('startDate'), cycle.get('endDate')] for cycle in cycles])
251
+ ))) if site_type not in _SKIP_LAND_COVER_SITE_TYPES else []
252
+ site_type_term = download_hestia(get_landCover_term_id_from_site_type(site_type)) if all([
253
+ len(dates) >= 2,
254
+ site_type
255
+ ]) else None
256
+ products_site_type = [{
257
+ "term": linked_node(site_type_term),
258
+ "value": 100,
259
+ "startDate": dates[0],
260
+ "endDate": dates[-1]
261
+ }] if site_type_term else []
262
+
263
+ return products_site_type, 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(
270
+ cycles=cycles,
271
+ site_type=site.get("siteType", "")
272
+ )
273
+ all_products = products_land_cover + products_crop_forage + products_animal
249
274
  all_products = condense_nodes(all_products)
250
275
 
251
276
  practices = [
@@ -254,10 +279,10 @@ def _should_run(site: dict):
254
279
  value=practice,
255
280
  keys=["term", "value", "startDate", "endDate"]
256
281
  )
257
- ) for practice in _get_items_with_relevant_term_type(
282
+ ) for practice in _get_relevant_items(
258
283
  cycles=cycles,
259
284
  item_name="practices",
260
- relevant_values=[
285
+ relevant_terms=[
261
286
  TermTermType.WATERREGIME,
262
287
  TermTermType.TILLAGE,
263
288
  TermTermType.CROPRESIDUEMANAGEMENT,
@@ -275,6 +300,7 @@ def _should_run(site: dict):
275
300
  model_key=MODEL_KEY,
276
301
  products_crop_forage_ids=log_blank_nodes_id(products_crop_forage),
277
302
  products_land_cover_ids=log_blank_nodes_id(products_land_cover),
303
+ products_animal=log_blank_nodes_id(products_animal),
278
304
  practice_ids=log_blank_nodes_id(practices),
279
305
  inputs=log_blank_nodes_id(relevant_inputs)
280
306
  )
@@ -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
 
@@ -626,3 +626,23 @@ def get_electricity_grid_mix_terms():
626
626
  }
627
627
  }, limit=LIMIT, fields=['@type', '@id', 'name', 'termType', 'units'])
628
628
  return list(map(lambda n: n["@id"], terms))
629
+
630
+
631
+ def get_land_cover_siteTypes():
632
+ """
633
+ Find all `Land Cover` terms with siteTypes
634
+
635
+ Returns
636
+ -------
637
+ List of landCover terms with associated siteTypes.
638
+ """
639
+ return search({
640
+ "bool": {
641
+ "must": [
642
+ {"match": {"@type": "Term"}},
643
+ {"match": {"termType": "landCover"}}
644
+ ],
645
+ "should": [{"match": {"name": siteType.value}} for siteType in SiteSiteType],
646
+ "minimum_should_match": 1
647
+ },
648
+ })
@@ -1 +1 @@
1
- VERSION = '0.62.3'
1
+ VERSION = '0.62.4'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hestia-earth-models
3
- Version: 0.62.3
3
+ Version: 0.62.4
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
@@ -1,10 +1,10 @@
1
1
  hestia_earth/__init__.py,sha256=G-d438vPx7m_ks5e9XTtM3u7LDRO5dSSukibukWmyPM,56
2
2
  hestia_earth/models/__init__.py,sha256=qEFeq3yuf3lQKVseALmL8aPM8fpCS54B_5pry00M3hk,76
3
3
  hestia_earth/models/cache_sites.py,sha256=KQp9cUKE-aIcYJoMWEtKFYS8gBFfsx5LKQhqoWpUSoM,6065
4
- hestia_earth/models/log.py,sha256=b63I3qyTtQs17xxbq8RI0Fv2lvZ1oDZ9k0njhxqiFFk,3459
4
+ hestia_earth/models/log.py,sha256=DbfNcGzaC5hzkuMDxQqW6XYoNBI4Uxw4SIoOYoZA6og,3474
5
5
  hestia_earth/models/preload_requests.py,sha256=y_okcYzSbqODvmzkw-wOK2cOZEzkJq3pmRfxRsPsUw0,1012
6
6
  hestia_earth/models/requirements.py,sha256=eU4yT443fx7BnaokhrLB_PCizJI7Y6m4auyo8vQauNg,17363
7
- hestia_earth/models/version.py,sha256=7aQk_ZZAw1avQvecDCGEiWz0z9mUZWdHHPPAzm2Hgf0,19
7
+ hestia_earth/models/version.py,sha256=VvAcSTPsHvm2Agla-EjyZ04Gq8k08dRvMyQy3jw2KbM,19
8
8
  hestia_earth/models/agribalyse2016/__init__.py,sha256=WvK0qCQbnYtg9oZxrACd1wGormZyXibPtpCnIQeDqbw,415
9
9
  hestia_earth/models/agribalyse2016/fuelElectricity.py,sha256=tnGxBmJdPfPFfehLUQcefEqy1lHvzsSpx_s7O8nf3Zs,4412
10
10
  hestia_earth/models/agribalyse2016/machineryInfrastructureDepreciatedAmountPerCycle.py,sha256=_Rbngu0DzHKa62JwBl58ZC_ui1zLF2que_nB7ukhOQc,3392
@@ -131,7 +131,7 @@ hestia_earth/models/faostat2018/coldCarcassWeightPerHead.py,sha256=y1ouj5FBrnGWx
131
131
  hestia_earth/models/faostat2018/coldDressedCarcassWeightPerHead.py,sha256=Aphq7r06Q5-RDer4i1CneOLifVQCKTiVPTIWE3AxLfE,3230
132
132
  hestia_earth/models/faostat2018/landTransformationFromCropland100YearAverage.py,sha256=2qVeSGMoJ15pD6-p0Fsq1yN-3mpL8SyOKkVuIiYoJMg,2655
133
133
  hestia_earth/models/faostat2018/landTransformationFromCropland20YearAverage.py,sha256=0vJHRIb4F2G_8MG9Qgz2n-7dYerG5q6r7pG-j84LKjk,2648
134
- hestia_earth/models/faostat2018/liveweightPerHead.py,sha256=3h8zveCVQ21ms2qtsQyAYeet-98TMkipL6QLEnyUcTU,5111
134
+ hestia_earth/models/faostat2018/liveweightPerHead.py,sha256=flI3_TyG-7xoWp6cU6pZAFiXyHyFkfRz7Lmb7cQAffI,5140
135
135
  hestia_earth/models/faostat2018/readyToCookWeightPerHead.py,sha256=b1_GZQ3oFl88w6TY5DqLSqXNaYX6TcRBK4R9M2cWSjM,3165
136
136
  hestia_earth/models/faostat2018/seed.py,sha256=ts9PKs9UnZnJ9nPFlL7etL1Qb9uIWIES8Mz8W7FWbOw,2917
137
137
  hestia_earth/models/faostat2018/utils.py,sha256=r69UWDdMOLTYkI8_oQeEnUCOAZCnmwj_NwyrypAOb_A,3734
@@ -367,7 +367,7 @@ hestia_earth/models/linkedImpactAssessment/landTransformationFromPermanentPastur
367
367
  hestia_earth/models/linkedImpactAssessment/utils.py,sha256=dGwGc2d-8_WQElTpfyPmz5vQtL-LHQRmiZnCTuPXMDs,1876
368
368
  hestia_earth/models/mocking/__init__.py,sha256=n3Fkkrvh8zHNWiJZmnfQ7WZ91JRzAO9P6pSG1JpwtXo,687
369
369
  hestia_earth/models/mocking/mock_search.py,sha256=dBCDRfbZmbMLKP21u_VYkxyimomqs-zztjX-_ZNKuuM,2036
370
- hestia_earth/models/mocking/search-results.json,sha256=E-YgXbJEDOtPpC7VCv0bf1ckfQbZwkoLT-SzG_TcIh4,43349
370
+ hestia_earth/models/mocking/search-results.json,sha256=_2VGybtuYwXO05Oj4wCr0t8HbJ7a0KZqDJnmqoITAVM,46411
371
371
  hestia_earth/models/pooreNemecek2018/__init__.py,sha256=nPboL7ULJzL5nJD5q7q9VOZt_fxbKVm8fmn1Az5YkVY,417
372
372
  hestia_earth/models/pooreNemecek2018/aboveGroundCropResidueTotal.py,sha256=Qt-mel4dkhK6N5uUOutNOinCTFjbjtGzITaaI0LvYc4,2396
373
373
  hestia_earth/models/pooreNemecek2018/belowGroundCropResidue.py,sha256=JT0RybbvWVlo01FO8K0Yj41HrEaJT3Kj1xfayr2X-xw,2315
@@ -466,7 +466,7 @@ hestia_earth/models/site/brackishWater.py,sha256=vLEhIZv5PUKwzwvIuYrWi7K---fq7ZX
466
466
  hestia_earth/models/site/cationExchangeCapacityPerKgSoil.py,sha256=0eH4A-tXJ0hvIkiYXWxlx8TfrdbIKUGYUDk97-yQJgg,3653
467
467
  hestia_earth/models/site/flowingWater.py,sha256=v3g5722GIA4zQAUQI9yGFiZvFvI1QAVZqlQrY-6_B3A,1731
468
468
  hestia_earth/models/site/freshWater.py,sha256=FXs3Vt8V4e-wn325_dwSTOKlZtn5ksNUpvYGDeLJShY,1255
469
- hestia_earth/models/site/management.py,sha256=iljb0YjZqQcilXNlYIffjfEqszvMaLRKJlgv0TKIe-M,9627
469
+ hestia_earth/models/site/management.py,sha256=n980WNeTQpoXgTrH4KbwHFaaAJRdMmIqeCz_MvvSKqg,10655
470
470
  hestia_earth/models/site/netPrimaryProduction.py,sha256=UIIQkYd911qVzrWjxBLrC37e-RARIVgDwLdARY9BuLw,1849
471
471
  hestia_earth/models/site/organicCarbonPerHa.py,sha256=F2ShinHf0m9qKa1nCYBspsDkRY6jzOl0wM8mSDre22I,14916
472
472
  hestia_earth/models/site/organicCarbonPerKgSoil.py,sha256=t--wAshiAKS-JvEKhLFRadGvgSBv5NFZ68jdyms_wh4,1945
@@ -557,10 +557,10 @@ hestia_earth/models/utils/practice.py,sha256=tNadOzsrNlCEt801B815XaruJXzZ5yPASam
557
557
  hestia_earth/models/utils/product.py,sha256=H9UqJNzTqtMWXDQnbRkZlTpv_hg4s-Tya469fBk8InA,10143
558
558
  hestia_earth/models/utils/productivity.py,sha256=bUBVCZInGqHuHZvHDSYPQkjWXQxOtTjEk-1-f_BsFOo,594
559
559
  hestia_earth/models/utils/property.py,sha256=_9Wy0oZIBLsa-jOiGLokKehYLNdz-_7LfLaE4fb6SWM,5085
560
- hestia_earth/models/utils/site.py,sha256=yei3qk7edxb_boag9h8j713r06KGstjTBWdb1KjqMus,3602
560
+ hestia_earth/models/utils/site.py,sha256=zEj2PtIghk-L_vVJidlXM6_ed7HTc2-ogP0sQSh49vw,3874
561
561
  hestia_earth/models/utils/source.py,sha256=Y-CcO5Y3q5Hz4A4RdX35C1EUjL9w1NKnOrzVfOWQ7nU,1748
562
562
  hestia_earth/models/utils/temperature.py,sha256=ljlG4-yCgFFb6LRZweb18cZKLrr7K2mqd4E4Hz_D1f8,476
563
- hestia_earth/models/utils/term.py,sha256=pGg59IUaiTWlqKiT2jgIGvfZriVXaPwsLUbxWvBPXtQ,17812
563
+ hestia_earth/models/utils/term.py,sha256=lStzguJ0x13bPWzzNYD3cjZZVNDZ9xhl2jlAsMJHrxw,18327
564
564
  hestia_earth/models/utils/transformation.py,sha256=nyT5Mz4_VgFwhkL8JoNX9kxxow0zuxzsYl3W8xOu2p0,370
565
565
  hestia_earth/models/webbEtAl2012AndSintermannEtAl2012/__init__.py,sha256=Niv7ZFMBCwThlbCKGOwA17QdkpOUDFrqrFItGNqnZAA,434
566
566
  hestia_earth/models/webbEtAl2012AndSintermannEtAl2012/nh3ToAirOrganicFertiliser.py,sha256=TGXyusrRd9shT842iqbrI6MkQhICgw7uYdrl4jsDrg8,4193
@@ -683,7 +683,7 @@ tests/models/faostat2018/test_coldCarcassWeightPerHead.py,sha256=RImhLygwrJ2RoEH
683
683
  tests/models/faostat2018/test_coldDressedCarcassWeightPerHead.py,sha256=hZVKMtf-F5Iz7igZVahDJoqzfm2VtcIlwWBPCry7kqw,1594
684
684
  tests/models/faostat2018/test_landTransformationFromCropland100YearAverage.py,sha256=AkDXj4qNKgbu5xRbw9u_cUibnVSnAK1CN8pc4IjK9fk,1263
685
685
  tests/models/faostat2018/test_landTransformationFromCropland20YearAverage.py,sha256=L03Xh1QbbXc9yGdMoHGNmyCpu9WKANNiEE73NoBSqxk,1260
686
- tests/models/faostat2018/test_liveweightPerHead.py,sha256=1gnezEdoWvb8Hu-W6YCD3ffI0hAYM8giz9Sl1YxgQDM,4500
686
+ tests/models/faostat2018/test_liveweightPerHead.py,sha256=5Z0Fw7iT3-REg8QjK8tUpWs5bUIG4fjWDM7SEOSYBcw,4799
687
687
  tests/models/faostat2018/test_readyToCookWeightPerHead.py,sha256=pMDcONs0WUvANcJ6_OPF7TBwMF45JGMxFRPNPtHLqVI,1570
688
688
  tests/models/faostat2018/test_seed.py,sha256=tUXoNVveX0m0ed9UXB4zXxIZsPxktXyUXlbWuUKG0sQ,1705
689
689
  tests/models/faostat2018/product/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1009,7 +1009,7 @@ tests/models/site/test_brackishWater.py,sha256=YGCp4glaWudKklYBSp-50KbfvIRtp3F4Q
1009
1009
  tests/models/site/test_cationExchangeCapacityPerKgSoil.py,sha256=tNMhN998vcjQ15I-5mNnFh2d7mHzEBIBO6o1VSfQNUE,1075
1010
1010
  tests/models/site/test_flowingWater.py,sha256=t_rxvdlmUVDsFBoDF20_zDM-0iiLKkNCV7knO9l1T7o,1370
1011
1011
  tests/models/site/test_freshWater.py,sha256=GOeAxHhPW_2E1wQdQRX4W-r7mnb_LgmiAVLImitoApw,982
1012
- tests/models/site/test_management.py,sha256=1ecEbbHNmzA-qSw9-d_sGi-j64FXOCxUm1WLSEmPJHU,12659
1012
+ tests/models/site/test_management.py,sha256=b6CyvJ35Qa5utjsH6d5jo5AHnrb3k3Uv-ez0P6PWask,14102
1013
1013
  tests/models/site/test_netPrimaryProduction.py,sha256=JCxG0MODbKVvl3hOqmKzh4FjHYn3Xs9KsVod6LvKQII,1108
1014
1014
  tests/models/site/test_organicCarbonPerHa.py,sha256=XtGrE7ZqthTF0x8lDxJ1slNd_GvYHEyEydcRgA46jEc,3207
1015
1015
  tests/models/site/test_organicCarbonPerKgSoil.py,sha256=0M-NMg_T3UXzGT_VlKOKhSxg4cZ0_zhd3FRgY5Hpj6o,1087
@@ -1088,8 +1088,8 @@ tests/models/utils/test_source.py,sha256=mv3vHZV5cjpoLA2I1109-YUkuzAiuhbRSnv_76_
1088
1088
  tests/models/utils/test_term.py,sha256=M5Sa26v2gzQYbZ4H_fo7DspnaCx__-WtL-MULGapCWk,3509
1089
1089
  tests/models/webbEtAl2012AndSintermannEtAl2012/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1090
1090
  tests/models/webbEtAl2012AndSintermannEtAl2012/test_nh3ToAirOrganicFertiliser.py,sha256=qi2FNXS5Af2WDtm7nq_FsprH3BfCF0XxnE0XHmC4aIY,2244
1091
- hestia_earth_models-0.62.3.dist-info/LICENSE,sha256=AC7h7GAgCZGJK_Tzh6LUCrML9gQEfowWwecEw2w54QM,1154
1092
- hestia_earth_models-0.62.3.dist-info/METADATA,sha256=W88V_K9ahWR2FHo76_7FbHPa6QINUx_0glKvYrO5G1c,3343
1093
- hestia_earth_models-0.62.3.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
1094
- hestia_earth_models-0.62.3.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1095
- hestia_earth_models-0.62.3.dist-info/RECORD,,
1091
+ hestia_earth_models-0.62.4.dist-info/LICENSE,sha256=AC7h7GAgCZGJK_Tzh6LUCrML9gQEfowWwecEw2w54QM,1154
1092
+ hestia_earth_models-0.62.4.dist-info/METADATA,sha256=WJCEsKRmOjSYJeIm86qjEAHu6PX_HQK_KQwrUrabBDQ,3343
1093
+ hestia_earth_models-0.62.4.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
1094
+ hestia_earth_models-0.62.4.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1095
+ hestia_earth_models-0.62.4.dist-info/RECORD,,
@@ -123,3 +123,12 @@ def test_run_liveAnimal_sheepLamb(mock_download_hestia, *args):
123
123
  }
124
124
  value = run(cycle)
125
125
  assert value == expected
126
+
127
+
128
+ @patch(f"{class_path}._new_property", side_effect=fake_new_property)
129
+ def test_run_liveAninal_missing_term_id(*args):
130
+ with open(f"{fixtures_folder}/liveAnimal/missing-fao-term-id/cycle.jsonld", encoding='utf-8') as f:
131
+ cycle = json.load(f)
132
+
133
+ value = run(cycle)
134
+ assert value == []
@@ -2,7 +2,7 @@ import json
2
2
  from unittest.mock import patch
3
3
 
4
4
  import pytest
5
- from hestia_earth.schema import TermTermType
5
+ from hestia_earth.schema import TermTermType, SiteSiteType
6
6
 
7
7
  from hestia_earth.models.site.management import MODEL, MODEL_KEY, run, _should_run
8
8
  from hestia_earth.models.utils.blank_node import condense_nodes
@@ -17,8 +17,17 @@ 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
+ 'animalHousing': {
21
+ "@type": "Term",
22
+ "@id": "animalHousing",
23
+ "name": "Animal housing",
24
+ "termType": TermTermType.LANDCOVER.value,
25
+ "units": "% area"
26
+ }
20
27
  }
21
28
 
29
+ LAND_COVER_TERM_BY_SITE_TYPE = {SiteSiteType.ANIMAL_HOUSING.value: "animalHousing"}
30
+
22
31
 
23
32
  def lookup_side_effect(*args, **kwargs):
24
33
  # Values taken from real lookups.
@@ -233,7 +242,7 @@ def test_should_run(mock_related_cycles, *args):
233
242
  should_run, *args = _should_run({})
234
243
  assert should_run is True
235
244
 
236
- # with relevant product => run
245
+ # with relevant product, blank site_type => no run
237
246
  mock_related_cycles.return_value = [
238
247
  {
239
248
  "products": [
@@ -253,6 +262,28 @@ def test_should_run(mock_related_cycles, *args):
253
262
  }
254
263
  ]
255
264
  should_run, *args = _should_run({})
265
+ assert should_run is False
266
+
267
+ # with relevant product and site_type => run
268
+ mock_related_cycles.return_value = [
269
+ {
270
+ "products": [
271
+ {
272
+ "term": {
273
+ "termType": TermTermType.CROP.value,
274
+ "@id": "genericCropProduct"
275
+ },
276
+ "value": [51],
277
+ "startDate": "2001",
278
+ "endDate": "2002",
279
+ "properties": {"test": "properties"}
280
+ }
281
+ ],
282
+ "startDate": "2021",
283
+ "endDate": "2022"
284
+ }
285
+ ]
286
+ should_run, *args = _should_run({"siteType": "cropland"})
256
287
  assert should_run is True
257
288
  assert args[0] == [{
258
289
  'term': TERM_BY_ID['genericCropPlant'],
@@ -270,7 +301,7 @@ def test_should_run(mock_related_cycles, *args):
270
301
  ("Example 2", f"{fixtures_folder}/inputs/example2"),
271
302
  ("Example 3", f"{fixtures_folder}/inputs/example3"),
272
303
  ("Example 4", f"{fixtures_folder}/inputs/example4"),
273
- ("Condense Nodes", f"{fixtures_folder}/inputs/condense_nodes")
304
+ ("Condense Nodes", f"{fixtures_folder}/inputs/condense_nodes"),
274
305
  # Expected:
275
306
  # - appleTree (81) x 3 condenses 2020-03-01 to 2021-02-15
276
307
  # - animalManureUsed (true) x 2 condenses 2001-04-01 to 2001-12-31
@@ -282,18 +313,34 @@ def test_should_run(mock_related_cycles, *args):
282
313
  # - sassafrasTree (86) x 2 condenses 2001-01-01 to 2004-12-31
283
314
  # - bananaPlant (87) does not condense [non-consecutive years]
284
315
  # - durianTree (89) does not condense [dates overwritten See 808]
316
+ ("Site Type", f"{fixtures_folder}/inputs/site_type")
285
317
  ]
286
318
  )
287
- @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda id, *args: TERM_BY_ID[id])
319
+ @patch(
320
+ f"{CLASS_PATH}.get_landCover_term_id_from_site_type",
321
+ side_effect=lambda site_type: LAND_COVER_TERM_BY_SITE_TYPE[site_type]
322
+ )
323
+ @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda term_id, *args: TERM_BY_ID[term_id])
288
324
  @patch(f"{CLASS_PATH}.related_cycles")
289
325
  @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):
326
+ def test_run(
327
+ mock_get_lookup_with_debug,
328
+ mock_related_cycles,
329
+ mock_download,
330
+ mock_land_cover_lookup,
331
+ test_name,
332
+ fixture_path
333
+ ):
291
334
  with open(f"{fixture_path}/cycles.jsonld", encoding='utf-8') as f:
292
335
  cycles = json.load(f)
293
336
  mock_related_cycles.return_value = cycles
294
337
 
295
- with open(f"{fixtures_folder}/site.jsonld", encoding='utf-8') as f:
296
- site = json.load(f)
338
+ try:
339
+ with open(f"{fixture_path}/site.jsonld", encoding='utf-8') as f:
340
+ site = json.load(f)
341
+ except FileNotFoundError:
342
+ with open(f"{fixtures_folder}/site.jsonld", encoding='utf-8') as f:
343
+ site = json.load(f)
297
344
 
298
345
  with open(f"{fixture_path}/result.jsonld", encoding='utf-8') as f:
299
346
  expected = json.load(f)