hestia-earth-models 0.67.0__py3-none-any.whl → 0.68.0__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 (161) 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 +26 -14
  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/cml2001Baseline/resourceUseEnergyDepletionDuringCycle.py +5 -10
  13. hestia_earth/models/config/Cycle.json +15 -0
  14. hestia_earth/models/config/ImpactAssessment.json +14 -1
  15. hestia_earth/models/config/Site.json +8 -0
  16. hestia_earth/models/cycle/completeness/freshForage.py +7 -3
  17. hestia_earth/models/cycle/excretaKgMass.py +2 -2
  18. hestia_earth/models/cycle/inorganicFertiliser.py +67 -17
  19. hestia_earth/models/cycle/materialAndSubstrate.py +3 -2
  20. hestia_earth/models/cycle/pastureGrass.py +3 -3
  21. hestia_earth/models/dammgen2009/noxToAirExcreta.py +1 -1
  22. hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +1 -1
  23. hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +2 -6
  24. hestia_earth/models/emissionNotRelevant/__init__.py +4 -4
  25. hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +60 -46
  26. hestia_earth/models/environmentalFootprintV3_1/photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +36 -0
  27. hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +2 -2
  28. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +9 -8
  29. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +45 -34
  30. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexTotalLandUseEffects.py +24 -21
  31. hestia_earth/models/faostat2018/coldCarcassWeightPerHead.py +2 -2
  32. hestia_earth/models/faostat2018/coldDressedCarcassWeightPerHead.py +2 -2
  33. hestia_earth/models/faostat2018/liveweightPerHead.py +7 -8
  34. hestia_earth/models/faostat2018/product/price.py +34 -28
  35. hestia_earth/models/faostat2018/readyToCookWeightPerHead.py +2 -2
  36. hestia_earth/models/faostat2018/utils.py +15 -27
  37. hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +16 -9
  38. hestia_earth/models/geospatialDatabase/altitude.py +60 -0
  39. hestia_earth/models/geospatialDatabase/croppingIntensity.py +1 -1
  40. hestia_earth/models/geospatialDatabase/ecoClimateZone.py +2 -2
  41. hestia_earth/models/geospatialDatabase/longFallowRatio.py +1 -1
  42. hestia_earth/models/geospatialDatabase/utils.py +4 -1
  43. hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +2 -3
  44. hestia_earth/models/haversineFormula/transport/distance.py +3 -3
  45. hestia_earth/models/hestia/landCover.py +72 -45
  46. hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +1 -1
  47. hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +1 -1
  48. hestia_earth/models/hestia/seed_emissions.py +11 -7
  49. hestia_earth/models/impact_assessment/__init__.py +3 -3
  50. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +1 -1
  51. hestia_earth/models/ipcc2019/animal/fatContent.py +1 -1
  52. hestia_earth/models/ipcc2019/animal/hoursWorkedPerDay.py +1 -1
  53. hestia_earth/models/ipcc2019/animal/liveweightGain.py +1 -1
  54. hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +1 -1
  55. hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +1 -1
  56. hestia_earth/models/ipcc2019/animal/pastureGrass.py +1 -1
  57. hestia_earth/models/ipcc2019/animal/pregnancyRateTotal.py +1 -1
  58. hestia_earth/models/ipcc2019/animal/trueProteinContent.py +1 -1
  59. hestia_earth/models/ipcc2019/animal/utils.py +5 -7
  60. hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +1 -1
  61. hestia_earth/models/ipcc2019/belowGroundBiomass.py +1 -1
  62. hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +2 -2
  63. hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +6 -7
  64. hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +5 -3
  65. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +1 -1
  66. hestia_earth/models/ipcc2019/croppingDuration.py +3 -6
  67. hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +947 -0
  68. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +4 -4
  69. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +1 -1
  70. hestia_earth/models/ipcc2019/pastureGrass.py +1 -1
  71. hestia_earth/models/koble2014/residueBurnt.py +5 -7
  72. hestia_earth/models/koble2014/residueRemoved.py +5 -7
  73. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthWaterStress.py +2 -2
  74. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
  75. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthWaterStress.py +2 -2
  76. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
  77. hestia_earth/models/log.py +1 -1
  78. hestia_earth/models/mocking/search-results.json +3477 -1045
  79. hestia_earth/models/site/management.py +1 -1
  80. hestia_earth/models/site/post_checks/__init__.py +3 -2
  81. hestia_earth/models/site/post_checks/country.py +9 -0
  82. hestia_earth/models/site/pre_checks/__init__.py +3 -2
  83. hestia_earth/models/site/pre_checks/country.py +9 -0
  84. hestia_earth/models/utils/__init__.py +1 -16
  85. hestia_earth/models/utils/blank_node.py +89 -36
  86. hestia_earth/models/utils/completeness.py +3 -2
  87. hestia_earth/models/utils/cycle.py +5 -4
  88. hestia_earth/models/utils/ecoClimateZone.py +2 -2
  89. hestia_earth/models/utils/emission.py +5 -5
  90. hestia_earth/models/utils/feedipedia.py +6 -6
  91. hestia_earth/models/utils/impact_assessment.py +6 -6
  92. hestia_earth/models/utils/indicator.py +9 -7
  93. hestia_earth/models/utils/inorganicFertiliser.py +4 -6
  94. hestia_earth/models/utils/input.py +6 -5
  95. hestia_earth/models/utils/lookup.py +35 -105
  96. hestia_earth/models/utils/management.py +4 -4
  97. hestia_earth/models/utils/measurement.py +6 -7
  98. hestia_earth/models/utils/method.py +20 -0
  99. hestia_earth/models/utils/practice.py +4 -5
  100. hestia_earth/models/utils/product.py +4 -5
  101. hestia_earth/models/utils/property.py +12 -22
  102. hestia_earth/models/utils/site.py +14 -8
  103. hestia_earth/models/utils/term.py +27 -1
  104. hestia_earth/models/version.py +1 -1
  105. hestia_earth/orchestrator/log.py +0 -11
  106. hestia_earth/orchestrator/models/__init__.py +17 -4
  107. hestia_earth/orchestrator/strategies/run/add_blank_node_if_missing.py +2 -20
  108. {hestia_earth_models-0.67.0.dist-info → hestia_earth_models-0.68.0.dist-info}/METADATA +2 -2
  109. {hestia_earth_models-0.67.0.dist-info → hestia_earth_models-0.68.0.dist-info}/RECORD +159 -151
  110. tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +3 -3
  111. tests/models/cml2001Baseline/test_resourceUseEnergyDepletionDuringCycle.py +68 -35
  112. tests/models/cycle/test_coldCarcassWeightPerHead.py +1 -1
  113. tests/models/cycle/test_coldDressedCarcassWeightPerHead.py +1 -1
  114. tests/models/cycle/test_concentrateFeed.py +1 -1
  115. tests/models/cycle/test_energyContentLowerHeatingValue.py +1 -1
  116. tests/models/cycle/test_excretaKgMass.py +1 -1
  117. tests/models/cycle/test_feedConversionRatio.py +3 -3
  118. tests/models/cycle/test_pastureGrass.py +1 -1
  119. tests/models/cycle/test_readyToCookWeightPerHead.py +1 -1
  120. tests/models/environmentalFootprintV3_1/test_environmentalFootprintSingleOverallScore.py +38 -8
  121. tests/models/environmentalFootprintV3_1/test_photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +30 -0
  122. tests/models/environmentalFootprintV3_1/test_soilQualityIndexLandTransformation.py +65 -36
  123. tests/models/environmentalFootprintV3_1/test_soilQualityIndexTotalLandUseEffects.py +30 -7
  124. tests/models/faostat2018/product/test_price.py +27 -14
  125. tests/models/faostat2018/test_faostat_utils.py +4 -24
  126. tests/models/faostat2018/test_liveweightPerHead.py +9 -9
  127. tests/models/globalCropWaterModel2008/test_rootingDepth.py +7 -3
  128. tests/models/haversineFormula/transport/test_distance.py +1 -1
  129. tests/models/hestia/test_landCover.py +53 -5
  130. tests/models/ipcc2019/animal/test_pastureGrass.py +5 -3
  131. tests/models/ipcc2019/test_aboveGroundCropResidueTotal.py +4 -4
  132. tests/models/ipcc2019/test_belowGroundCropResidue.py +4 -4
  133. tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +10 -10
  134. tests/models/ipcc2019/test_croppingDuration.py +1 -1
  135. tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +83 -0
  136. tests/models/ipcc2019/test_organicCarbonPerHa.py +12 -12
  137. tests/models/ipcc2019/test_pastureGrass.py +5 -3
  138. tests/models/pooreNemecek2018/test_excretaKgN.py +5 -5
  139. tests/models/pooreNemecek2018/test_excretaKgVs.py +2 -2
  140. tests/models/site/post_checks/test_country.py +6 -0
  141. tests/models/site/pre_checks/test_cache_geospatialDatabase.py +1 -1
  142. tests/models/site/pre_checks/test_country.py +12 -0
  143. tests/models/site/test_management.py +1 -4
  144. tests/models/test_ecoinventV3.py +7 -3
  145. tests/models/utils/test_blank_node.py +17 -177
  146. tests/models/utils/test_dataCompleteness.py +5 -5
  147. tests/models/utils/test_emission.py +2 -2
  148. tests/models/utils/test_indicator.py +2 -2
  149. tests/models/utils/test_input.py +2 -2
  150. tests/models/utils/test_measurement.py +2 -4
  151. tests/models/utils/test_practice.py +4 -2
  152. tests/models/utils/test_product.py +2 -2
  153. tests/models/utils/test_property.py +4 -2
  154. tests/models/utils/test_site.py +7 -0
  155. tests/orchestrator/models/test_transformations.py +4 -1
  156. tests/orchestrator/strategies/run/test_add_blank_node_if_missing.py +4 -9
  157. hestia_earth/models/environmentalFootprintV3_1/utils.py +0 -17
  158. tests/models/utils/test_lookup.py +0 -10
  159. {hestia_earth_models-0.67.0.dist-info → hestia_earth_models-0.68.0.dist-info}/LICENSE +0 -0
  160. {hestia_earth_models-0.67.0.dist-info → hestia_earth_models-0.68.0.dist-info}/WHEEL +0 -0
  161. {hestia_earth_models-0.67.0.dist-info → hestia_earth_models-0.68.0.dist-info}/top_level.txt +0 -0
@@ -4,16 +4,17 @@ Product Price
4
4
  Calculates the price of `crop` and `liveAnimal` using FAOSTAT data.
5
5
  """
6
6
  from hestia_earth.schema import TermTermType
7
- from hestia_earth.utils.api import download_hestia
8
- from hestia_earth.utils.lookup import get_table_value, column_name, download_lookup, extract_grouped_data
7
+ from hestia_earth.utils.lookup import extract_grouped_data
9
8
  from hestia_earth.utils.tools import non_empty_list, safe_parse_float, safe_parse_date
10
9
 
11
- from hestia_earth.models.log import debugMissingLookup, debugValues, logRequirements, logShouldRun
10
+ from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
12
11
  from hestia_earth.models.utils.constant import Units
12
+ from hestia_earth.models.utils.term import download_term
13
13
  from hestia_earth.models.utils.currency import DEFAULT_CURRENCY
14
14
  from hestia_earth.models.utils.crop import FAOSTAT_PRODUCTION_LOOKUP_COLUMN, get_crop_grouping_faostat_production
15
15
  from hestia_earth.models.utils.animalProduct import FAO_LOOKUP_COLUMN, get_animalProduct_grouping_fao
16
16
  from hestia_earth.models.utils.product import convert_product_to_unit
17
+ from hestia_earth.models.utils.lookup import get_region_lookup_value
17
18
  from ..utils import get_liveAnimal_to_animalProduct_id
18
19
  from .. import MODEL
19
20
 
@@ -37,12 +38,12 @@ RETURNS = {
37
38
  LOOKUPS = {
38
39
  "@doc": "Depending on the primary product [termType](https://hestia.earth/schema/Product#term)",
39
40
  "crop": "cropGroupingFaostatProduction",
40
- "region-crop-cropGroupingFaostatProduction-price": "use value from above",
41
+ "region-crop-cropGroupingFaostatProduction-price": "",
41
42
  "liveAnimal": ["primaryMeatProductFaoPriceTermId"],
42
43
  "animalProduct": ["animalProductGroupingFAOEquivalent", "animalProductGroupingFAO"],
43
- "region-animalProduct-animalProductGroupingFAO-price": "use value from above",
44
- "region-animalProduct-animalProductGroupingFAO-averageColdCarcassWeight": "use value from above",
45
- "region-animalProduct-animalProductGroupingFAO-weightPerItem": "use value from above"
44
+ "region-animalProduct-animalProductGroupingFAO-price": "",
45
+ "region-animalProduct-animalProductGroupingFAO-averageColdCarcassWeight": "",
46
+ "region-animalProduct-animalProductGroupingFAO-weightPerItem": ""
46
47
  }
47
48
  MODEL_KEY = 'price'
48
49
  LOOKUP_NAME = {
@@ -62,14 +63,19 @@ def _term_grouping(term: dict): return LOOKUP_GROUPING.get(term.get('termType'),
62
63
 
63
64
 
64
65
  def _lookup_data(
65
- term_id: str, grouping: str, country_id: str, year: int, term_type: str = None, lookup_name: str = None
66
+ term_id: str, grouping: str, country: dict, year: int, term_type: str = None, lookup_name: str = None
66
67
  ):
67
- lookup_name = lookup_name or LOOKUP_NAME.get(term_type)
68
- lookup = download_lookup(lookup_name)
69
- data = get_table_value(lookup, 'termid', country_id, column_name(grouping))
70
- debugMissingLookup(lookup_name, 'termid', country_id, grouping, data, model=MODEL, term=term_id, key=MODEL_KEY)
71
- price = extract_grouped_data(data, str(year)) or extract_grouped_data(data, 'Average_price_per_tonne')
72
- return safe_parse_float(price, None)
68
+ lookup_name = lookup_name or LOOKUP_NAME.get(term_type, '')
69
+
70
+ def get_data(country_id):
71
+ data = get_region_lookup_value(lookup_name, country_id, grouping, model=MODEL, term=term_id, key=MODEL_KEY)
72
+ price = extract_grouped_data(data, str(year)) or extract_grouped_data(data, 'Average_price_per_tonne')
73
+ return safe_parse_float(price, None)
74
+
75
+ # try get country data first, falls back to region data
76
+ country_id = country.get('@id')
77
+ region_id = (country.get('subClassOf') or [{}])[0].get('@id')
78
+ return get_data(country_id) or (get_data(region_id) if region_id else None)
73
79
 
74
80
 
75
81
  def _product(product: dict, value: float):
@@ -77,7 +83,7 @@ def _product(product: dict, value: float):
77
83
  return product | {'currency': DEFAULT_CURRENCY, MODEL_KEY: round(value, 4)}
78
84
 
79
85
 
80
- def _get_liveAnimal_lookup_values(cycle: dict, product: dict, country_id: str, year: int = None):
86
+ def _get_liveAnimal_lookup_values(cycle: dict, product: dict, country: dict, year: int = None):
81
87
  term_id = product.get('term', {}).get('@id')
82
88
  animal_product = get_liveAnimal_to_animalProduct_id(term_id, LOOKUPS['liveAnimal'][0], key=MODEL_KEY)
83
89
  groupingFAO = _term_grouping({'termType': TermTermType.ANIMALPRODUCT.value, '@id': animal_product})
@@ -85,7 +91,7 @@ def _get_liveAnimal_lookup_values(cycle: dict, product: dict, country_id: str, y
85
91
  # one live animal can be linked to many animal product, hence go one by one until we have a match
86
92
  if groupingFAO:
87
93
  price_per_ton_liveweight = _lookup_data(
88
- term_id, groupingFAO, country_id, year, term_type=TermTermType.ANIMALPRODUCT.value
94
+ term_id, groupingFAO, country, year, term_type=TermTermType.ANIMALPRODUCT.value
89
95
  )
90
96
  debugValues(cycle, model=MODEL, term=term_id, key=MODEL_KEY, by='liveAnimal',
91
97
  animal_product=animal_product,
@@ -97,11 +103,11 @@ def _get_liveAnimal_lookup_values(cycle: dict, product: dict, country_id: str, y
97
103
  return (None, None)
98
104
 
99
105
 
100
- def _run_by_liveAnimal(cycle: dict, product: dict, country_id: str, year: int = None):
106
+ def _run_by_liveAnimal(cycle: dict, product: dict, country: dict, year: int = None):
101
107
  term_id = product.get('term', {}).get('@id')
102
- animal_product_id, price_per_kg_liveweight = _get_liveAnimal_lookup_values(cycle, product, country_id, year)
108
+ animal_product_id, price_per_kg_liveweight = _get_liveAnimal_lookup_values(cycle, product, country, year)
103
109
 
104
- animal_product = download_hestia(animal_product_id)
110
+ animal_product = download_term(animal_product_id, TermTermType.ANIMALPRODUCT)
105
111
  price_per_head = convert_product_to_unit({
106
112
  **product,
107
113
  'term': animal_product,
@@ -123,7 +129,7 @@ def _should_run_liveAnimal(product: dict):
123
129
  return product.get('term', {}).get('termType') == TermTermType.LIVEANIMAL.value
124
130
 
125
131
 
126
- def _run_by_country(cycle: dict, product: dict, country_id: str, year: int = None):
132
+ def _run_by_country(cycle: dict, product: dict, country: dict, year: int = None):
127
133
  product_term = product.get('term', {})
128
134
  term_id = product_term.get('@id')
129
135
  term_type = product_term.get('termType')
@@ -136,12 +142,12 @@ def _run_by_country(cycle: dict, product: dict, country_id: str, year: int = Non
136
142
  grouping = _term_grouping(product_term) or None
137
143
 
138
144
  should_run = all([not_already_set, has_yield, grouping])
139
- value = _lookup_data(term_id, grouping, country_id, year, term_type=term_type) if should_run else None
145
+ value = _lookup_data(term_id, grouping, country, year, term_type=term_type) if should_run else None
140
146
 
141
147
  # if units is number instead of kg, need to convert to number first
142
- conversion_to_number = safe_parse_float(get_table_value(
143
- download_lookup(LOOKUP_UNITS_NUMBER.get(term_type)), 'termid', country_id, column_name(grouping)
144
- ), 1) if term_units == Units.NUMBER.value else 1
148
+ conversion_to_number = safe_parse_float(
149
+ get_region_lookup_value(LOOKUP_UNITS_NUMBER.get(term_type), country.get('@id'), grouping), 1
150
+ ) if term_units == Units.NUMBER.value else 1
145
151
 
146
152
  logRequirements(cycle, model=MODEL, term=term_id, key=MODEL_KEY, by='country',
147
153
  has_yield=has_yield,
@@ -161,7 +167,7 @@ def _should_run_product(product: dict): return product.get(MODEL_KEY) is None
161
167
 
162
168
 
163
169
  def run(cycle: dict):
164
- country_id = cycle.get('site', {}).get('country', {}).get('@id')
170
+ country = cycle.get('site', {}).get('country', {})
165
171
  end_date = safe_parse_date(cycle.get('endDate'))
166
172
  year = end_date.year if end_date else None
167
173
 
@@ -169,8 +175,8 @@ def run(cycle: dict):
169
175
  return non_empty_list([
170
176
  (
171
177
  (
172
- (_run_by_liveAnimal(cycle, p, country_id, year) if _should_run_liveAnimal(p) else None)
173
- or _run_by_country(cycle, p, country_id, year)
174
- ) if country_id else None
178
+ (_run_by_liveAnimal(cycle, p, country, year) if _should_run_liveAnimal(p) else None)
179
+ or _run_by_country(cycle, p, country, year)
180
+ ) if country else None
175
181
  ) for p in products
176
182
  ])
@@ -22,8 +22,8 @@ REQUIREMENTS = {
22
22
  }
23
23
  }
24
24
  LOOKUPS = {
25
- "region-animalProduct-animalProductGroupingFAO-productionQuantity": "production quantity",
26
- "region-animalProduct-animalProductGroupingFAO-head": "number of heads"
25
+ "region-animalProduct-animalProductGroupingFAO-productionQuantity": "",
26
+ "region-animalProduct-animalProductGroupingFAO-head": ""
27
27
  }
28
28
  RETURNS = {
29
29
  "Product": [{
@@ -1,4 +1,3 @@
1
- from numpy import recarray
2
1
  from hestia_earth.schema import TermTermType
3
2
  from hestia_earth.utils.api import download_hestia
4
3
  from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name, extract_grouped_data_closest_date
@@ -11,9 +10,11 @@ from hestia_earth.models.utils.animalProduct import (
11
10
  from hestia_earth.models.utils.product import convert_product_to_unit
12
11
  from hestia_earth.models.utils.impact_assessment import get_country_id, impact_end_year
13
12
  from hestia_earth.models.utils.indicator import _new_indicator
13
+ from hestia_earth.models.utils.lookup import get_region_lookup_value
14
14
  from . import MODEL
15
15
 
16
16
  LOOKUP_PREFIX = f"{TermTermType.REGION.value}-{TermTermType.ANIMALPRODUCT.value}-{FAO_LOOKUP_COLUMN}"
17
+ FAOSTAT_AREA_LOOKUP = 'region-faostatArea.csv'
17
18
 
18
19
 
19
20
  def get_liveAnimal_to_animalProduct_id(product_term_id: str, column: str, **log_args):
@@ -32,12 +33,10 @@ def product_equivalent_value(product: dict, year: int, country: str):
32
33
  if not grouping or not fao_product_id:
33
34
  return None
34
35
 
35
- lookup = download_lookup(f"{LOOKUP_PREFIX}-productionQuantity.csv")
36
- quantity_values = get_table_value(lookup, 'termid', country, column_name(grouping))
36
+ quantity_values = get_region_lookup_value(f"{LOOKUP_PREFIX}-productionQuantity.csv", country, grouping)
37
37
  quantity = safe_parse_float(extract_grouped_data_closest_date(quantity_values, year))
38
38
 
39
- lookup = download_lookup(f"{LOOKUP_PREFIX}-head.csv")
40
- head_values = get_table_value(lookup, 'termid', country, column_name(grouping))
39
+ head_values = get_region_lookup_value(f"{LOOKUP_PREFIX}-head.csv", country, grouping)
41
40
  head = safe_parse_float(extract_grouped_data_closest_date(head_values, year))
42
41
 
43
42
  # quantity is in Tonnes
@@ -64,11 +63,11 @@ def _split_delta(table_value: str, start_year: int, end_year: int):
64
63
  ]) else None
65
64
 
66
65
 
67
- def get_sum_of_columns(lookup: recarray, country: str, year: int, columns_list: list) -> float:
66
+ def get_sum_of_columns(country: str, year: int, columns_list: list) -> float:
68
67
  return sum(
69
68
  [safe_parse_float(
70
69
  extract_grouped_data_closest_date(
71
- data=get_table_value(lookup, 'termid', country, column_name(col)),
70
+ data=get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, col, model=MODEL),
72
71
  year=year
73
72
  )
74
73
  ) for col in columns_list]
@@ -76,9 +75,8 @@ def get_sum_of_columns(lookup: recarray, country: str, year: int, columns_list:
76
75
 
77
76
 
78
77
  def get_single_delta(country: str, start_year: int, end_year: int, column: str):
79
- lookup = download_lookup('region-faostatArea.csv')
80
78
  return _split_delta(
81
- get_table_value(lookup, 'termid', country, column_name(column)), start_year, end_year
79
+ get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, column, model=MODEL), start_year, end_year
82
80
  )
83
81
 
84
82
 
@@ -88,27 +86,24 @@ def get_land_ratio(
88
86
  """
89
87
  total_column is optional. Assumes that, if missing, total is the sum of values from first and second.
90
88
  """
91
- lookup = download_lookup('region-faostatArea.csv')
92
89
  first_delta = _split_delta(
93
- get_table_value(lookup, 'termid', country, column_name(first_column)), start_year, end_year
90
+ get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, first_column, model=MODEL), start_year, end_year
94
91
  )
95
92
  second_delta = _split_delta(
96
- get_table_value(lookup, 'termid', country, column_name(second_column)), start_year, end_year
93
+ get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, second_column, model=MODEL), start_year, end_year
97
94
  )
98
95
  total_delta = (
99
96
  get_sum_of_columns(
100
- lookup=lookup,
101
97
  country=country,
102
98
  year=end_year,
103
99
  columns_list=[first_column, second_column]
104
100
  ) - get_sum_of_columns(
105
- lookup=lookup,
106
101
  country=country,
107
102
  year=start_year,
108
103
  columns_list=[first_column, second_column]
109
104
  )
110
105
  ) if total_column is None else _split_delta(
111
- get_table_value(lookup, 'termid', country, column_name(total_column)), start_year, end_year
106
+ get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, total_column, model=MODEL), start_year, end_year
112
107
  )
113
108
 
114
109
  return (None, None, None) if any([
@@ -130,18 +125,11 @@ def get_cropland_ratio(country: str, start_year: int, end_year: int):
130
125
 
131
126
 
132
127
  def get_change_in_harvested_area_for_crop(country_id: str, crop_name: str, start_year: int, end_year: int = 0):
133
- lookup = download_lookup('region-crop-cropGroupingFaostatProduction-areaHarvested.csv')
134
- if end_year == 0 or end_year == start_year:
135
- return safe_parse_float(
136
- extract_grouped_data_closest_date(
137
- data=get_table_value(lookup, 'termid', country_id, column_name(crop_name)),
138
- year=start_year
139
- )
140
- )
141
- else:
142
- return _split_delta(
143
- get_table_value(lookup, 'termid', country_id, column_name(crop_name)), start_year, end_year
144
- )
128
+ lookup_name = 'region-crop-cropGroupingFaostatProduction-areaHarvested.csv'
129
+ value = get_region_lookup_value(lookup_name, country_id, crop_name)
130
+ return safe_parse_float(
131
+ extract_grouped_data_closest_date(value, start_year)
132
+ ) if end_year == 0 or end_year == start_year else _split_delta(value, start_year, end_year)
145
133
 
146
134
 
147
135
  def should_run_landTransformationFromCropland(term_id: str, impact: dict):
@@ -63,9 +63,11 @@ def _run(emissions: list):
63
63
 
64
64
 
65
65
  def _should_run(impact_assessment: dict):
66
- emissions = [emission for emission in filter_list_term_type(impact_assessment.get('emissionsResourceUse', []),
67
- TermTermType.EMISSION)
68
- if emission.get('term', {}).get('@id', '') in LOOKUPS[TermTermType.WASTE.value]]
66
+ emissions = [
67
+ emission
68
+ for emission in filter_list_term_type(impact_assessment.get('emissionsResourceUse', []), TermTermType.EMISSION)
69
+ if emission.get('term', {}).get('@id', '') in LOOKUPS[TermTermType.WASTE.value]
70
+ ]
69
71
 
70
72
  has_emissions = bool(emissions)
71
73
 
@@ -80,7 +82,7 @@ def _should_run(impact_assessment: dict):
80
82
  "input": input,
81
83
  "indicator-input-is-valid": _valid_waste(input),
82
84
  "value": _node_value(emission),
83
- "coefficient": get_table_value(array=download_lookup(filename="waste.csv"),
85
+ "coefficient": get_table_value(lookup=download_lookup(filename="waste.csv"),
84
86
  col_match='termid',
85
87
  col_match_with=input.get('@id'),
86
88
  col_val=column_name(emission['term']['@id'])) if input else None
@@ -89,9 +91,13 @@ def _should_run(impact_assessment: dict):
89
91
  ]
90
92
  )
91
93
 
92
- valid_emission_with_cf = [em for em in emissions_unpacked if em['coefficient'] is not None
93
- and em['indicator-is-valid'] is True
94
- and em['indicator-input-is-valid'] is True]
94
+ valid_emission_with_cf = [
95
+ em for em in emissions_unpacked if all([
96
+ em['coefficient'] is not None,
97
+ em['indicator-is-valid'] is True,
98
+ em['indicator-input-is-valid'] is True
99
+ ])
100
+ ]
95
101
 
96
102
  valid_input_requirements = all([
97
103
  all([
@@ -101,8 +107,9 @@ def _should_run(impact_assessment: dict):
101
107
  for em in emissions_unpacked
102
108
  ])
103
109
 
104
- all_emissions_have_known_cf = all([em['coefficient'] is not None for em in emissions_unpacked]) and bool(
105
- emissions_unpacked)
110
+ all_emissions_have_known_cf = all([
111
+ em['coefficient'] is not None for em in emissions_unpacked
112
+ ]) and bool(emissions_unpacked)
106
113
 
107
114
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
108
115
  has_emissions=has_emissions,
@@ -0,0 +1,60 @@
1
+ from hestia_earth.schema import MeasurementMethodClassification
2
+ from hestia_earth.utils.tools import safe_parse_float
3
+
4
+ from hestia_earth.models.log import logRequirements, logShouldRun
5
+ from hestia_earth.models.utils.measurement import _new_measurement
6
+ from hestia_earth.models.utils.source import get_source
7
+ from .utils import download, has_geospatial_data, should_download
8
+ from . import MODEL
9
+
10
+ REQUIREMENTS = {
11
+ "Site": {
12
+ "or": [
13
+ {"latitude": "", "longitude": ""},
14
+ {"boundary": {}},
15
+ {"region": {"@type": "Term", "termType": "region"}}
16
+ ]
17
+ }
18
+ }
19
+ RETURNS = {
20
+ "Measurement": [{
21
+ "value": "",
22
+ "methodClassification": "geospatial dataset"
23
+ }]
24
+ }
25
+ TERM_ID = 'altitude'
26
+ EE_PARAMS = {
27
+ 'collection': 'USGS/GMTED2010_FULL',
28
+ 'ee_type': 'raster',
29
+ 'band_name': 'med',
30
+ 'is_image': True
31
+ }
32
+ BIBLIO_TITLE = 'An Enhanced Global Elevation Model Generalized From Multiple Higher Resolution Source Datasets'
33
+
34
+
35
+ def _measurement(site: dict, value: float):
36
+ measurement = _new_measurement(TERM_ID)
37
+ measurement['value'] = [value]
38
+ measurement['methodClassification'] = MeasurementMethodClassification.GEOSPATIAL_DATASET.value
39
+ return measurement | get_source(site, BIBLIO_TITLE)
40
+
41
+
42
+ def _run(site: dict):
43
+ value = download(TERM_ID, site, EE_PARAMS)
44
+ return [_measurement(site, safe_parse_float(value))] if value is not None else []
45
+
46
+
47
+ def _should_run(site: dict):
48
+ contains_geospatial_data = has_geospatial_data(site)
49
+ below_max_area_size = should_download(TERM_ID, site)
50
+
51
+ logRequirements(site, model=MODEL, term=TERM_ID,
52
+ contains_geospatial_data=contains_geospatial_data,
53
+ below_max_area_size=below_max_area_size)
54
+
55
+ should_run = all([contains_geospatial_data, below_max_area_size])
56
+ logShouldRun(site, MODEL, TERM_ID, should_run)
57
+ return should_run
58
+
59
+
60
+ def run(site: dict): return _run(site) if _should_run(site) else []
@@ -65,7 +65,7 @@ def _should_run(cycle: dict):
65
65
 
66
66
 
67
67
  def run(cycle: dict):
68
- sites = get_allowed_sites(MODEL, TERM_ID, TermTermType.LANDUSEMANAGEMENT, cycle) if _should_run(cycle) else []
68
+ sites = get_allowed_sites(MODEL, TERM_ID, cycle) if _should_run(cycle) else []
69
69
  sites = [
70
70
  (site, get_region_factor(TERM_ID, site, TermTermType.LANDUSEMANAGEMENT)) for site in sites
71
71
  ]
@@ -79,7 +79,7 @@ def _run_default(site: dict):
79
79
  region_factor=region_factor)
80
80
 
81
81
  should_run = all([region_factor])
82
- logShouldRun(site, MODEL, TERM_ID, should_run)
82
+ logShouldRun(site, MODEL, TERM_ID, should_run, run_by='Lookup')
83
83
  return [_measurement(site, round(region_factor))] if should_run else []
84
84
 
85
85
 
@@ -92,7 +92,7 @@ def _should_run(site: dict):
92
92
  below_max_area_size=below_max_area_size)
93
93
 
94
94
  should_run = all([contains_geospatial_data, below_max_area_size])
95
- logShouldRun(site, MODEL, TERM_ID, should_run)
95
+ logShouldRun(site, MODEL, TERM_ID, should_run, run_by='Earth Engine')
96
96
  return should_run
97
97
 
98
98
 
@@ -65,7 +65,7 @@ def _should_run(cycle: dict):
65
65
 
66
66
 
67
67
  def run(cycle: dict):
68
- sites = get_allowed_sites(MODEL, TERM_ID, TermTermType.LANDUSEMANAGEMENT, cycle) if _should_run(cycle) else []
68
+ sites = get_allowed_sites(MODEL, TERM_ID, cycle) if _should_run(cycle) else []
69
69
  sites = [
70
70
  (site, get_region_factor(TERM_ID, site, TermTermType.LANDUSEMANAGEMENT)) for site in sites
71
71
  ]
@@ -196,4 +196,7 @@ def download(term: str, site: dict, data: dict, only_coordinates=False) -> dict:
196
196
  def get_region_factor(term_id: str, site: dict, termType: TermTermType = TermTermType.MEASUREMENT):
197
197
  region_id = region_level_1_id(site.get('region', {}).get('@id'))
198
198
  country_id = site.get('country', {}).get('@id')
199
- return region_factor(MODEL, region_id, term_id, termType) or region_factor(MODEL, country_id, term_id, termType)
199
+ return (
200
+ # `region-measurement` only exists for countries
201
+ region_factor(MODEL, region_id, term_id, termType) if termType != TermTermType.MEASUREMENT else None
202
+ ) or region_factor(MODEL, country_id, term_id, termType)
@@ -1,11 +1,10 @@
1
1
  from hestia_earth.schema import CycleFunctionalUnit, TermTermType
2
- from hestia_earth.utils.api import download_hestia
3
2
  from hestia_earth.utils.model import find_term_match, filter_list_term_type
4
3
  from hestia_earth.utils.tools import list_sum, non_empty_list, safe_parse_float
5
4
 
6
5
  from hestia_earth.models.log import logRequirements, logShouldRun
7
6
  from hestia_earth.models.utils.property import _new_property, node_has_no_property
8
- from hestia_earth.models.utils.term import get_irrigation_terms
7
+ from hestia_earth.models.utils.term import get_irrigation_terms, download_term
9
8
  from hestia_earth.models.utils.crop import get_crop_lookup_value
10
9
  from hestia_earth.models.utils.completeness import _is_term_type_complete
11
10
  from . import MODEL
@@ -81,7 +80,7 @@ def _should_run_product(cycle: dict):
81
80
 
82
81
 
83
82
  def _run_cycle(products: list):
84
- term = download_hestia(TERM_ID)
83
+ term = download_term(TERM_ID, TermTermType.PROPERTY)
85
84
 
86
85
  def run_product(values: tuple):
87
86
  product, value = values
@@ -10,7 +10,7 @@ from hestia_earth.utils.api import download_hestia
10
10
  from hestia_earth.utils.tools import non_empty_list
11
11
 
12
12
  from hestia_earth.models.log import logRequirements, logShouldRun, debugValues
13
- from hestia_earth.models.utils import _include_methodModel
13
+ from hestia_earth.models.utils.method import include_methodModel
14
14
  from .. import MODEL
15
15
 
16
16
  REQUIREMENTS = {
@@ -39,8 +39,8 @@ MODEL_KEY = 'distance'
39
39
 
40
40
  def _run_transport(cycle: dict, distance_kms: float):
41
41
  def exec(transport: dict):
42
- return _include_methodModel({
43
- **transport, MODEL_KEY: distance_kms
42
+ return include_methodModel(transport | {
43
+ MODEL_KEY: distance_kms
44
44
  }, MODEL) if _should_run_transport(cycle, transport) else transport
45
45
  return exec
46
46