hestia-earth-models 0.67.1__py3-none-any.whl → 0.68.1__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 (148) hide show
  1. hestia_earth/models/aware/scarcityWeightedWaterUse.py +5 -6
  2. hestia_earth/models/blonkConsultants2016/ch4ToAirNaturalVegetationBurning.py +1 -1
  3. hestia_earth/models/blonkConsultants2016/co2ToAirAboveGroundBiomassStockChangeLandUseChange.py +1 -1
  4. hestia_earth/models/blonkConsultants2016/n2OToAirNaturalVegetationBurningDirect.py +1 -1
  5. hestia_earth/models/blonkConsultants2016/utils.py +9 -9
  6. hestia_earth/models/cache_sites.py +44 -23
  7. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandOccupation.py +2 -2
  8. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandTransformation.py +2 -2
  9. hestia_earth/models/chaudharyBrooks2018/utils.py +13 -8
  10. hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +2 -3
  11. hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +1 -1
  12. hestia_earth/models/config/Cycle.json +15 -0
  13. hestia_earth/models/config/ImpactAssessment.json +14 -1
  14. hestia_earth/models/config/Site.json +8 -0
  15. hestia_earth/models/cycle/excretaKgMass.py +2 -2
  16. hestia_earth/models/cycle/materialAndSubstrate.py +3 -2
  17. hestia_earth/models/cycle/pastureGrass.py +3 -3
  18. hestia_earth/models/dammgen2009/noxToAirExcreta.py +1 -1
  19. hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +1 -1
  20. hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +2 -6
  21. hestia_earth/models/emissionNotRelevant/__init__.py +4 -4
  22. hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +30 -21
  23. hestia_earth/models/environmentalFootprintV3_1/photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +36 -0
  24. hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +2 -2
  25. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +9 -8
  26. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +25 -22
  27. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexTotalLandUseEffects.py +7 -6
  28. hestia_earth/models/faostat2018/coldCarcassWeightPerHead.py +2 -2
  29. hestia_earth/models/faostat2018/coldDressedCarcassWeightPerHead.py +2 -2
  30. hestia_earth/models/faostat2018/liveweightPerHead.py +7 -8
  31. hestia_earth/models/faostat2018/product/price.py +34 -28
  32. hestia_earth/models/faostat2018/readyToCookWeightPerHead.py +2 -2
  33. hestia_earth/models/faostat2018/utils.py +15 -27
  34. hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +16 -9
  35. hestia_earth/models/geospatialDatabase/altitude.py +60 -0
  36. hestia_earth/models/geospatialDatabase/croppingIntensity.py +1 -1
  37. hestia_earth/models/geospatialDatabase/ecoClimateZone.py +2 -2
  38. hestia_earth/models/geospatialDatabase/longFallowRatio.py +1 -1
  39. hestia_earth/models/geospatialDatabase/utils.py +4 -1
  40. hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +2 -3
  41. hestia_earth/models/haversineFormula/transport/distance.py +3 -3
  42. hestia_earth/models/hestia/landCover.py +72 -45
  43. hestia_earth/models/hestia/seed_emissions.py +11 -7
  44. hestia_earth/models/impact_assessment/__init__.py +3 -3
  45. hestia_earth/models/ipcc2019/animal/fatContent.py +1 -1
  46. hestia_earth/models/ipcc2019/animal/hoursWorkedPerDay.py +1 -1
  47. hestia_earth/models/ipcc2019/animal/liveweightGain.py +1 -1
  48. hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +1 -1
  49. hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +1 -1
  50. hestia_earth/models/ipcc2019/animal/pastureGrass.py +1 -1
  51. hestia_earth/models/ipcc2019/animal/pregnancyRateTotal.py +1 -1
  52. hestia_earth/models/ipcc2019/animal/trueProteinContent.py +1 -1
  53. hestia_earth/models/ipcc2019/animal/utils.py +5 -7
  54. hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +1 -1
  55. hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +2 -2
  56. hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +6 -7
  57. hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +5 -3
  58. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +1 -1
  59. hestia_earth/models/ipcc2019/croppingDuration.py +3 -6
  60. hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +947 -0
  61. hestia_earth/models/ipcc2019/pastureGrass.py +1 -1
  62. hestia_earth/models/koble2014/residueBurnt.py +5 -7
  63. hestia_earth/models/koble2014/residueRemoved.py +5 -7
  64. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthWaterStress.py +2 -2
  65. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
  66. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthWaterStress.py +2 -2
  67. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
  68. hestia_earth/models/log.py +1 -1
  69. hestia_earth/models/mocking/search-results.json +3397 -1097
  70. hestia_earth/models/site/management.py +1 -1
  71. hestia_earth/models/site/post_checks/__init__.py +3 -2
  72. hestia_earth/models/site/post_checks/country.py +9 -0
  73. hestia_earth/models/site/pre_checks/__init__.py +3 -2
  74. hestia_earth/models/site/pre_checks/country.py +9 -0
  75. hestia_earth/models/site/soilMeasurement.py +2 -0
  76. hestia_earth/models/utils/__init__.py +1 -16
  77. hestia_earth/models/utils/blank_node.py +25 -25
  78. hestia_earth/models/utils/completeness.py +3 -2
  79. hestia_earth/models/utils/cycle.py +5 -4
  80. hestia_earth/models/utils/emission.py +5 -5
  81. hestia_earth/models/utils/feedipedia.py +6 -6
  82. hestia_earth/models/utils/impact_assessment.py +1 -2
  83. hestia_earth/models/utils/indicator.py +9 -7
  84. hestia_earth/models/utils/inorganicFertiliser.py +4 -6
  85. hestia_earth/models/utils/input.py +6 -5
  86. hestia_earth/models/utils/lookup.py +32 -100
  87. hestia_earth/models/utils/management.py +4 -4
  88. hestia_earth/models/utils/measurement.py +7 -8
  89. hestia_earth/models/utils/method.py +20 -0
  90. hestia_earth/models/utils/practice.py +4 -5
  91. hestia_earth/models/utils/product.py +4 -5
  92. hestia_earth/models/utils/property.py +12 -22
  93. hestia_earth/models/utils/site.py +14 -8
  94. hestia_earth/models/utils/term.py +27 -1
  95. hestia_earth/models/version.py +1 -1
  96. hestia_earth/orchestrator/log.py +0 -11
  97. hestia_earth/orchestrator/models/__init__.py +17 -4
  98. hestia_earth/orchestrator/strategies/run/add_blank_node_if_missing.py +2 -20
  99. {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/METADATA +2 -2
  100. {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/RECORD +146 -138
  101. tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +3 -3
  102. tests/models/cml2001Baseline/test_resourceUseEnergyDepletionDuringCycle.py +1 -1
  103. tests/models/cycle/test_coldCarcassWeightPerHead.py +1 -1
  104. tests/models/cycle/test_coldDressedCarcassWeightPerHead.py +1 -1
  105. tests/models/cycle/test_concentrateFeed.py +1 -1
  106. tests/models/cycle/test_energyContentLowerHeatingValue.py +1 -1
  107. tests/models/cycle/test_excretaKgMass.py +1 -1
  108. tests/models/cycle/test_feedConversionRatio.py +3 -3
  109. tests/models/cycle/test_pastureGrass.py +1 -1
  110. tests/models/cycle/test_readyToCookWeightPerHead.py +1 -1
  111. tests/models/environmentalFootprintV3_1/test_photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +30 -0
  112. tests/models/environmentalFootprintV3_1/test_soilQualityIndexTotalLandUseEffects.py +30 -7
  113. tests/models/faostat2018/product/test_price.py +27 -14
  114. tests/models/faostat2018/test_faostat_utils.py +4 -24
  115. tests/models/faostat2018/test_liveweightPerHead.py +9 -9
  116. tests/models/globalCropWaterModel2008/test_rootingDepth.py +7 -3
  117. tests/models/haversineFormula/transport/test_distance.py +1 -1
  118. tests/models/hestia/test_landCover.py +53 -5
  119. tests/models/ipcc2019/animal/test_pastureGrass.py +5 -3
  120. tests/models/ipcc2019/test_aboveGroundCropResidueTotal.py +4 -4
  121. tests/models/ipcc2019/test_belowGroundCropResidue.py +4 -4
  122. tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +10 -10
  123. tests/models/ipcc2019/test_croppingDuration.py +1 -1
  124. tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +83 -0
  125. tests/models/ipcc2019/test_organicCarbonPerHa.py +12 -12
  126. tests/models/ipcc2019/test_pastureGrass.py +5 -3
  127. tests/models/pooreNemecek2018/test_excretaKgN.py +5 -5
  128. tests/models/pooreNemecek2018/test_excretaKgVs.py +2 -2
  129. tests/models/site/post_checks/test_country.py +6 -0
  130. tests/models/site/pre_checks/test_cache_geospatialDatabase.py +1 -1
  131. tests/models/site/pre_checks/test_country.py +12 -0
  132. tests/models/test_ecoinventV3.py +7 -3
  133. tests/models/utils/test_blank_node.py +4 -12
  134. tests/models/utils/test_dataCompleteness.py +5 -5
  135. tests/models/utils/test_emission.py +2 -2
  136. tests/models/utils/test_indicator.py +2 -2
  137. tests/models/utils/test_input.py +2 -2
  138. tests/models/utils/test_measurement.py +2 -4
  139. tests/models/utils/test_practice.py +4 -2
  140. tests/models/utils/test_product.py +2 -2
  141. tests/models/utils/test_property.py +4 -2
  142. tests/models/utils/test_site.py +7 -0
  143. tests/orchestrator/strategies/run/test_add_blank_node_if_missing.py +4 -9
  144. hestia_earth/models/environmentalFootprintV3_1/utils.py +0 -17
  145. tests/models/utils/test_lookup.py +0 -10
  146. {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/LICENSE +0 -0
  147. {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/WHEEL +0 -0
  148. {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/top_level.txt +0 -0
@@ -3,16 +3,15 @@ from collections.abc import Iterable
3
3
  from functools import reduce
4
4
  from statistics import mode, mean
5
5
  from typing import Any, Optional, Union
6
-
7
6
  from hestia_earth.schema import MeasurementMethodClassification, SchemaType
8
- from hestia_earth.utils.api import download_hestia
9
7
  from hestia_earth.utils.model import linked_node
10
8
  from hestia_earth.utils.tools import non_empty_list, flatten, safe_parse_float
11
9
  from hestia_earth.utils.date import diff_in_days
12
10
 
13
- from hestia_earth.models.utils.blank_node import most_relevant_blank_node_by_id
14
- from . import _term_id, _include_method, flatten_args
15
- from .term import get_lookup_value
11
+ from . import flatten_args
12
+ from .blank_node import most_relevant_blank_node_by_id
13
+ from .method import include_methodModel
14
+ from .term import download_term, get_lookup_value
16
15
 
17
16
 
18
17
  # TODO: verify those values
@@ -29,14 +28,14 @@ MEASUREMENT_METHOD_CLASSIFICATIONS = [e.value for e in MeasurementMethodClassifi
29
28
 
30
29
  def _new_measurement(term, model=None):
31
30
  node = {'@type': SchemaType.MEASUREMENT.value}
32
- node['term'] = linked_node(term if isinstance(term, dict) else download_hestia(_term_id(term)))
33
- return _include_method(node, term_id=model)
31
+ node['term'] = linked_node(term if isinstance(term, dict) else download_term(term))
32
+ return include_methodModel(node, term_id=model)
34
33
 
35
34
 
36
35
  def measurement_value(measurement: dict, is_larger_unit: bool = False) -> float:
37
36
  term = measurement.get('term', {})
38
37
  reducer = get_lookup_value(term, 'arrayTreatmentLargerUnitOfTime' if is_larger_unit else 'arrayTreatment') or 'mean'
39
- value = measurement.get('value', [])
38
+ value = non_empty_list(measurement.get('value', []))
40
39
  is_value_valid = value is not None and isinstance(value, list) and len(value) > 0
41
40
  return MEASUREMENT_REDUCE.get(reducer, lambda v: v[0])(value) if is_value_valid else 0
42
41
 
@@ -0,0 +1,20 @@
1
+ from typing import Union
2
+ from hestia_earth.schema import TermTermType
3
+ from hestia_earth.utils.model import linked_node
4
+
5
+ from .term import download_term
6
+
7
+
8
+ def include_method(node: dict, term_id: Union[None, str, dict], key='method'):
9
+ term = (
10
+ download_term(term_id, TermTermType.MODEL) or download_term(term_id) or {}
11
+ ) if isinstance(term_id, str) else term_id
12
+ return node | ({} if term is None or term.get('@id') is None else {key: linked_node(term)})
13
+
14
+
15
+ def include_model(node: dict, term_id: Union[None, str, dict]):
16
+ return include_method(node, term_id=term_id, key='model')
17
+
18
+
19
+ def include_methodModel(node: dict, term_id: Union[None, str, dict]):
20
+ return include_method(node, term_id=term_id, key='methodModel')
@@ -1,15 +1,14 @@
1
1
  from hestia_earth.schema import SchemaType
2
- from hestia_earth.utils.api import download_hestia
3
2
  from hestia_earth.utils.model import linked_node
4
3
 
5
- from . import _term_id, _include_model
6
- from .term import get_lookup_value
4
+ from .term import get_lookup_value, download_term
5
+ from .method import include_model
7
6
 
8
7
 
9
8
  def _new_practice(term, model=None):
10
9
  node = {'@type': SchemaType.PRACTICE.value}
11
- node['term'] = linked_node(term if isinstance(term, dict) else download_hestia(_term_id(term)))
12
- return _include_model(node, model)
10
+ node['term'] = linked_node(term if isinstance(term, dict) else download_term(term))
11
+ return include_model(node, model)
13
12
 
14
13
 
15
14
  def is_model_enabled(model: str, term_id: str, practice: dict = None):
@@ -1,26 +1,25 @@
1
1
  from hestia_earth.schema import SchemaType, TermTermType, UNIQUENESS_FIELDS
2
- from hestia_earth.utils.api import download_hestia
3
2
  from hestia_earth.utils.model import filter_list_term_type, find_term_match, linked_node
4
3
  from hestia_earth.utils.tools import flatten, list_sum, non_empty_list, get_dict_key
5
4
 
6
- from . import _term_id, _include_model
7
5
  from .blank_node import get_total_value, get_total_value_converted
8
6
  from .constant import Units
9
7
  from .currency import DEFAULT_CURRENCY
10
8
  from .property import _get_nitrogen_content, get_node_property_value
11
- from .term import get_rice_paddy_terms
9
+ from .term import get_rice_paddy_terms, download_term
10
+ from .method import include_model
12
11
 
13
12
 
14
13
  def _new_product(term, value: float = None, model=None):
15
14
  node = {'@type': SchemaType.PRODUCT.value}
16
- node['term'] = linked_node(term if isinstance(term, dict) else download_hestia(_term_id(term)))
15
+ node['term'] = linked_node(term if isinstance(term, dict) else download_term(term))
17
16
  if value is not None:
18
17
  node['value'] = [value]
19
18
  elif value == 0:
20
19
  node['economicValueShare'] = 0
21
20
  node['revenue'] = 0
22
21
  node['currency'] = DEFAULT_CURRENCY
23
- return _include_model(node, model)
22
+ return include_model(node, model)
24
23
 
25
24
 
26
25
  def _match_list_el(source: list, dest: list, key: str):
@@ -1,22 +1,17 @@
1
- from functools import cache
2
-
3
1
  from hestia_earth.schema import SchemaType, TermTermType
4
- from hestia_earth.utils.api import download_hestia
5
2
  from hestia_earth.utils.lookup import download_lookup, extract_grouped_data, get_table_value, column_name
6
3
  from hestia_earth.utils.model import find_term_match, linked_node
7
4
  from hestia_earth.utils.tools import list_sum, safe_parse_float
8
5
 
9
- from . import _term_id, _include_methodModel
10
- from .term import get_lookup_value
11
- from ..log import debugMissingLookup
12
-
13
- download_hestia_cached = cache(download_hestia)
6
+ from hestia_earth.models.log import debugMissingLookup
7
+ from .method import include_methodModel
8
+ from .term import download_term, get_lookup_value
14
9
 
15
10
 
16
11
  def _new_property(term, model=None):
17
12
  node = {'@type': SchemaType.PROPERTY.value}
18
- node['term'] = linked_node(term if isinstance(term, dict) else download_hestia(_term_id(term)))
19
- return _include_methodModel(node, model)
13
+ node['term'] = linked_node(term if isinstance(term, dict) else download_term(term, TermTermType.PROPERTY))
14
+ return include_methodModel(node, model)
20
15
 
21
16
 
22
17
  def merge_properties(properties: list, new_properties: list):
@@ -30,7 +25,7 @@ def get_property_lookup_value(model: str, term_id: str, column: str):
30
25
  return get_lookup_value(term, column, model=model, term=term_id)
31
26
 
32
27
 
33
- def find_term_property(term, property: str, default=None, keep_in_memory=False) -> dict:
28
+ def find_term_property(term, property: str, default=None) -> dict:
34
29
  """
35
30
  Get the property by `@id` linked to the `Term` in the glossary.
36
31
 
@@ -42,23 +37,20 @@ def find_term_property(term, property: str, default=None, keep_in_memory=False)
42
37
  The `term.@id` of the property. Example: `nitrogenContent`.
43
38
  default : Any
44
39
  The default value if the property is not found. Defaults to `None`.
45
- keep_in_memory: bool
46
- Should we cache results from download_hestia(). Default False
47
40
 
48
41
  Returns
49
42
  -------
50
43
  dict
51
44
  The property if found, `default` otherwise.
52
45
  """
53
- download_func = download_hestia_cached if keep_in_memory else download_hestia
54
46
  props = term.get('defaultProperties', []) if isinstance(term, dict) else []
55
- term_id = _term_id(term)
56
- props = (download_func(term_id) or {}).get('defaultProperties', []) if len(props) == 0 and term_id else props
47
+ props = (
48
+ download_term(term, TermTermType.PROPERTY) or {}
49
+ ).get('defaultProperties', []) if len(props) == 0 and term else props
57
50
  return find_term_match(props, property, default)
58
51
 
59
52
 
60
- def get_node_property(node: dict, property: str, find_default_property: bool = True,
61
- keep_in_memory: bool = False) -> dict:
53
+ def get_node_property(node: dict, property: str, find_default_property: bool = True) -> dict:
62
54
  """
63
55
  Get the property by `@id` linked to the Blank Node in the glossary.
64
56
 
@@ -74,8 +66,6 @@ def get_node_property(node: dict, property: str, find_default_property: bool = T
74
66
  The `term.@id` of the property. Example: `nitrogenContent`.
75
67
  find_default_property : bool
76
68
  Default to fetching the property from the `defaultProperties` of the `Term`.
77
- keep_in_memory:
78
- If True and find_default_property is True, will cache this term_id call to api
79
69
 
80
70
  Returns
81
71
  -------
@@ -83,7 +73,7 @@ def get_node_property(node: dict, property: str, find_default_property: bool = T
83
73
  The property if found, `None` otherwise.
84
74
  """
85
75
  prop = find_term_match(node.get('properties', []), property, None)
86
- return find_term_property(node.get('term', {}), property, {}, keep_in_memory) if all([
76
+ return find_term_property(node.get('term', {}), property, {}) if all([
87
77
  find_default_property,
88
78
  prop is None
89
79
  ]) else (prop or {})
@@ -115,7 +105,7 @@ def node_property_lookup_value(model: str, node_term: dict, prop_id: str, defaul
115
105
 
116
106
  def get_node_property_value(model: str, node: dict, prop_id: str, default=None, handle_percents=True, **log_args):
117
107
  prop = get_node_property(node, prop_id)
118
- term = (prop or {}).get('term', download_hestia(prop_id))
108
+ term = (prop or {}).get('term') or download_term(prop_id, TermTermType.PROPERTY)
119
109
  units = (term or {}).get('units')
120
110
  value = prop.get('value') if prop else node_property_lookup_value(model, node.get('term', {}), prop_id, **log_args)
121
111
  return default if value is None else (value / 100 if units == '%' and handle_percents else value)
@@ -1,11 +1,12 @@
1
+ from typing import Optional
2
+
1
3
  from hestia_earth.schema import SchemaType, SiteSiteType, TermTermType
2
4
  from hestia_earth.utils.api import find_related
3
- from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
4
5
  from hestia_earth.utils.tools import non_empty_list, flatten, safe_parse_date
5
6
 
6
- from hestia_earth.models.log import debugMissingLookup
7
7
  from . import cached_value, _load_calculated_node
8
8
  from .term import get_land_cover_siteTypes
9
+ from .lookup import get_region_lookup_value
9
10
 
10
11
  CACHE_YEARS_KEY = 'years'
11
12
  WATER_TYPES = [
@@ -67,7 +68,7 @@ def years_from_cycles(cycles: list):
67
68
  ] for cycle in cycles))))
68
69
 
69
70
 
70
- def related_cycles(site: dict):
71
+ def related_cycles(site: dict, cycles_mapping: Optional[dict[str, dict]] = None):
71
72
  """
72
73
  Get the list of `Cycle` related to the `Site`.
73
74
  Gets the `recalculated` data if available, else `original`.
@@ -76,15 +77,23 @@ def related_cycles(site: dict):
76
77
  ----------
77
78
  site_id : str
78
79
  The `@id` of the `Site`.
80
+ cycles_mapping : dict[str, dict], optional
81
+ An optional dict of related `Cycle`s for which the data has already been retrieved, with the format
82
+ `{cycle_id (str): cycle (dict), ...ids}`.
79
83
 
80
84
  Returns
81
85
  -------
82
86
  list[dict]
83
87
  The related `Cycle`s as `dict`.
84
88
  """
89
+ cycles_mapping = cycles_mapping or {}
90
+
85
91
  cached_nodes = [n for n in cached_value(site, 'related', []) if n.get('@type') == SchemaType.CYCLE.value]
86
92
  related_nodes = cached_nodes or find_related(SchemaType.SITE, site.get('@id'), SchemaType.CYCLE) or []
87
- return non_empty_list(map(lambda node: _load_calculated_node(node, SchemaType.CYCLE), related_nodes))
93
+ return non_empty_list(map(
94
+ lambda node: cycles_mapping.get(node['@id']) or _load_calculated_node(node, SchemaType.CYCLE),
95
+ related_nodes
96
+ ))
88
97
 
89
98
 
90
99
  def related_years(site: dict):
@@ -117,10 +126,7 @@ def valid_site_type(site: dict, site_types=[SiteSiteType.CROPLAND.value, SiteSit
117
126
 
118
127
 
119
128
  def region_factor(model: str, region_id: str, term_id: str, termType: TermTermType):
120
- lookup_name = f"region-{termType.value}.csv"
121
- value = get_table_value(download_lookup(lookup_name), 'termid', region_id, column_name(term_id))
122
- debugMissingLookup(lookup_name, 'termid', region_id, term_id, value, model=model, term=term_id)
123
- return value
129
+ return get_region_lookup_value(f"region-{termType.value}.csv", region_id, term_id, model=model, term=term_id)
124
130
 
125
131
 
126
132
  def get_land_cover_term_id(site_type: str):
@@ -1,5 +1,9 @@
1
+ from typing import Union
2
+ from functools import lru_cache
3
+ import json
1
4
  from hestia_earth.schema import SchemaType, TermTermType, SiteSiteType
2
- from hestia_earth.utils.api import find_node, search
5
+ from hestia_earth.utils.storage import _load_from_storage
6
+ from hestia_earth.utils.api import find_node, search, download_hestia
3
7
  from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
4
8
 
5
9
  from .constant import Units
@@ -20,6 +24,28 @@ def get_lookup_value(lookup_term: dict, column: str, skip_debug: bool = False, *
20
24
  return value
21
25
 
22
26
 
27
+ @lru_cache()
28
+ def _load_term_file(term_type: str):
29
+ try:
30
+ filepath = f"glossary/{term_type}.json"
31
+ nodes = json.loads(_load_from_storage(filepath, glossary=True))
32
+ return {node.get('@id'): node for node in nodes}
33
+ except Exception as e:
34
+ print(e)
35
+ return {}
36
+
37
+
38
+ def download_term(term: Union[str, dict], termType: Union[str, TermTermType] = None):
39
+ term_id = term.get('@id', term.get('id')) if isinstance(term, dict) else term
40
+ term_type = (
41
+ termType if isinstance(termType, str) else termType.value
42
+ ) if termType else (
43
+ term.get('termType') if isinstance(term, dict) else None
44
+ )
45
+ cached_nodes = _load_term_file(term_type) if term_type else {}
46
+ return cached_nodes.get(term_id) or download_hestia(term_id)
47
+
48
+
23
49
  def get_liquid_fuel_terms():
24
50
  """
25
51
  Find all "liquid" `fuel` terms from the Glossary:
@@ -1 +1 @@
1
- VERSION = '0.67.1'
1
+ VERSION = '0.68.1'
@@ -1,7 +1,5 @@
1
1
  import os
2
2
  import sys
3
- import platform
4
- import resource
5
3
  import logging
6
4
 
7
5
  LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO')
@@ -44,15 +42,6 @@ if LOG_FILENAME is not None:
44
42
  def _join_args(**kwargs): return ', '.join([f"{key}={value}" for key, value in kwargs.items()])
45
43
 
46
44
 
47
- def log_memory_usage(**kwargs):
48
- factor = 1024 * (
49
- 1024 if platform.system() in ['Darwin', 'Windows'] else 1
50
- )
51
- value = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / factor
52
- extra = (', ' + _join_args(**kwargs)) if len(kwargs.keys()) > 0 else ''
53
- logger.info('memory used=%s, unit=MB' + extra, value)
54
-
55
-
56
45
  def _log_node_suffix(node: dict = {}):
57
46
  node_type = node.get('@type', node.get('type')) if node else None
58
47
  node_id = node.get('@id', node.get('id', node.get('term', {}).get('@id'))) if node else None
@@ -1,18 +1,27 @@
1
1
  import os
2
+ import resource
3
+ import platform
2
4
  from typing import Union, List
3
5
  import importlib
4
6
  from functools import reduce
5
7
  import concurrent.futures
6
8
  from copy import deepcopy
7
- from hestia_earth.utils.tools import non_empty_list
9
+ from hestia_earth.utils.tools import non_empty_list, current_time_ms
8
10
 
9
11
  from hestia_earth.models.version import VERSION
10
- from ..log import logger, log_memory_usage
12
+ from ..log import logger
11
13
  from ..utils import get_required_model_param, _snakecase
12
14
  from ..strategies.run import should_run
13
15
  from ..strategies.merge import merge
14
16
 
15
17
 
18
+ def _memory_usage():
19
+ factor = 1024 * (
20
+ 1024 if platform.system() in ['Darwin', 'Windows'] else 1
21
+ )
22
+ return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / factor
23
+
24
+
16
25
  def _max_workers(type: str):
17
26
  try:
18
27
  return int(os.getenv(f"MAX_WORKERS_{type.upper()}"))
@@ -78,13 +87,17 @@ def _run_post_checks(data: dict):
78
87
  def _run_model(data: dict, model: dict, all_models: list):
79
88
  model_id = get_required_model_param(model, 'model')
80
89
  model_value = model.get('value') or _list_except_item(all_models, model)
81
- log_memory_usage(model_model=model_id, model_value=model_value, step='before')
90
+
91
+ now = current_time_ms()
92
+ memory_usage = _memory_usage()
82
93
 
83
94
  module = _import_model(model_id.replace('-', '_'))
84
95
  # if no value is provided, use all the models but this one
85
96
  result = module.get('run')(model_value, data)
86
97
 
87
- log_memory_usage(model_model=model_id, model_value=model_value, step='after')
98
+ logger.info('model_model=%s, model_value=%s, time=%s, memory_used=%s',
99
+ model_id, model.get('value'), current_time_ms() - now, _memory_usage() - memory_usage)
100
+
88
101
  return {'data': data, 'model': model, 'version': module.get('version'), 'result': result}
89
102
 
90
103
 
@@ -1,29 +1,11 @@
1
- from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
2
- from hestia_earth.utils.api import download_hestia
1
+ from hestia_earth.utils.lookup_utils import is_node_type_allowed
3
2
 
4
3
  from hestia_earth.orchestrator.log import debugValues, logShouldRun
5
4
  from hestia_earth.orchestrator.utils import get_required_model_param, find_term_match
6
5
 
7
- _ALLOW_ALL = 'all'
8
-
9
-
10
- def _lookup_values(term: dict, column: str):
11
- term_id = term.get('@id')
12
- term_type = term.get('termType')
13
- lookup = download_lookup(f"{term_type}.csv")
14
- values = get_table_value(lookup, 'termid', term_id, column_name(column))
15
- return (values or _ALLOW_ALL).split(';')
16
-
17
-
18
- def _is_node_type_allowed(data: dict, term_id: str):
19
- node_type = data.get('@type', data.get('type'))
20
- term = download_hestia(term_id)
21
- allowed_types = _lookup_values(term, 'typesAllowed') if term else [_ALLOW_ALL]
22
- return True if _ALLOW_ALL in allowed_types or not node_type else node_type in allowed_types
23
-
24
6
 
25
7
  def _run_required(data: dict, model: str, term_id: str):
26
- node_type_allowed = _is_node_type_allowed(data, term_id)
8
+ node_type_allowed = is_node_type_allowed(data, term_id)
27
9
 
28
10
  run_required = all([node_type_allowed])
29
11
  debugValues(data, model=model, term=term_id,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hestia-earth-models
3
- Version: 0.67.1
3
+ Version: 0.68.1
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
@@ -12,7 +12,7 @@ Classifier: Programming Language :: Python :: 3.6
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
14
  Requires-Dist: hestia-earth-schema==30.*
15
- Requires-Dist: hestia-earth-utils>=0.13.19
15
+ Requires-Dist: hestia-earth-utils>=0.14.0
16
16
  Requires-Dist: python-dateutil>=2.8.1
17
17
  Requires-Dist: CurrencyConverter==0.16.8
18
18
  Requires-Dist: haversine>=2.7.0