hestia-earth-models 0.73.2__py3-none-any.whl → 0.73.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.
Files changed (26) hide show
  1. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +3 -2
  2. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +1 -1
  3. hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +10 -6
  4. hestia_earth/models/geospatialDatabase/utils.py +20 -7
  5. hestia_earth/models/hestia/default_emissions.py +1 -0
  6. hestia_earth/models/hestia/default_resourceUse.py +3 -2
  7. hestia_earth/models/hestia/excretaKgMass.py +1 -1
  8. hestia_earth/models/hestia/excretaKgN.py +1 -1
  9. hestia_earth/models/hestia/excretaKgVs.py +1 -1
  10. hestia_earth/models/hestia/landCover.py +1 -1
  11. hestia_earth/models/hestia/waterSalinity.py +13 -6
  12. hestia_earth/models/ipcc2019/n2OToAirCropResidueBurningDirect.py +8 -7
  13. hestia_earth/models/mocking/search-results.json +913 -913
  14. hestia_earth/models/schmidt2007/utils.py +2 -2
  15. hestia_earth/models/utils/__init__.py +1 -1
  16. hestia_earth/models/utils/cycle.py +2 -2
  17. hestia_earth/models/utils/impact_assessment.py +14 -14
  18. hestia_earth/models/utils/lookup.py +30 -10
  19. hestia_earth/models/version.py +1 -1
  20. {hestia_earth_models-0.73.2.dist-info → hestia_earth_models-0.73.3.dist-info}/METADATA +1 -1
  21. {hestia_earth_models-0.73.2.dist-info → hestia_earth_models-0.73.3.dist-info}/RECORD +26 -26
  22. tests/models/environmentalFootprintV3_1/test_soilQualityIndexLandOccupation.py +3 -3
  23. tests/models/frischknechtEtAl2000/test_ionisingRadiationKbqU235Eq.py +85 -31
  24. {hestia_earth_models-0.73.2.dist-info → hestia_earth_models-0.73.3.dist-info}/LICENSE +0 -0
  25. {hestia_earth_models-0.73.2.dist-info → hestia_earth_models-0.73.3.dist-info}/WHEEL +0 -0
  26. {hestia_earth_models-0.73.2.dist-info → hestia_earth_models-0.73.3.dist-info}/top_level.txt +0 -0
@@ -16,7 +16,7 @@ REQUIREMENTS = {
16
16
  "optional": {"country": {"@type": "Term", "termType": "region"}},
17
17
  "emissionsResourceUse": [{
18
18
  "@type": "Indicator",
19
- "value": ">0",
19
+ "value": ">=0",
20
20
  "term.@id": ["landOccupationInputsProduction", "landOccupationDuringCycle"],
21
21
  "term.units": "m2*year",
22
22
  "landCover": {"@type": "Term", "term.termType": "landCover"}
@@ -60,12 +60,13 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
60
60
  ]
61
61
 
62
62
  found_land_occupation_indicators = [{
63
+ 'indicator-id': indicator.get('term', {}).get('@id', ''),
63
64
  'area-by-year': _node_value(indicator),
64
65
  'area-unit': indicator.get('term', {}).get("units"),
65
66
  'land-cover-id': indicator.get('landCover', {}).get("@id"),
66
67
  'country-id': get_country_id(impact_assessment, blank_node=indicator),
67
68
  'area-by-year-is-valid': _node_value(indicator) is not None and _node_value(
68
- indicator) > 0,
69
+ indicator) >= 0,
69
70
  'area-unit-is-valid': indicator.get('term', {}).get("units") == "m2*year",
70
71
  'used-country': fallback_country(get_country_id(impact_assessment, blank_node=indicator), [LOOKUP]),
71
72
  'pef-grouping': get_pef_grouping(indicator.get('landCover', {}).get("@id"))
@@ -92,10 +92,10 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
92
92
 
93
93
  found_transformations = [
94
94
  {
95
+ 'indicator-id': indicator.get('term', {}).get('@id', ''),
95
96
  'value': _node_value(indicator),
96
97
  'land-cover-id-from': indicator.get('previousLandCover', {}).get("@id"),
97
98
  'land-cover-id-to': indicator.get('landCover', {}).get("@id"),
98
- 'indicator-id': indicator.get('term', {}).get('@id', ''),
99
99
  'good-land-cover-term': all([
100
100
  bool(indicator.get('landCover')),
101
101
  bool(indicator.get('previousLandCover'))
@@ -1,9 +1,11 @@
1
+ from functools import reduce
1
2
  from hestia_earth.schema import TermTermType
2
3
  from hestia_earth.utils.lookup import get_table_value, download_lookup, column_name
3
4
  from hestia_earth.utils.model import filter_list_term_type
4
- from hestia_earth.utils.tools import flatten
5
+ from hestia_earth.utils.tools import flatten, list_sum
5
6
 
6
7
  from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
8
+ from hestia_earth.models.utils.blank_node import group_by_keys
7
9
  from hestia_earth.models.utils.indicator import _new_indicator
8
10
  from hestia_earth.models.utils.lookup import _node_value
9
11
  from . import MODEL
@@ -47,22 +49,24 @@ def _valid_emission(emission: dict) -> bool:
47
49
  return len(emission.get('inputs', [])) == 1 and isinstance(_node_value(emission), (int, float))
48
50
 
49
51
 
50
- def _indicator(value: float, input: dict):
52
+ def _indicator(value: float, input: dict) -> dict:
51
53
  indicator = _new_indicator(TERM_ID, MODEL)
52
54
  indicator['value'] = value
53
55
  indicator['inputs'] = [input]
54
56
  return indicator
55
57
 
56
58
 
57
- def _run(emissions: list):
59
+ def _run(emissions: list) -> list[dict]:
58
60
  indicators = [
59
- _indicator(value=emission['value'] * emission['coefficient'], input=emission['input'])
60
- for emission in emissions
61
+ _indicator(value=list_sum([emission['value'] * emission['coefficient'] for emission in emission_group]),
62
+ input=emission_group[0]['input'])
63
+ for emission_group in reduce(group_by_keys(['input']), emissions, {}).values()
61
64
  ]
65
+
62
66
  return indicators
63
67
 
64
68
 
65
- def _should_run(impact_assessment: dict):
69
+ def _should_run(impact_assessment: dict) -> tuple[bool, list]:
66
70
  emissions = [
67
71
  emission
68
72
  for emission in filter_list_term_type(impact_assessment.get('emissionsResourceUse', []), TermTermType.EMISSION)
@@ -1,6 +1,7 @@
1
1
  import os
2
+ import json
2
3
  from area import area
3
- from functools import reduce
4
+ from functools import reduce, lru_cache
4
5
  from hestia_earth.schema import TermTermType
5
6
  from hestia_earth.utils.tools import non_empty_list
6
7
 
@@ -10,6 +11,7 @@ from hestia_earth.models.utils.term import download_term
10
11
  from . import MODEL
11
12
 
12
13
  MAX_AREA_SIZE = int(os.getenv('MAX_AREA_SIZE', '5000'))
14
+ _ENABLE_CACHE_BOUNDARY_AREA = os.getenv('CACHE_BOUNDARY_AREA', 'false') == 'true'
13
15
  CACHE_VALUE = MODEL
14
16
  CACHE_AREA_SIZE = 'areaSize'
15
17
  GEOPANDAS_COLLECTION_NAME = {
@@ -85,17 +87,28 @@ def geospatial_data(site: dict, only_coordinates=False):
85
87
  })
86
88
 
87
89
 
88
- def _get_boundary_area_size(boundary: dict):
90
+ def _geojson_area_size(boundary: dict):
91
+ return (
92
+ _geojson_area_size(boundary.get('geometry')) if 'geometry' in boundary else
93
+ reduce(lambda p, c: p + _geojson_area_size(c), boundary.get('features'), 0) if 'features' in boundary
94
+ else area(boundary) / 1_000_000
95
+ )
96
+
97
+
98
+ @lru_cache()
99
+ def _cached_boundary_area_size(boundary: str):
89
100
  try:
90
- return (
91
- (area(boundary.get('geometry')) / 1_000_000) if 'geometry' in boundary else
92
- reduce(lambda p, c: p + _get_boundary_area_size(c), boundary.get('features'), 0) if 'features' in boundary
93
- else area(boundary) / 1_000_000
94
- )
101
+ return _geojson_area_size(json.loads(boundary))
95
102
  except Exception:
96
103
  return None
97
104
 
98
105
 
106
+ def _get_boundary_area_size(boundary: dict):
107
+ return _cached_boundary_area_size(
108
+ boundary=json.dumps(boundary)
109
+ ) if _ENABLE_CACHE_BOUNDARY_AREA else _geojson_area_size(boundary=boundary)
110
+
111
+
99
112
  def _get_region_area_size(site: dict):
100
113
  term = site.get('region', site.get('country'))
101
114
  return term.get('area', (download_term(term.get('@id'), TermTermType.REGION) or {}).get('area')) if term else None
@@ -31,6 +31,7 @@ RETURNS = {
31
31
  }]
32
32
  }
33
33
  LOOKUPS = {
34
+ "emission": "inHestiaDefaultSystemBoundary",
34
35
  "organicFertiliser": "backgroundEmissionsResourceUseDefaultValue"
35
36
  }
36
37
  MODEL_KEY = 'default_emissions'
@@ -1,6 +1,6 @@
1
1
  from hestia_earth.schema import IndicatorMethodTier, TermTermType
2
2
  from hestia_earth.utils.tools import flatten, safe_parse_float
3
- from hestia_earth.utils.lookup import download_lookup, lookup_term_ids
3
+ from hestia_earth.utils.emission import emissions_in_system_boundary
4
4
 
5
5
  from hestia_earth.models.log import logRequirements, logShouldRun
6
6
  from hestia_earth.models.utils import _omit
@@ -34,6 +34,7 @@ RETURNS = {
34
34
  }]
35
35
  }
36
36
  LOOKUPS = {
37
+ "resourceUse": "inHestiaDefaultSystemBoundary",
37
38
  "organicFertiliser": "backgroundEmissionsResourceUseDefaultValue"
38
39
  }
39
40
  MODEL_KEY = 'default_resourceUse'
@@ -54,7 +55,7 @@ def _default_value(input: dict):
54
55
 
55
56
  def _run_input(impact: dict):
56
57
  required_resourceUse_term_ids = [
57
- id for id in lookup_term_ids(download_lookup(f"{TermTermType.RESOURCEUSE.value}.csv"))
58
+ id for id in emissions_in_system_boundary(TermTermType.RESOURCEUSE)
58
59
  if id.endswith('InputsProduction')
59
60
  ]
60
61
 
@@ -52,7 +52,7 @@ def _convert_by_product(cycle: dict, product: dict, term_id: str):
52
52
  conversion_to_kg_ratio
53
53
  ]) else None
54
54
 
55
- debugValues(cycle, model=MODEL, term=term_id,
55
+ debugValues(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
56
56
  using_excreta_product=existing_product.get('term', {}).get('@id'),
57
57
  conversion_to_kg_ratio=conversion_to_kg_ratio,
58
58
  value=value)
@@ -38,7 +38,7 @@ def _run_product(cycle: dict, term_id: str):
38
38
  existing_kg_product = find_term_match(cycle.get('products', []), get_kg_term_id(term_id))
39
39
  value = convert_product_to_unit(existing_kg_product, Units.KG_N)
40
40
 
41
- debugValues(cycle, model=MODEL, term=term_id,
41
+ debugValues(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
42
42
  using_excreta_product=existing_kg_product.get('term', {}).get('@id'),
43
43
  value=value)
44
44
 
@@ -38,7 +38,7 @@ def _run_product(cycle: dict, term_id: str):
38
38
  existing_kg_product = find_term_match(cycle.get('products', []), get_kg_term_id(term_id))
39
39
  value = convert_product_to_unit(existing_kg_product, Units.KG_VS)
40
40
 
41
- debugValues(cycle, model=MODEL, term=term_id,
41
+ debugValues(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
42
42
  using_excreta_product=existing_kg_product.get('term', {}).get('@id'),
43
43
  value=value)
44
44
 
@@ -818,7 +818,7 @@ def _should_run(site: dict) -> tuple[bool, list, dict]:
818
818
 
819
819
  has_no_prior_land_cover_data = _no_prior_land_cover_data(
820
820
  nodes=management_nodes,
821
- target_node=relevant_nodes[-1:][0]
821
+ target_node=relevant_nodes[0]
822
822
  ) if relevant_nodes else None
823
823
 
824
824
  should_run_nodes, site_area = _should_run_historical_land_use_change(
@@ -1,11 +1,13 @@
1
+ from functools import reduce
1
2
  from hestia_earth.schema import MeasurementMethodClassification, TermTermType
2
3
  from hestia_earth.utils.model import filter_list_term_type
3
- from hestia_earth.utils.tools import safe_parse_float
4
+ from hestia_earth.utils.tools import safe_parse_float, list_average, non_empty_list
4
5
 
5
6
  from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
6
7
  from hestia_earth.models.utils.measurement import _new_measurement
7
8
  from hestia_earth.models.utils.site import related_cycles
8
9
  from hestia_earth.models.utils.term import get_lookup_value
10
+ from hestia_earth.models.utils.blank_node import group_by_keys
9
11
  from . import MODEL
10
12
 
11
13
  REQUIREMENTS = {
@@ -43,7 +45,7 @@ def _measurement(value: float, start_date: str = None, end_date: str = None):
43
45
  if start_date:
44
46
  data['startDate'] = start_date
45
47
  data['methodClassification'] = MeasurementMethodClassification.EXPERT_OPINION.value
46
- return data
48
+ return data if value is not None else None
47
49
 
48
50
 
49
51
  def _should_run(site: dict):
@@ -73,7 +75,12 @@ def _should_run(site: dict):
73
75
 
74
76
  def run(site: dict):
75
77
  should_run, values = _should_run(site)
76
- return [
77
- _measurement(value.get('lookup-value'), value.get('start-date'), value.get('end-date'))
78
- for value in values if value.get('lookup-value') is not None
79
- ] if should_run else []
78
+ grouped_values = reduce(group_by_keys(['start-date', 'end-date']), values, {})
79
+ return non_empty_list([
80
+ _measurement(
81
+ list_average([v.get('lookup-value') for v in value if v.get('lookup-value')], default=0),
82
+ value[0].get('start-date'),
83
+ value[0].get('end-date')
84
+ )
85
+ for value in grouped_values.values()
86
+ ]) if should_run else []
@@ -38,24 +38,25 @@ def _emission(value: float):
38
38
  return emission
39
39
 
40
40
 
41
- def _run(product_value: list):
41
+ def _run(product_value: list, factor: float):
42
42
  value = sum(product_value)
43
- factor = get_lookup_value({'termType': 'emission', '@id': TERM_ID}, LOOKUPS['emission'][0])
44
43
  return [_emission(value * factor)]
45
44
 
46
45
 
47
46
  def _should_run(cycle: dict):
48
47
  crop_residue_burnt_value = get_crop_residue_burnt_value(cycle)
49
48
  has_crop_residue_burnt = len(crop_residue_burnt_value) > 0
49
+ factor = get_lookup_value({'termType': 'emission', '@id': TERM_ID}, LOOKUPS['emission'][0])
50
50
 
51
51
  logRequirements(cycle, model=MODEL, term=TERM_ID,
52
- has_crop_residue_burnt=has_crop_residue_burnt)
52
+ has_crop_residue_burnt=has_crop_residue_burnt,
53
+ burning_factor=factor)
53
54
 
54
- should_run = all([has_crop_residue_burnt])
55
+ should_run = all([has_crop_residue_burnt, factor is not None])
55
56
  logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
56
- return should_run, crop_residue_burnt_value
57
+ return should_run, crop_residue_burnt_value, factor
57
58
 
58
59
 
59
60
  def run(cycle: dict):
60
- should_run, crop_residue_burnt_value = _should_run(cycle)
61
- return _run(crop_residue_burnt_value) if should_run else []
61
+ should_run, crop_residue_burnt_value, factor = _should_run(cycle)
62
+ return _run(crop_residue_burnt_value, factor) if should_run else []