hestia-earth-models 0.69.1__py3-none-any.whl → 0.70.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 (219) hide show
  1. hestia_earth/models/aware/scarcityWeightedWaterUse.py +8 -16
  2. hestia_earth/models/cache_sites.py +3 -2
  3. hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +2 -1
  4. hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +3 -2
  5. hestia_earth/models/config/Cycle.json +82 -60
  6. hestia_earth/models/config/ImpactAssessment.json +12 -4
  7. hestia_earth/models/config/Site.json +33 -22
  8. hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +1 -1
  9. hestia_earth/models/cycle/animal/input/properties.py +1 -1
  10. hestia_earth/models/cycle/cycleDuration.py +2 -2
  11. hestia_earth/models/cycle/input/hestiaAggregatedData.py +12 -14
  12. hestia_earth/models/cycle/input/properties.py +1 -1
  13. hestia_earth/models/cycle/siteDuration.py +3 -3
  14. hestia_earth/models/cycle/transformation.py +1 -1
  15. hestia_earth/models/cycle/utils.py +0 -6
  16. hestia_earth/models/data/ecoinventV3/__init__.py +15 -13
  17. hestia_earth/models/ecoalimV9/__init__.py +13 -0
  18. hestia_earth/models/ecoalimV9/cycle.py +128 -0
  19. hestia_earth/models/ecoalimV9/impact_assessment.py +125 -0
  20. hestia_earth/models/ecoalimV9/utils.py +31 -0
  21. hestia_earth/models/ecoinventV3/__init__.py +6 -14
  22. hestia_earth/models/ecoinventV3/utils.py +1 -29
  23. hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +8 -2
  24. hestia_earth/models/emissionNotRelevant/__init__.py +33 -8
  25. hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +1 -1
  26. hestia_earth/models/geospatialDatabase/croppingIntensity.py +4 -4
  27. hestia_earth/models/geospatialDatabase/longFallowRatio.py +4 -4
  28. hestia_earth/models/geospatialDatabase/region.py +3 -2
  29. hestia_earth/models/geospatialDatabase/utils.py +6 -5
  30. hestia_earth/models/haversineFormula/transport/distance.py +5 -4
  31. hestia_earth/models/{koble2014 → hestia}/aboveGroundCropResidue.py +4 -5
  32. hestia_earth/models/{cycle → hestia}/aboveGroundCropResidueTotal.py +2 -2
  33. hestia_earth/models/{site → hestia}/brackishWater.py +1 -1
  34. hestia_earth/models/{site → hestia}/cationExchangeCapacityPerKgSoil.py +1 -1
  35. hestia_earth/models/{cycle → hestia}/coldCarcassWeightPerHead.py +1 -1
  36. hestia_earth/models/{cycle → hestia}/coldDressedCarcassWeightPerHead.py +1 -1
  37. hestia_earth/models/{cycle → hestia}/concentrateFeed.py +1 -1
  38. hestia_earth/models/{cycle → hestia}/cropResidueManagement.py +1 -1
  39. hestia_earth/models/{cycle → hestia}/croppingIntensity.py +1 -1
  40. hestia_earth/models/{cycle → hestia}/energyContentLowerHeatingValue.py +2 -2
  41. hestia_earth/models/{cycle → hestia}/excretaKgMass.py +7 -2
  42. hestia_earth/models/{cycle → hestia}/excretaKgN.py +1 -1
  43. hestia_earth/models/{cycle → hestia}/excretaKgVs.py +1 -1
  44. hestia_earth/models/{cycle → hestia}/feedConversionRatio/__init__.py +1 -1
  45. hestia_earth/models/{site → hestia}/flowingWater.py +1 -1
  46. hestia_earth/models/{site → hestia}/freshWater.py +1 -1
  47. hestia_earth/models/{cycle → hestia}/inorganicFertiliser.py +1 -1
  48. hestia_earth/models/{cycle → hestia}/irrigatedTypeUnspecified.py +14 -19
  49. hestia_earth/models/hestia/landCover.py +31 -27
  50. hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +2 -1
  51. hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +2 -1
  52. hestia_earth/models/{cycle → hestia}/liveAnimal.py +1 -1
  53. hestia_earth/models/{cycle → hestia}/longFallowRatio.py +1 -1
  54. hestia_earth/models/{site → hestia}/management.py +5 -3
  55. hestia_earth/models/{cycle → hestia}/materialAndSubstrate.py +1 -1
  56. hestia_earth/models/{cycle → hestia}/milkYield.py +1 -1
  57. hestia_earth/models/{site → hestia}/netPrimaryProduction.py +1 -1
  58. hestia_earth/models/{site → hestia}/organicCarbonPerHa.py +1 -1
  59. hestia_earth/models/{cycle → hestia}/pastureGrass.py +1 -1
  60. hestia_earth/models/{cycle → hestia}/pastureSystem.py +1 -1
  61. hestia_earth/models/{site → hestia}/potentialEvapotranspirationAnnual.py +3 -3
  62. hestia_earth/models/{site → hestia}/potentialEvapotranspirationMonthly.py +3 -3
  63. hestia_earth/models/{site → hestia}/precipitationAnnual.py +3 -3
  64. hestia_earth/models/{site → hestia}/precipitationMonthly.py +3 -3
  65. hestia_earth/models/{site → hestia}/rainfallAnnual.py +3 -3
  66. hestia_earth/models/{site → hestia}/rainfallMonthly.py +3 -3
  67. hestia_earth/models/{cycle → hestia}/readyToCookWeightPerHead.py +1 -1
  68. hestia_earth/models/{cycle → hestia}/residueBurnt.py +1 -1
  69. hestia_earth/models/{cycle → hestia}/residueIncorporated.py +1 -1
  70. hestia_earth/models/{cycle → hestia}/residueLeftOnField.py +1 -1
  71. hestia_earth/models/hestia/residueRemoved.py +65 -13
  72. hestia_earth/models/{site → hestia}/salineWater.py +1 -1
  73. hestia_earth/models/hestia/seed_emissions.py +1 -1
  74. hestia_earth/models/{site → hestia}/soilMeasurement.py +1 -1
  75. hestia_earth/models/{cycle → hestia}/stockingDensityAnimalHousingAverage.py +1 -1
  76. hestia_earth/models/{site → hestia}/temperatureAnnual.py +3 -3
  77. hestia_earth/models/{site → hestia}/temperatureMonthly.py +3 -3
  78. hestia_earth/models/{site → hestia}/totalNitrogenPerKgSoil.py +1 -1
  79. hestia_earth/models/{cycle → hestia}/unknownPreSeasonWaterRegime.py +1 -1
  80. hestia_earth/models/hestia/utils.py +93 -0
  81. hestia_earth/models/{site → hestia}/waterDepth.py +1 -1
  82. hestia_earth/models/hestia/waterSalinity.py +78 -0
  83. hestia_earth/models/impact_assessment/emissions.py +1 -1
  84. hestia_earth/models/impact_assessment/product/economicValueShare.py +1 -1
  85. hestia_earth/models/impact_assessment/product/value.py +1 -1
  86. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +1 -1
  87. hestia_earth/models/ipcc2019/animal/fatContent.py +2 -2
  88. hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +2 -2
  89. hestia_earth/models/ipcc2019/animal/trueProteinContent.py +2 -2
  90. hestia_earth/models/ipcc2019/belowGroundBiomass.py +1 -1
  91. hestia_earth/models/ipcc2019/biomass_utils.py +2 -4
  92. hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +7 -2
  93. hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +163 -78
  94. hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +1 -0
  95. hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +2 -1
  96. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +31 -20
  97. hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +2 -1
  98. hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +16 -9
  99. hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +36 -47
  100. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +94 -9
  101. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py +167 -13
  102. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +7 -5
  103. hestia_earth/models/koble2014/cropResidueManagement.py +1 -1
  104. hestia_earth/models/koble2014/residueBurnt.py +1 -1
  105. hestia_earth/models/koble2014/residueRemoved.py +1 -1
  106. hestia_earth/models/koble2014/utils.py +3 -3
  107. hestia_earth/models/mocking/search-results.json +1263 -1229
  108. hestia_earth/models/pooreNemecek2018/excretaKgN.py +1 -1
  109. hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py +1 -1
  110. hestia_earth/models/pooreNemecek2018/utils.py +12 -3
  111. hestia_earth/models/schmidt2007/ch4ToAirWasteTreatment.py +1 -6
  112. hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +1 -6
  113. hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +1 -6
  114. hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +1 -6
  115. hestia_earth/models/site/pre_checks/country.py +4 -2
  116. hestia_earth/models/transformation/input/excreta.py +1 -1
  117. hestia_earth/models/utils/aggregated.py +12 -15
  118. hestia_earth/models/utils/background_emissions.py +52 -0
  119. hestia_earth/models/utils/blank_node.py +24 -6
  120. hestia_earth/models/utils/impact_assessment.py +26 -17
  121. hestia_earth/models/utils/lookup.py +48 -39
  122. hestia_earth/models/utils/measurement.py +3 -3
  123. hestia_earth/models/utils/product.py +1 -1
  124. hestia_earth/models/utils/source.py +2 -1
  125. hestia_earth/models/utils/term.py +26 -1
  126. hestia_earth/models/version.py +1 -1
  127. {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.1.dist-info}/METADATA +2 -2
  128. {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.1.dist-info}/RECORD +214 -209
  129. tests/models/aware/test_scarcityWeightedWaterUse.py +1 -12
  130. tests/models/cycle/input/test_hestiaAggregatedData.py +18 -16
  131. tests/models/ecoalimV9/__init__.py +0 -0
  132. tests/models/ecoalimV9/test_cycle.py +21 -0
  133. tests/models/ecoalimV9/test_impact_assessment.py +24 -0
  134. tests/models/environmentalFootprintV3_1/test_scarcityWeightedWaterUse.py +4 -2
  135. tests/models/geospatialDatabase/test_region.py +1 -1
  136. tests/models/geospatialDatabase/test_utils.py +1 -1
  137. tests/models/haversineFormula/transport/test_distance.py +2 -2
  138. tests/models/{koble2014 → hestia}/test_aboveGroundCropResidue.py +3 -3
  139. tests/models/{cycle → hestia}/test_aboveGroundCropResidueTotal.py +1 -1
  140. tests/models/{site → hestia}/test_brackishWater.py +1 -1
  141. tests/models/{site → hestia}/test_cationExchangeCapacityPerKgSoil.py +1 -1
  142. tests/models/{cycle → hestia}/test_coldCarcassWeightPerHead.py +1 -1
  143. tests/models/{cycle → hestia}/test_coldDressedCarcassWeightPerHead.py +1 -1
  144. tests/models/{cycle → hestia}/test_concentrateFeed.py +1 -1
  145. tests/models/{cycle → hestia}/test_cropResidueManagement.py +1 -1
  146. tests/models/{cycle → hestia}/test_croppingIntensity.py +1 -1
  147. tests/models/{cycle → hestia}/test_energyContentLowerHeatingValue.py +5 -3
  148. tests/models/{cycle → hestia}/test_excretaKgMass.py +1 -1
  149. tests/models/{cycle → hestia}/test_excretaKgN.py +1 -1
  150. tests/models/{cycle → hestia}/test_excretaKgVs.py +1 -1
  151. tests/models/{cycle → hestia}/test_feedConversionRatio.py +1 -1
  152. tests/models/{site → hestia}/test_flowingWater.py +1 -1
  153. tests/models/{site → hestia}/test_freshWater.py +1 -1
  154. tests/models/{cycle → hestia}/test_inorganicFertiliser.py +1 -1
  155. tests/models/{cycle → hestia}/test_irrigatedTypeUnspecified.py +2 -5
  156. tests/models/hestia/test_landCover.py +4 -34
  157. tests/models/{cycle → hestia}/test_liveAnimal.py +1 -1
  158. tests/models/{cycle → hestia}/test_longFallowRatio.py +1 -1
  159. tests/models/{site → hestia}/test_management.py +1 -1
  160. tests/models/{cycle → hestia}/test_materialsAndSubstrate.py +1 -1
  161. tests/models/{cycle → hestia}/test_milkYield.py +1 -1
  162. tests/models/{site → hestia}/test_netPrimaryProduction.py +1 -1
  163. tests/models/{site → hestia}/test_organicCarbonPerHa.py +1 -1
  164. tests/models/{site → hestia}/test_organicCarbonPerKgSoil.py +1 -1
  165. tests/models/{site → hestia}/test_organicCarbonPerM3Soil.py +1 -1
  166. tests/models/{site → hestia}/test_organicMatterPerKgSoil.py +1 -1
  167. tests/models/{site → hestia}/test_organicMatterPerM3Soil.py +1 -1
  168. tests/models/{cycle → hestia}/test_pastureGrass.py +1 -1
  169. tests/models/{cycle → hestia}/test_pastureSystem.py +1 -1
  170. tests/models/{site → hestia}/test_potentialEvapotranspirationAnnual.py +1 -1
  171. tests/models/{site → hestia}/test_potentialEvapotranspirationMonthly.py +1 -1
  172. tests/models/{site → hestia}/test_precipitationAnnual.py +1 -1
  173. tests/models/{site → hestia}/test_precipitationMonthly.py +1 -1
  174. tests/models/{site → hestia}/test_rainfallAnnual.py +1 -1
  175. tests/models/{site → hestia}/test_rainfallMonthly.py +1 -1
  176. tests/models/{cycle → hestia}/test_readyToCookWeightPerHead.py +1 -1
  177. tests/models/{cycle → hestia}/test_residueBurnt.py +1 -1
  178. tests/models/{cycle → hestia}/test_residueIncorporated.py +1 -1
  179. tests/models/{cycle → hestia}/test_residueLeftOnField.py +1 -1
  180. tests/models/hestia/test_residueRemoved.py +15 -3
  181. tests/models/{site → hestia}/test_salineWater.py +1 -1
  182. tests/models/{site → hestia}/test_soilMeasurement.py +2 -2
  183. tests/models/{cycle → hestia}/test_stockingDensityAnimalHousingAverage.py +1 -1
  184. tests/models/{site → hestia}/test_temperatureAnnual.py +1 -1
  185. tests/models/{site → hestia}/test_temperatureMonthly.py +1 -1
  186. tests/models/{site → hestia}/test_totalNitrogenPerKgSoil.py +1 -1
  187. tests/models/{cycle → hestia}/test_unknownPreSeasonWaterRegime.py +1 -1
  188. tests/models/{site → hestia}/test_waterDepth.py +1 -1
  189. tests/models/hestia/test_waterSalinity.py +26 -0
  190. tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +11 -0
  191. tests/models/ipcc2019/test_ch4ToAirFloodedRice.py +10 -42
  192. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +2 -1
  193. tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +22 -8
  194. tests/models/ipcc2019/test_organicCarbonPerHa.py +4 -2
  195. tests/models/pooreNemecek2018/test_landOccupationDuringCycle.py +3 -0
  196. tests/models/site/pre_checks/test_country.py +4 -3
  197. tests/models/test_ecoinventV3.py +2 -2
  198. tests/models/test_ecoinventV3AndEmberClimate.py +2 -2
  199. tests/models/test_emissionNotRelevant.py +0 -8
  200. tests/models/utils/test_measurement.py +1 -1
  201. tests/models/utils/test_source.py +15 -5
  202. tests/orchestrator/test_models.py +1 -0
  203. hestia_earth/models/cycle/residueRemoved.py +0 -54
  204. hestia_earth/models/hestia/nh3ToSurfaceWaterAquacultureSystems.py +0 -64
  205. hestia_earth/models/site/utils.py +0 -93
  206. tests/models/cycle/test_residueRemoved.py +0 -37
  207. tests/models/hestia/test_nh3ToSurfaceWaterAquacultureSystems.py +0 -51
  208. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioCarbon.py +0 -0
  209. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioDryMatter.py +0 -0
  210. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioEnergy.py +0 -0
  211. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioFedWeight.py +0 -0
  212. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioNitrogen.py +0 -0
  213. /hestia_earth/models/{site → hestia}/organicCarbonPerKgSoil.py +0 -0
  214. /hestia_earth/models/{site → hestia}/organicCarbonPerM3Soil.py +0 -0
  215. /hestia_earth/models/{site → hestia}/organicMatterPerKgSoil.py +0 -0
  216. /hestia_earth/models/{site → hestia}/organicMatterPerM3Soil.py +0 -0
  217. {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.1.dist-info}/LICENSE +0 -0
  218. {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.1.dist-info}/WHEEL +0 -0
  219. {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.1.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,7 @@ REQUIREMENTS = {
15
15
  "inputs": [{
16
16
  "@type": "Input",
17
17
  "or": {
18
- "impactAssessment": "",
18
+ "impactAssessment": {"@type": "ImpactAssessment"},
19
19
  "properties": [{"@type": "Property", "@id": "dryMatter"}]
20
20
  }
21
21
  }]
@@ -11,11 +11,11 @@ REQUIREMENTS = {
11
11
  "endDate": "",
12
12
  "optional": {
13
13
  "startDate": "",
14
- "products": {
14
+ "products": [{
15
15
  "@type": "Product",
16
16
  "primary": "True",
17
17
  "term.termType": "crop"
18
- },
18
+ }],
19
19
  "practices": [{"@type": "Practice", "value": "", "term.@id": "croppingIntensity"}]
20
20
  }
21
21
  }
@@ -1,12 +1,11 @@
1
1
  from hestia_earth.schema import TermTermType
2
- from hestia_earth.utils.api import download_hestia
3
2
  from hestia_earth.utils.model import find_primary_product, linked_node, filter_list_term_type
4
3
  from hestia_earth.utils.tools import non_empty_list
5
4
 
6
5
  from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
7
6
  from hestia_earth.models.utils.crop import valid_site_type
8
7
  from hestia_earth.models.utils.blank_node import get_lookup_value
9
- from hestia_earth.models.utils.term import get_generic_crop
8
+ from hestia_earth.models.utils.term import get_generic_crop, download_term
10
9
  from hestia_earth.models.utils.aggregated import (
11
10
  should_link_input_to_impact, link_inputs_to_impact, find_closest_impact, aggregated_end_date
12
11
  )
@@ -17,7 +16,7 @@ REQUIREMENTS = {
17
16
  "@type": "Input",
18
17
  "value": "",
19
18
  "none": {
20
- "impactAssessment": "",
19
+ "impactAssessment": {"@type": "ImpactAssessment"},
21
20
  "fromCycle": "True",
22
21
  "producedInCycle": "True"
23
22
  },
@@ -37,7 +36,7 @@ REQUIREMENTS = {
37
36
  "term.@id": "seed",
38
37
  "value": "",
39
38
  "none": {
40
- "impactAssessment": ""
39
+ "impactAssessment": {"@type": "ImpactAssessment"}
41
40
  }
42
41
  }],
43
42
  "products": [{"@type": "Product", "value": "", "primary": "True"}]
@@ -58,8 +57,7 @@ MODEL_KEY = 'impactAssessment'
58
57
 
59
58
 
60
59
  def _run_seed(cycle: dict, primary_product: dict, seed_input: dict, product_term_id: str):
61
- product = download_hestia(product_term_id)
62
- region = seed_input.get('region')
60
+ product = download_term(product_term_id, TermTermType.SEED)
63
61
  country = seed_input.get('country')
64
62
  # to avoid double counting seed => aggregated impact => seed, we need to get the impact of the previous decade
65
63
  # if the data does not exist, use the aggregated impact of generic crop instead
@@ -68,16 +66,16 @@ def _run_seed(cycle: dict, primary_product: dict, seed_input: dict, product_term
68
66
  default_product = get_generic_crop()
69
67
 
70
68
  impact = (
71
- find_closest_impact(cycle, date, product, region, country, match_end_date) or
72
- find_closest_impact(cycle, date, primary_product.get('term', {}), region, country, match_end_date) or
73
- find_closest_impact(cycle, date, default_product, region, country)
69
+ find_closest_impact(cycle, date, product, country, must_queries=match_end_date) or
70
+ find_closest_impact(cycle, date, primary_product.get('term', {}), country, must_queries=match_end_date) or
71
+ find_closest_impact(cycle, date, default_product, country)
74
72
  )
75
73
 
76
74
  search_by_product_term_id = (product or primary_product or default_product).get('@id')
77
- search_by_region_id = (region or country or {}).get('@id') or 'region-world'
75
+ search_by_country_id = (country or {}).get('@id') or 'region-world'
78
76
  debugValues(cycle, model=MODEL_ID, term=seed_input.get('term', {}).get('@id'), key=MODEL_KEY,
79
77
  search_by_product_term_id=search_by_product_term_id,
80
- search_by_region_id=search_by_region_id,
78
+ search_by_country_id=search_by_country_id,
81
79
  search_by_end_date=str(date),
82
80
  impact_assessment_id_found=(impact or {}).get('@id'))
83
81
 
@@ -95,7 +93,7 @@ def _should_run_seed(cycle: dict):
95
93
  seed_inputs = [
96
94
  {
97
95
  'input': seed_input,
98
- 'product': get_lookup_value(seed_input.get('term', {}), LOOKUPS['seed'], key=MODEL_KEY)
96
+ 'product-id': get_lookup_value(seed_input.get('term', {}), LOOKUPS['seed'], key=MODEL_KEY)
99
97
  }
100
98
  for seed_input in seed_inputs
101
99
  ]
@@ -104,7 +102,7 @@ def _should_run_seed(cycle: dict):
104
102
 
105
103
  for seed_input in seed_inputs:
106
104
  term_id = seed_input.get('input').get('term', {}).get('@id')
107
- linked_product_id = seed_input.get('product')
105
+ linked_product_id = seed_input.get('product-id')
108
106
 
109
107
  logRequirements(cycle, model=MODEL_ID, term=term_id, key=MODEL_KEY,
110
108
  site_type_valid=site_type_valid,
@@ -140,7 +138,7 @@ def run(cycle: dict):
140
138
  link_inputs_to_impact(MODEL_ID, cycle, inputs) if should_run else []
141
139
  ) + (
142
140
  non_empty_list([
143
- _run_seed(cycle, primary_product, seed_input.get('input'), seed_input.get('product'))
141
+ _run_seed(cycle, primary_product, seed_input.get('input'), seed_input.get('product-id'))
144
142
  for seed_input in seed_inputs
145
143
  ]) if should_run_seed else []
146
144
  )
@@ -12,7 +12,7 @@ REQUIREMENTS = {
12
12
  "inputs": [{
13
13
  "@type": "Input",
14
14
  "or": {
15
- "impactAssessment": "",
15
+ "impactAssessment": {"@type": "ImpactAssessment"},
16
16
  "properties": [{"@type": "Property", "@id": "dryMatter"}]
17
17
  }
18
18
  }]
@@ -9,14 +9,14 @@ REQUIREMENTS = {
9
9
  "Cycle": {
10
10
  "cycleDuration": "> 0",
11
11
  "none": {
12
- "otherSites": ""
12
+ "otherSites": [{"@type": "Site"}]
13
13
  },
14
14
  "optional": {
15
- "products": {
15
+ "products": [{
16
16
  "@type": "Product",
17
17
  "primary": "True",
18
18
  "term.termType": "crop"
19
- },
19
+ }],
20
20
  "startDateDefinition": ""
21
21
  }
22
22
  }
@@ -25,7 +25,7 @@ def _run_emission(cycle: dict, transformation: dict):
25
25
  def exec(emission: dict):
26
26
  term_id = emission.get('term', {}).get('@id')
27
27
  logShouldRun(cycle, MODEL_LOG, term_id, True, key=MODEL_KEY)
28
- return {**emission, MODEL_KEY: transformation.get('term', {})}
28
+ return emission | {MODEL_KEY: transformation.get('term', {})}
29
29
  return exec
30
30
 
31
31
 
@@ -1,15 +1,9 @@
1
1
  from hestia_earth.utils.tools import list_average
2
2
 
3
3
  from hestia_earth.models.log import logShouldRun
4
- from hestia_earth.models.utils.term import get_lookup_value
5
4
  from . import MODEL
6
5
 
7
6
 
8
- def get_liveAnimal_term_id(product: dict, **log_ars):
9
- term_id = get_lookup_value(product.get('term', {}), 'liveAnimalTermId', model=MODEL, **log_ars)
10
- return term_id.split(';')[0] if term_id else None
11
-
12
-
13
7
  def _should_run_property_by_min_max(property: dict):
14
8
  return all([
15
9
  property.get('min') is not None,
@@ -1,32 +1,34 @@
1
1
  import os
2
- from hestia_earth.utils.lookup import column_name, get_table_value, load_lookup
2
+ from functools import lru_cache
3
+ from hestia_earth.utils.lookup import column_name, get_table_value, load_lookup, lookup_columns
3
4
  from hestia_earth.utils.tools import non_empty_list
4
5
 
5
6
  from hestia_earth.models.log import logger
6
7
 
7
8
  CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
8
- ECOINVENT_FILEPATH = os.getenv('ECOINVENT_V3_FILEPATH', f"{os.path.join(CURRENT_DIR, 'ecoinventV3_excerpt')}.csv")
9
+ _FILEPATH = os.getenv('ECOINVENT_V3_FILEPATH', f"{os.path.join(CURRENT_DIR, 'ecoinventV3_excerpt')}.csv")
9
10
 
10
11
 
12
+ @lru_cache()
11
13
  def _get_file():
12
- if not os.path.exists(ECOINVENT_FILEPATH):
13
- logger.warn('Ecoinvent file not found. Please make sure to set env variable "ECOINVENT_V3_FILEPATH".')
14
+ if not os.path.exists(_FILEPATH):
15
+ logger.warning('Ecoinvent file not found. Please make sure to set env variable "ECOINVENT_V3_FILEPATH".')
14
16
  return None
15
17
 
16
- return load_lookup(filepath=ECOINVENT_FILEPATH, keep_in_memory=True)
18
+ return load_lookup(filepath=_FILEPATH, keep_in_memory=True)
17
19
 
18
20
 
19
21
  def ecoinventV3_emissions(ecoinventName: str):
20
22
  lookup = _get_file()
21
23
  col_name = column_name('ecoinventName')
22
24
 
23
- def emission(index: int):
24
- id = get_table_value(
25
- lookup, col_name, ecoinventName, column_name(f"emissionsResourceUse.{index}.term.id")
26
- )
27
- value = get_table_value(
28
- lookup, col_name, ecoinventName, column_name(f"emissionsResourceUse.{index}.value")
29
- )
25
+ def emission(column: str):
26
+ id = get_table_value(lookup, col_name, ecoinventName, column_name(column))
27
+ value = get_table_value(lookup, col_name, ecoinventName, column_name(column.replace('termid', 'value')))
30
28
  return (id, value) if id else None
31
29
 
32
- return non_empty_list(map(emission, range(0, 12)))
30
+ columns = [
31
+ col for col in lookup_columns(lookup)
32
+ if col.endswith(column_name('termid'))
33
+ ]
34
+ return non_empty_list(map(emission, columns))
@@ -0,0 +1,13 @@
1
+ from os.path import dirname, abspath
2
+ import sys
3
+ from importlib import import_module
4
+
5
+ from hestia_earth.models.utils.blank_node import run_if_required
6
+
7
+ CURRENT_DIR = dirname(abspath(__file__)) + '/'
8
+ sys.path.append(CURRENT_DIR)
9
+ MODEL = 'ecoalimV9'
10
+ PKG = '.'.join(['hestia_earth', 'models', MODEL])
11
+
12
+
13
+ def run(model: str, data): return run_if_required(MODEL, model, data, import_module(f".{model}", package=PKG))
@@ -0,0 +1,128 @@
1
+ from functools import reduce
2
+ from statistics import mean
3
+ from hestia_earth.schema import EmissionMethodTier
4
+ from hestia_earth.utils.tools import flatten, list_sum
5
+
6
+ from hestia_earth.models.log import debugValues, logShouldRun, logRequirements
7
+ from hestia_earth.models.utils.emission import _new_emission
8
+ from hestia_earth.models.utils.background_emissions import get_background_inputs, no_gap_filled_background_emissions
9
+ from hestia_earth.models.utils.blank_node import group_by_keys
10
+ from .utils import get_input_mappings, ecoalim_values
11
+ from . import MODEL
12
+
13
+ REQUIREMENTS = {
14
+ "Cycle": {
15
+ "inputs": [{
16
+ "@type": "Input",
17
+ "value": "> 0",
18
+ "none": {
19
+ "fromCycle": "True",
20
+ "producedInCycle": "True"
21
+ }
22
+ }],
23
+ "optional": {
24
+ "animals": [{
25
+ "@type": "Animal",
26
+ "inputs": [{
27
+ "@type": "Input",
28
+ "value": "> 0",
29
+ "none": {
30
+ "fromCycle": "True",
31
+ "producedInCycle": "True"
32
+ }
33
+ }]
34
+ }]
35
+ }
36
+ }
37
+ }
38
+ RETURNS = {
39
+ "Emission": [{
40
+ "term": "",
41
+ "value": "",
42
+ "methodTier": "background",
43
+ "inputs": "",
44
+ "operation": "",
45
+ "animals": ""
46
+ }]
47
+ }
48
+ LOOKUPS = {
49
+ "ecoalim-emissionsResourceUse": "emission-",
50
+ "crop": "ecoalimMapping",
51
+ "processedFood": "ecoalimMapping",
52
+ "animalProduct": "ecoalimMapping",
53
+ "forage": "ecoalimMapping",
54
+ "feedFoodAdditive": "ecoalimMapping"
55
+ }
56
+ MODEL_KEY = 'cycle'
57
+ TIER = EmissionMethodTier.BACKGROUND.value
58
+
59
+
60
+ def _emission(term_id: str, value: float, input: dict):
61
+ emission = _new_emission(term_id, MODEL)
62
+ emission['value'] = [value]
63
+ emission['methodTier'] = TIER
64
+ emission['inputs'] = [input.get('term')]
65
+ if input.get('operation'):
66
+ emission['operation'] = input.get('operation')
67
+ if input.get('animal'):
68
+ emission['animals'] = [input.get('animal')]
69
+ return emission
70
+
71
+
72
+ def _add_emission(cycle: dict, input: dict):
73
+ input_term_id = input.get('term', {}).get('@id')
74
+ operation_term_id = input.get('operation', {}).get('@id')
75
+ animal_term_id = input.get('animal', {}).get('@id')
76
+
77
+ def add(prev: dict, mapping: tuple):
78
+ gadm_id, ecoalim_key = mapping
79
+ # all countries have the same coefficient
80
+ coefficient = 1
81
+ emissions = ecoalim_values(ecoalim_key, 'emission')
82
+ for emission_term_id, value in emissions:
83
+ # log run on each emission so we know it did run
84
+ debugValues(cycle, model=MODEL, term=emission_term_id, model_key=MODEL_KEY,
85
+ value=value,
86
+ coefficient=coefficient,
87
+ input=input_term_id,
88
+ operation=operation_term_id,
89
+ animal=animal_term_id)
90
+ prev[emission_term_id] = prev.get(emission_term_id, []) + [value * coefficient]
91
+ return prev
92
+ return add
93
+
94
+
95
+ def _run_input(cycle: dict):
96
+ no_gap_filled_background_emissions_func = no_gap_filled_background_emissions(cycle)
97
+
98
+ def run(inputs: list):
99
+ input = inputs[0]
100
+ input_term_id = input.get('term', {}).get('@id')
101
+ input_value = list_sum(flatten(input.get('value', []) for input in inputs))
102
+ mappings = get_input_mappings(MODEL, input)
103
+ has_mappings = len(mappings) > 0
104
+
105
+ # skip input that has background emissions we have already gap-filled (model run before)
106
+ has_no_gap_filled_background_emissions = no_gap_filled_background_emissions_func(input)
107
+
108
+ logRequirements(cycle, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
109
+ has_ecoalim_mappings=has_mappings,
110
+ ecoalim_mappings=';'.join([v[1] for v in mappings]),
111
+ has_no_gap_filled_background_emissions=has_no_gap_filled_background_emissions,
112
+ input_value=input_value)
113
+
114
+ should_run = all([has_mappings, has_no_gap_filled_background_emissions, input_value])
115
+ logShouldRun(cycle, MODEL, input_term_id, should_run, methodTier=TIER, model_key=MODEL_KEY)
116
+
117
+ grouped_emissions = reduce(_add_emission(cycle, input), mappings, {}) if should_run else {}
118
+ return [
119
+ _emission(term_id, mean(value) * input_value, input)
120
+ for term_id, value in grouped_emissions.items()
121
+ ]
122
+ return run
123
+
124
+
125
+ def run(cycle: dict):
126
+ inputs = get_background_inputs(cycle)
127
+ grouped_inputs = reduce(group_by_keys(['term', 'operation', 'animal']), inputs, {})
128
+ return flatten(map(_run_input(cycle), grouped_inputs.values()))
@@ -0,0 +1,125 @@
1
+ from functools import reduce
2
+ from statistics import mean
3
+ from hestia_earth.schema import IndicatorMethodTier
4
+ from hestia_earth.utils.tools import flatten, list_sum
5
+
6
+ from hestia_earth.models.log import debugValues, logShouldRun, logRequirements
7
+ from hestia_earth.models.utils.indicator import _new_indicator
8
+ from hestia_earth.models.utils.background_emissions import get_background_inputs
9
+ from hestia_earth.models.utils.blank_node import group_by_keys
10
+ from .utils import get_input_mappings, ecoalim_values
11
+ from . import MODEL
12
+
13
+ REQUIREMENTS = {
14
+ "ImpactAssessment": {
15
+ "cycle": {
16
+ "@type": "Cycle",
17
+ "inputs": [{
18
+ "@type": "Input",
19
+ "value": "> 0",
20
+ "none": {
21
+ "fromCycle": "True",
22
+ "producedInCycle": "True"
23
+ }
24
+ }],
25
+ "optional": {
26
+ "animals": [{
27
+ "@type": "Animal",
28
+ "inputs": [{
29
+ "@type": "Input",
30
+ "value": "> 0",
31
+ "none": {
32
+ "fromCycle": "True",
33
+ "producedInCycle": "True"
34
+ }
35
+ }]
36
+ }]
37
+ }
38
+ }
39
+ }
40
+ }
41
+ RETURNS = {
42
+ "Indicator": [{
43
+ "term": "",
44
+ "value": "",
45
+ "methodTier": "background",
46
+ "inputs": "",
47
+ "operation": ""
48
+ }]
49
+ }
50
+ LOOKUPS = {
51
+ "ecoalim-emissionsResourceUse": "resourceUse-",
52
+ "crop": "ecoalimMapping",
53
+ "processedFood": "ecoalimMapping",
54
+ "animalProduct": "ecoalimMapping",
55
+ "forage": "ecoalimMapping",
56
+ "feedFoodAdditive": "ecoalimMapping"
57
+ }
58
+ MODEL_KEY = 'impact_assessment'
59
+ TIER = IndicatorMethodTier.BACKGROUND.value
60
+
61
+
62
+ def _indicator(term_id: str, value: float, input: dict):
63
+ indicator = _new_indicator(term_id, MODEL)
64
+ indicator['value'] = value
65
+ indicator['methodTier'] = TIER
66
+ indicator['inputs'] = [input.get('term')]
67
+ if input.get('operation'):
68
+ indicator['operation'] = input.get('operation')
69
+ return indicator
70
+
71
+
72
+ def _add_indicator(cycle: dict, input: dict):
73
+ input_term_id = input.get('term', {}).get('@id')
74
+ operation_term_id = input.get('operation', {}).get('@id')
75
+ animal_term_id = input.get('animal', {}).get('@id')
76
+
77
+ def add(prev: dict, mapping: tuple):
78
+ gadm_id, ecoalim_key = mapping
79
+ # all countries have the same coefficient
80
+ coefficient = 1
81
+ indicators = ecoalim_values(ecoalim_key, 'resourceUse')
82
+ for indicator_term_id, value in indicators:
83
+ # log run on each indicator so we know it did run
84
+ debugValues(cycle, model=MODEL, term=indicator_term_id, model_key=MODEL_KEY,
85
+ value=value,
86
+ coefficient=coefficient,
87
+ input=input_term_id,
88
+ operation=operation_term_id,
89
+ animal=animal_term_id)
90
+ if value is not None:
91
+ prev[indicator_term_id] = prev.get(indicator_term_id, []) + [value * coefficient]
92
+ return prev
93
+ return add
94
+
95
+
96
+ def _run_input(impact_assessment: dict):
97
+ def run(inputs: list):
98
+ input = inputs[0]
99
+ input_term_id = input.get('term', {}).get('@id')
100
+ input_value = list_sum(flatten(input.get('value', []) for input in inputs))
101
+ mappings = get_input_mappings(MODEL, input)
102
+ has_mappings = len(mappings) > 0
103
+
104
+ logRequirements(impact_assessment, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
105
+ has_ecoalim_mappings=has_mappings,
106
+ ecoalim_mappings=';'.join([v[1] for v in mappings]),
107
+ input_value=input_value)
108
+
109
+ should_run = all([has_mappings, input_value])
110
+ logShouldRun(
111
+ impact_assessment, MODEL, input_term_id, should_run, methodTier=TIER, model_key=MODEL_KEY
112
+ )
113
+
114
+ grouped_indicators = reduce(_add_indicator(impact_assessment, input), mappings, {}) if should_run else {}
115
+ return [
116
+ _indicator(term_id, mean(value) * input_value, input)
117
+ for term_id, value in grouped_indicators.items()
118
+ ]
119
+ return run
120
+
121
+
122
+ def run(impact_assessment: dict):
123
+ inputs = get_background_inputs(impact_assessment.get('cycle', {}))
124
+ grouped_inputs = reduce(group_by_keys(['term', 'operation']), inputs, {})
125
+ return flatten(map(_run_input(impact_assessment), grouped_inputs.values()))
@@ -0,0 +1,31 @@
1
+ from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name, lookup_columns
2
+ from hestia_earth.utils.tools import non_empty_list
3
+
4
+ from hestia_earth.models.utils.term import get_lookup_value
5
+
6
+
7
+ _LOOKUP = "ecoalim-emissionsResourceUse.csv"
8
+
9
+
10
+ def get_input_mappings(model: str, input: dict):
11
+ term = input.get('term', {})
12
+ term_id = term.get('@id')
13
+ value = get_lookup_value(term, 'ecoalimMapping', model=model, term=term_id)
14
+ mappings = non_empty_list(value.split(';')) if value else []
15
+ return [(m.split(':')[0], m.split(':')[1]) for m in mappings]
16
+
17
+
18
+ def ecoalim_values(mapping: str, column_prefix: str):
19
+ lookup = download_lookup(_LOOKUP)
20
+ col_name = column_name('ecoalimMappingName')
21
+
22
+ def emission(column: str):
23
+ id = get_table_value(lookup, col_name, mapping, column)
24
+ value = get_table_value(lookup, col_name, mapping, column.replace('term', 'value'))
25
+ return (id, value) if id else None
26
+
27
+ columns = [
28
+ col for col in lookup_columns(lookup)
29
+ if col.startswith(column_name(column_prefix)) and col.endswith(column_name('term'))
30
+ ]
31
+ return non_empty_list(map(emission, columns))
@@ -4,12 +4,12 @@ from hestia_earth.utils.tools import flatten, list_sum
4
4
 
5
5
  from hestia_earth.models.log import debugValues, logShouldRun, logRequirements
6
6
  from hestia_earth.models.data.ecoinventV3 import ecoinventV3_emissions
7
- from hestia_earth.models.utils import is_from_model
8
7
  from hestia_earth.models.utils.emission import _new_emission
8
+ from hestia_earth.models.utils.background_emissions import get_background_inputs, no_gap_filled_background_emissions
9
9
  from hestia_earth.models.utils.blank_node import group_by_keys
10
10
  from hestia_earth.models.utils.pesticideAI import get_pesticides_from_inputs
11
11
  from hestia_earth.models.utils.fertiliser import get_fertilisers_from_inputs
12
- from .utils import get_background_inputs, get_input_mappings
12
+ from .utils import get_input_mappings
13
13
 
14
14
  REQUIREMENTS = {
15
15
  "Cycle": {
@@ -96,26 +96,17 @@ def _add_emission(cycle: dict, input: dict):
96
96
 
97
97
 
98
98
  def _run_input(cycle: dict):
99
- emissions = cycle.get('emissions', [])
99
+ no_gap_filled_background_emissions_func = no_gap_filled_background_emissions(cycle)
100
100
 
101
101
  def run(inputs: list):
102
102
  input = inputs[0]
103
103
  input_term_id = input.get('term', {}).get('@id')
104
- operation_term_id = input.get('operation', {}).get('@id')
105
- animal_term_id = input.get('animal', {}).get('@id')
106
104
  input_value = list_sum(flatten(input.get('value', []) for input in inputs))
107
105
  mappings = get_input_mappings(MODEL, cycle, input)
108
106
  has_mappings = len(mappings) > 0
107
+
109
108
  # skip input that has background emissions we have already gap-filled (model run before)
110
- has_no_gap_filled_background_emissions = not any([
111
- is_from_model(e)
112
- for e in emissions
113
- if all([
114
- any([i.get('@id') == input_term_id for i in e.get('inputs', [])]),
115
- e.get('operation', {}).get('@id') == operation_term_id,
116
- e.get('animal', {}).get('@id') == animal_term_id
117
- ])
118
- ])
109
+ has_no_gap_filled_background_emissions = no_gap_filled_background_emissions_func(input)
119
110
 
120
111
  logRequirements(cycle, model=MODEL, term=input_term_id,
121
112
  has_ecoinvent_mappings=has_mappings,
@@ -125,6 +116,7 @@ def _run_input(cycle: dict):
125
116
 
126
117
  should_run = all([has_mappings, has_no_gap_filled_background_emissions, input_value])
127
118
  logShouldRun(cycle, MODEL, input_term_id, should_run, methodTier=TIER)
119
+
128
120
  grouped_emissions = reduce(_add_emission(cycle, input), mappings, {}) if should_run else {}
129
121
  return [
130
122
  _emission(term_id, value * input_value, input)
@@ -1,36 +1,8 @@
1
- from hestia_earth.utils.model import find_term_match
2
- from hestia_earth.utils.tools import flatten, non_empty_list
1
+ from hestia_earth.utils.tools import non_empty_list
3
2
 
4
3
  from hestia_earth.models.utils.term import get_lookup_value
5
4
 
6
5
 
7
- def _animal_inputs(animal: dict):
8
- inputs = animal.get('inputs', [])
9
- return [(input | {'animal': animal.get('term', {})}) for input in inputs]
10
-
11
-
12
- def _should_run_input(products: list):
13
- def should_run(input: dict):
14
- return all([
15
- # make sure Input is not a Product as well or we might double-count emissions
16
- find_term_match(products, input.get('term', {}).get('@id'), None) is None,
17
- # ignore inputs which are flagged as Product of the Cycle
18
- not input.get('fromCycle', False),
19
- not input.get('producedInCycle', False)
20
- ])
21
- return should_run
22
-
23
-
24
- def get_background_inputs(cycle: dict, extra_inputs: list = []):
25
- # add all the properties of some Term that inlcude others with the mapping
26
- inputs = flatten(
27
- cycle.get('inputs', []) +
28
- list(map(_animal_inputs, cycle.get('animals', []))) +
29
- extra_inputs
30
- )
31
- return list(filter(_should_run_input(cycle.get('products', [])), inputs))
32
-
33
-
34
6
  def get_input_mappings(model: str, cycle: dict, input: dict):
35
7
  term = input.get('term', {})
36
8
  term_id = term.get('@id')
@@ -4,12 +4,13 @@ from hestia_earth.schema import EmissionMethodTier
4
4
 
5
5
  from hestia_earth.models.log import logShouldRun, logRequirements, debugValues
6
6
  from hestia_earth.models.utils.emission import _new_emission
7
+ from hestia_earth.models.utils.background_emissions import get_background_inputs, no_gap_filled_background_emissions
7
8
  from hestia_earth.models.utils.blank_node import group_by_keys
8
9
  from hestia_earth.models.utils.completeness import _is_term_type_complete
9
10
  from hestia_earth.models.utils.term import get_electricity_grid_mix_terms
10
11
  from hestia_earth.models.data.ecoinventV3 import ecoinventV3_emissions
11
12
  from .utils import get_input_coefficient
12
- from ..ecoinventV3.utils import get_background_inputs, get_input_mappings
13
+ from ..ecoinventV3.utils import get_input_mappings
13
14
 
14
15
  REQUIREMENTS = {
15
16
  "Cycle": {
@@ -101,6 +102,7 @@ def _add_emission(cycle: dict, input: dict):
101
102
 
102
103
  def _run_input(cycle: dict):
103
104
  electricity_complete = _is_term_type_complete(cycle, 'electricityFuel')
105
+ no_gap_filled_background_emissions_func = no_gap_filled_background_emissions(cycle)
104
106
 
105
107
  def run(inputs: list):
106
108
  input = inputs[0]
@@ -109,12 +111,16 @@ def _run_input(cycle: dict):
109
111
  mappings = get_input_mappings(MODEL, cycle, input)
110
112
  has_mappings = len(mappings) > 0
111
113
 
114
+ # skip input that has background emissions we have already gap-filled (model run before)
115
+ has_no_gap_filled_background_emissions = no_gap_filled_background_emissions_func(input)
116
+
112
117
  logRequirements(cycle, model=MODEL, term=input_term_id,
113
118
  has_ecoinvent_mappings=has_mappings,
114
119
  ecoinvent_mappings=';'.join([v[0] for v in mappings]),
120
+ has_no_gap_filled_background_emissions=has_no_gap_filled_background_emissions,
115
121
  input_value=input_value)
116
122
 
117
- should_run = all([electricity_complete, has_mappings, input_value])
123
+ should_run = all([electricity_complete, has_mappings, has_no_gap_filled_background_emissions, input_value])
118
124
  logShouldRun(cycle, MODEL, input_term_id, should_run, methodTier=TIER)
119
125
 
120
126
  grouped_emissions = reduce(_add_emission(cycle, input), mappings, {}) if should_run else {}