hestia-earth-models 0.70.0__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 (168) hide show
  1. hestia_earth/models/aware/scarcityWeightedWaterUse.py +8 -16
  2. hestia_earth/models/config/Cycle.json +52 -64
  3. hestia_earth/models/config/ImpactAssessment.json +12 -4
  4. hestia_earth/models/config/Site.json +33 -22
  5. hestia_earth/models/cycle/transformation.py +1 -1
  6. hestia_earth/models/cycle/utils.py +0 -6
  7. hestia_earth/models/data/ecoinventV3/__init__.py +15 -13
  8. hestia_earth/models/ecoalimV9/__init__.py +13 -0
  9. hestia_earth/models/ecoalimV9/cycle.py +128 -0
  10. hestia_earth/models/ecoalimV9/impact_assessment.py +125 -0
  11. hestia_earth/models/ecoalimV9/utils.py +31 -0
  12. hestia_earth/models/ecoinventV3/__init__.py +6 -14
  13. hestia_earth/models/ecoinventV3/utils.py +1 -29
  14. hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +8 -2
  15. hestia_earth/models/emissionNotRelevant/__init__.py +33 -8
  16. hestia_earth/models/{cycle → hestia}/aboveGroundCropResidue.py +4 -3
  17. hestia_earth/models/{cycle → hestia}/aboveGroundCropResidueTotal.py +1 -1
  18. hestia_earth/models/{site → hestia}/brackishWater.py +1 -1
  19. hestia_earth/models/{site → hestia}/cationExchangeCapacityPerKgSoil.py +1 -1
  20. hestia_earth/models/{cycle → hestia}/coldCarcassWeightPerHead.py +1 -1
  21. hestia_earth/models/{cycle → hestia}/coldDressedCarcassWeightPerHead.py +1 -1
  22. hestia_earth/models/{cycle → hestia}/concentrateFeed.py +1 -1
  23. hestia_earth/models/{cycle → hestia}/cropResidueManagement.py +1 -1
  24. hestia_earth/models/{cycle → hestia}/croppingIntensity.py +1 -1
  25. hestia_earth/models/{cycle → hestia}/energyContentLowerHeatingValue.py +1 -1
  26. hestia_earth/models/{cycle → hestia}/excretaKgMass.py +7 -2
  27. hestia_earth/models/{cycle → hestia}/excretaKgN.py +1 -1
  28. hestia_earth/models/{cycle → hestia}/excretaKgVs.py +1 -1
  29. hestia_earth/models/{cycle → hestia}/feedConversionRatio/__init__.py +1 -1
  30. hestia_earth/models/{site → hestia}/flowingWater.py +1 -1
  31. hestia_earth/models/{site → hestia}/freshWater.py +1 -1
  32. hestia_earth/models/{cycle → hestia}/inorganicFertiliser.py +1 -1
  33. hestia_earth/models/{cycle → hestia}/irrigatedTypeUnspecified.py +14 -19
  34. hestia_earth/models/hestia/landCover.py +30 -22
  35. hestia_earth/models/{cycle → hestia}/liveAnimal.py +1 -1
  36. hestia_earth/models/{cycle → hestia}/longFallowRatio.py +1 -1
  37. hestia_earth/models/{cycle → hestia}/materialAndSubstrate.py +1 -1
  38. hestia_earth/models/{cycle → hestia}/milkYield.py +1 -1
  39. hestia_earth/models/{site → hestia}/netPrimaryProduction.py +1 -1
  40. hestia_earth/models/{site → hestia}/organicCarbonPerHa.py +1 -1
  41. hestia_earth/models/{cycle → hestia}/pastureGrass.py +1 -1
  42. hestia_earth/models/{cycle → hestia}/pastureSystem.py +1 -1
  43. hestia_earth/models/{site → hestia}/potentialEvapotranspirationAnnual.py +3 -3
  44. hestia_earth/models/{site → hestia}/potentialEvapotranspirationMonthly.py +3 -3
  45. hestia_earth/models/{site → hestia}/precipitationAnnual.py +3 -3
  46. hestia_earth/models/{site → hestia}/precipitationMonthly.py +3 -3
  47. hestia_earth/models/{site → hestia}/rainfallAnnual.py +3 -3
  48. hestia_earth/models/{site → hestia}/rainfallMonthly.py +3 -3
  49. hestia_earth/models/{cycle → hestia}/readyToCookWeightPerHead.py +1 -1
  50. hestia_earth/models/{cycle → hestia}/residueBurnt.py +1 -1
  51. hestia_earth/models/{cycle → hestia}/residueIncorporated.py +1 -1
  52. hestia_earth/models/{cycle → hestia}/residueLeftOnField.py +1 -1
  53. hestia_earth/models/hestia/residueRemoved.py +65 -13
  54. hestia_earth/models/{site → hestia}/salineWater.py +1 -1
  55. hestia_earth/models/{site → hestia}/soilMeasurement.py +1 -1
  56. hestia_earth/models/{cycle → hestia}/stockingDensityAnimalHousingAverage.py +1 -1
  57. hestia_earth/models/{site → hestia}/temperatureAnnual.py +3 -3
  58. hestia_earth/models/{site → hestia}/temperatureMonthly.py +3 -3
  59. hestia_earth/models/{site → hestia}/totalNitrogenPerKgSoil.py +1 -1
  60. hestia_earth/models/{cycle → hestia}/unknownPreSeasonWaterRegime.py +1 -1
  61. hestia_earth/models/hestia/utils.py +93 -0
  62. hestia_earth/models/{site → hestia}/waterDepth.py +1 -1
  63. hestia_earth/models/hestia/waterSalinity.py +78 -0
  64. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +1 -1
  65. hestia_earth/models/ipcc2019/belowGroundBiomass.py +1 -1
  66. hestia_earth/models/ipcc2019/biomass_utils.py +2 -4
  67. hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +163 -78
  68. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +31 -20
  69. hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +16 -9
  70. hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +35 -47
  71. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +86 -1
  72. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py +127 -1
  73. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +7 -5
  74. hestia_earth/models/mocking/search-results.json +764 -772
  75. hestia_earth/models/pooreNemecek2018/utils.py +8 -2
  76. hestia_earth/models/schmidt2007/ch4ToAirWasteTreatment.py +1 -4
  77. hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +1 -4
  78. hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +1 -4
  79. hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +1 -4
  80. hestia_earth/models/utils/background_emissions.py +52 -0
  81. hestia_earth/models/utils/blank_node.py +9 -5
  82. hestia_earth/models/utils/impact_assessment.py +26 -17
  83. hestia_earth/models/utils/lookup.py +48 -39
  84. hestia_earth/models/utils/measurement.py +3 -3
  85. hestia_earth/models/version.py +1 -1
  86. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/METADATA +2 -2
  87. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/RECORD +163 -158
  88. tests/models/aware/test_scarcityWeightedWaterUse.py +1 -12
  89. tests/models/ecoalimV9/__init__.py +0 -0
  90. tests/models/ecoalimV9/test_cycle.py +21 -0
  91. tests/models/ecoalimV9/test_impact_assessment.py +24 -0
  92. tests/models/environmentalFootprintV3_1/test_scarcityWeightedWaterUse.py +4 -2
  93. tests/models/{cycle → hestia}/test_aboveGroundCropResidue.py +1 -1
  94. tests/models/{cycle → hestia}/test_aboveGroundCropResidueTotal.py +1 -1
  95. tests/models/{site → hestia}/test_brackishWater.py +1 -1
  96. tests/models/{site → hestia}/test_cationExchangeCapacityPerKgSoil.py +1 -1
  97. tests/models/{cycle → hestia}/test_coldCarcassWeightPerHead.py +1 -1
  98. tests/models/{cycle → hestia}/test_coldDressedCarcassWeightPerHead.py +1 -1
  99. tests/models/{cycle → hestia}/test_concentrateFeed.py +1 -1
  100. tests/models/{cycle → hestia}/test_cropResidueManagement.py +1 -1
  101. tests/models/{cycle → hestia}/test_croppingIntensity.py +1 -1
  102. tests/models/{cycle → hestia}/test_energyContentLowerHeatingValue.py +5 -3
  103. tests/models/{cycle → hestia}/test_excretaKgMass.py +1 -1
  104. tests/models/{cycle → hestia}/test_excretaKgN.py +1 -1
  105. tests/models/{cycle → hestia}/test_excretaKgVs.py +1 -1
  106. tests/models/{cycle → hestia}/test_feedConversionRatio.py +1 -1
  107. tests/models/{site → hestia}/test_flowingWater.py +1 -1
  108. tests/models/{site → hestia}/test_freshWater.py +1 -1
  109. tests/models/{cycle → hestia}/test_inorganicFertiliser.py +1 -1
  110. tests/models/{cycle → hestia}/test_irrigatedTypeUnspecified.py +2 -5
  111. tests/models/hestia/test_landCover.py +4 -34
  112. tests/models/{cycle → hestia}/test_liveAnimal.py +1 -1
  113. tests/models/{cycle → hestia}/test_longFallowRatio.py +1 -1
  114. tests/models/{site → hestia}/test_management.py +1 -1
  115. tests/models/{cycle → hestia}/test_materialsAndSubstrate.py +1 -1
  116. tests/models/{cycle → hestia}/test_milkYield.py +1 -1
  117. tests/models/{site → hestia}/test_netPrimaryProduction.py +1 -1
  118. tests/models/{site → hestia}/test_organicCarbonPerHa.py +1 -1
  119. tests/models/{site → hestia}/test_organicCarbonPerKgSoil.py +1 -1
  120. tests/models/{site → hestia}/test_organicCarbonPerM3Soil.py +1 -1
  121. tests/models/{site → hestia}/test_organicMatterPerKgSoil.py +1 -1
  122. tests/models/{site → hestia}/test_organicMatterPerM3Soil.py +1 -1
  123. tests/models/{cycle → hestia}/test_pastureGrass.py +1 -1
  124. tests/models/{cycle → hestia}/test_pastureSystem.py +1 -1
  125. tests/models/{site → hestia}/test_potentialEvapotranspirationAnnual.py +1 -1
  126. tests/models/{site → hestia}/test_potentialEvapotranspirationMonthly.py +1 -1
  127. tests/models/{site → hestia}/test_precipitationAnnual.py +1 -1
  128. tests/models/{site → hestia}/test_precipitationMonthly.py +1 -1
  129. tests/models/{site → hestia}/test_rainfallAnnual.py +1 -1
  130. tests/models/{site → hestia}/test_rainfallMonthly.py +1 -1
  131. tests/models/{cycle → hestia}/test_readyToCookWeightPerHead.py +1 -1
  132. tests/models/{cycle → hestia}/test_residueBurnt.py +1 -1
  133. tests/models/{cycle → hestia}/test_residueIncorporated.py +1 -1
  134. tests/models/{cycle → hestia}/test_residueLeftOnField.py +1 -1
  135. tests/models/hestia/test_residueRemoved.py +15 -3
  136. tests/models/{site → hestia}/test_salineWater.py +1 -1
  137. tests/models/{site → hestia}/test_soilMeasurement.py +2 -2
  138. tests/models/{cycle → hestia}/test_stockingDensityAnimalHousingAverage.py +1 -1
  139. tests/models/{site → hestia}/test_temperatureAnnual.py +1 -1
  140. tests/models/{site → hestia}/test_temperatureMonthly.py +1 -1
  141. tests/models/{site → hestia}/test_totalNitrogenPerKgSoil.py +1 -1
  142. tests/models/{cycle → hestia}/test_unknownPreSeasonWaterRegime.py +1 -1
  143. tests/models/{site → hestia}/test_waterDepth.py +1 -1
  144. tests/models/hestia/test_waterSalinity.py +26 -0
  145. tests/models/ipcc2019/test_ch4ToAirFloodedRice.py +10 -42
  146. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +2 -1
  147. tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +3 -2
  148. tests/models/test_ecoinventV3AndEmberClimate.py +2 -2
  149. tests/models/test_emissionNotRelevant.py +0 -8
  150. tests/models/utils/test_measurement.py +1 -1
  151. hestia_earth/models/cycle/residueRemoved.py +0 -54
  152. hestia_earth/models/hestia/nh3ToSurfaceWaterAquacultureSystems.py +0 -64
  153. hestia_earth/models/site/utils.py +0 -93
  154. tests/models/cycle/test_residueRemoved.py +0 -37
  155. tests/models/hestia/test_nh3ToSurfaceWaterAquacultureSystems.py +0 -51
  156. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioCarbon.py +0 -0
  157. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioDryMatter.py +0 -0
  158. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioEnergy.py +0 -0
  159. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioFedWeight.py +0 -0
  160. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioNitrogen.py +0 -0
  161. /hestia_earth/models/{site → hestia}/management.py +0 -0
  162. /hestia_earth/models/{site → hestia}/organicCarbonPerKgSoil.py +0 -0
  163. /hestia_earth/models/{site → hestia}/organicCarbonPerM3Soil.py +0 -0
  164. /hestia_earth/models/{site → hestia}/organicMatterPerKgSoil.py +0 -0
  165. /hestia_earth/models/{site → hestia}/organicMatterPerM3Soil.py +0 -0
  166. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/LICENSE +0 -0
  167. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/WHEEL +0 -0
  168. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/top_level.txt +0 -0
@@ -31,12 +31,18 @@ def run_products_average(cycle: dict, term_id: str, get_value_func):
31
31
  return list_average(values) if should_run else None
32
32
 
33
33
 
34
+ def _excreta_product_id(data: str, term_id):
35
+ value = extract_grouped_data(data, term_id) or ''
36
+ return value.split('|')[0] if '|' in value else value
37
+
38
+
34
39
  def get_excreta_product_with_ratio(cycle: dict, lookup: str, **log_args):
35
40
  product = find_primary_product(cycle) or {}
36
41
 
37
42
  data = get_lookup_value(product.get('term'), lookup, model=MODEL, **log_args)
38
43
 
39
- default_product_id = extract_grouped_data(data, 'default')
44
+ # TODO: handle multiple products delimited by `|`
45
+ default_product_id = _excreta_product_id(data, 'default')
40
46
 
41
47
  # find matching practices and assign a ratio for each
42
48
  # if no matches, use default id with 100% ratio
@@ -44,7 +50,7 @@ def get_excreta_product_with_ratio(cycle: dict, lookup: str, **log_args):
44
50
  practices = [
45
51
  {
46
52
  'id': practice.get('term', {}).get('@id'),
47
- 'product-id': extract_grouped_data(data, practice.get('term', {}).get('@id')) or default_product_id,
53
+ 'product-id': _excreta_product_id(data, practice.get('term', {}).get('@id')) or default_product_id,
48
54
  'value': list_sum(practice.get('value'))
49
55
  }
50
56
  for practice in practices
@@ -8,10 +8,7 @@ from . import MODEL
8
8
 
9
9
  REQUIREMENTS = {
10
10
  "Cycle": {
11
- "or": {
12
- "products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
13
- "completeness.waste": ""
14
- }
11
+ "products": [{"@type": "Product", "value": ""}]
15
12
  }
16
13
  }
17
14
  RETURNS = {
@@ -8,10 +8,7 @@ from . import MODEL
8
8
 
9
9
  REQUIREMENTS = {
10
10
  "Cycle": {
11
- "or": {
12
- "products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
13
- "completeness.waste": ""
14
- }
11
+ "products": [{"@type": "Product", "value": ""}]
15
12
  }
16
13
  }
17
14
  RETURNS = {
@@ -8,10 +8,7 @@ from . import MODEL
8
8
 
9
9
  REQUIREMENTS = {
10
10
  "Cycle": {
11
- "or": {
12
- "products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
13
- "completeness.waste": ""
14
- }
11
+ "products": [{"@type": "Product", "value": ""}]
15
12
  }
16
13
  }
17
14
  RETURNS = {
@@ -8,10 +8,7 @@ from . import MODEL
8
8
 
9
9
  REQUIREMENTS = {
10
10
  "Cycle": {
11
- "or": {
12
- "products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
13
- "completeness.waste": ""
14
- }
11
+ "products": [{"@type": "Product", "value": ""}]
15
12
  }
16
13
  }
17
14
  RETURNS = {
@@ -0,0 +1,52 @@
1
+ from hestia_earth.utils.model import find_term_match
2
+ from hestia_earth.utils.tools import flatten
3
+
4
+ from . import is_from_model
5
+
6
+
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
+ def no_gap_filled_background_emissions(cycle: dict):
35
+ emissions = cycle.get('emissions', [])
36
+
37
+ def check_input(input: dict):
38
+ input_term_id = input.get('term', {}).get('@id')
39
+ operation_term_id = input.get('operation', {}).get('@id')
40
+ animal_term_id = input.get('animal', {}).get('@id')
41
+
42
+ return not any([
43
+ is_from_model(emission)
44
+ for emission in emissions
45
+ if all([
46
+ any([i.get('@id') == input_term_id for i in emission.get('inputs', [])]),
47
+ emission.get('operation', {}).get('@id') == operation_term_id,
48
+ emission.get('animal', {}).get('@id') == animal_term_id
49
+ ])
50
+ ])
51
+
52
+ return check_input
@@ -27,6 +27,7 @@ from hestia_earth.utils.tools import (
27
27
  )
28
28
  from hestia_earth.utils.lookup_utils import (
29
29
  is_model_siteType_allowed,
30
+ is_model_product_id_allowed,
30
31
  is_siteType_allowed,
31
32
  is_product_id_allowed,
32
33
  is_product_termType_allowed,
@@ -124,13 +125,16 @@ def _module_term_id(term_id: str, module):
124
125
  return getattr(module, 'TERM_ID', term_id_str).split(',')[0]
125
126
 
126
127
 
127
- def _run_model_required(model: str, term_id: str, data: dict):
128
+ def _run_model_required(model: str, term_id: str, data: dict, skip_logs: bool = False):
128
129
  siteType_allowed = is_model_siteType_allowed(model, term_id, data)
130
+ product_id_allowed = is_model_product_id_allowed(model, term_id, data)
129
131
 
130
- run_required = all([siteType_allowed])
131
- debugValues(data, model=model, term=term_id,
132
- run_required=run_required,
133
- siteType_allowed=siteType_allowed)
132
+ run_required = all([siteType_allowed, product_id_allowed])
133
+ if not skip_logs:
134
+ debugValues(data, model=model, term=term_id,
135
+ run_required=run_required,
136
+ siteType_allowed=siteType_allowed,
137
+ product_id_allowed=product_id_allowed)
134
138
  return run_required
135
139
 
136
140
 
@@ -3,7 +3,7 @@ from hestia_earth.schema import TermTermType
3
3
  from hestia_earth.utils.model import find_term_match, filter_list_term_type
4
4
  from hestia_earth.utils.tools import list_sum, safe_parse_date
5
5
 
6
- from hestia_earth.models.log import debugValues, log_as_table
6
+ from hestia_earth.models.log import debugValues
7
7
  from .lookup import all_factor_value, _term_factor_value, _aware_factor_value, fallback_country
8
8
  from .product import find_by_product
9
9
  from .site import region_level_1_id
@@ -157,22 +157,22 @@ def impact_country_value(
157
157
  The impact total value.
158
158
  """
159
159
  term_type = TermTermType.RESOURCEUSE.value if 'resourceUse' in lookup else TermTermType.EMISSION.value
160
- nodes = filter_list_term_type(impact.get('emissionsResourceUse', []), term_type)
160
+ blank_nodes = filter_list_term_type(impact.get('emissionsResourceUse', []), term_type)
161
161
 
162
162
  country_id = get_country_id(impact)
163
163
  country_id = fallback_country(country_id, [lookup]) if country_fallback else country_id
164
164
 
165
- values = list(map(_term_factor_value(model, term_id, lookup, country_id, group_key), nodes))
166
- debugValues(impact, model=model, term=term_id,
167
- values_used=log_as_table(values))
168
-
169
- has_values = len(values) > 0
170
- missing_values = set([v.get('id') for v in values if v.get('value') and v.get('coefficient') is None])
171
- all_with_factors = not missing_values
172
- values = [float((v.get('value') or 0) * (v.get('coefficient') or 0)) for v in values]
173
-
174
- # fail if some factors are missing
175
- return None if not all_with_factors else (list_sum(values) if has_values else default_no_values)
165
+ return all_factor_value(
166
+ model=model,
167
+ term_id=term_id,
168
+ node=impact,
169
+ lookup_name=lookup,
170
+ lookup_col=country_id,
171
+ blank_nodes=blank_nodes,
172
+ grouped_key=group_key,
173
+ default_no_values=None,
174
+ factor_value_func=_term_factor_value
175
+ )
176
176
 
177
177
 
178
178
  def impact_aware_value(model: str, term_id: str, impact: dict, lookup: str, group_key: str = None) -> float:
@@ -197,14 +197,23 @@ def impact_aware_value(model: str, term_id: str, impact: dict, lookup: str, grou
197
197
  int
198
198
  The impact total value.
199
199
  """
200
- nodes = impact.get('emissionsResourceUse', [])
200
+ blank_nodes = impact.get('emissionsResourceUse', [])
201
201
  site = get_site(impact)
202
202
  aware_id = site.get('awareWaterBasinId')
203
203
  if aware_id is None:
204
204
  return None
205
- factors = list(map(_aware_factor_value(model, term_id, lookup, aware_id, group_key), nodes))
206
- values = [value for value in factors if value is not None]
207
- return list_sum(values) if len(values) > 0 else None
205
+
206
+ return all_factor_value(
207
+ model=model,
208
+ term_id=term_id,
209
+ node=impact,
210
+ lookup_name=lookup,
211
+ lookup_col=aware_id,
212
+ blank_nodes=blank_nodes,
213
+ grouped_key=group_key,
214
+ default_no_values=None,
215
+ factor_value_func=_aware_factor_value
216
+ )
208
217
 
209
218
 
210
219
  def impact_endpoint_value(model: str, term_id: str, impact: dict, lookup_col: str) -> float:
@@ -26,7 +26,8 @@ def _factor_value(model: str, term_id: str, lookup_name: str, lookup_col: str, g
26
26
  coefficient = get_region_lookup_value(lookup_name, node_term_id, lookup_col, model=model, term=term_id)
27
27
  # value is either a number or matching between a model and a value (restrict value to specific model only)
28
28
  coefficient = safe_parse_float(
29
- extract_grouped_data(coefficient, grouped_data_key), None
29
+ extract_grouped_data(coefficient, grouped_data_key),
30
+ default=None
30
31
  ) if ':' in str(coefficient) else safe_parse_float(coefficient, None)
31
32
  if value is not None and coefficient is not None:
32
33
  if model:
@@ -39,43 +40,15 @@ def _factor_value(model: str, term_id: str, lookup_name: str, lookup_col: str, g
39
40
  return get_value
40
41
 
41
42
 
42
- def all_factor_value(
43
- model: str,
44
- term_id: str,
45
- node: dict,
46
- lookup_name: str,
47
- lookup_col: str,
48
- blank_nodes: List[dict],
49
- grouped_key: Optional[str] = None,
50
- default_no_values=0
51
- ):
52
- values = list(map(_factor_value(model, term_id, lookup_name, lookup_col, grouped_key), blank_nodes))
53
-
54
- has_values = len(values) > 0
55
- missing_values = set([v.get('id') for v in values if v.get('value') and v.get('coefficient') is None])
56
- all_with_factors = not missing_values
57
-
58
- for missing_value in missing_values:
59
- debugMissingLookup(lookup_name, 'termid', missing_value, lookup_col, None, model=model, term=term_id)
60
-
61
- debugValues(node, model=model, term=term_id,
62
- all_with_factors=all_with_factors,
63
- missing_lookup_factor=';'.join(missing_values),
64
- has_values=has_values,
65
- values_used=log_as_table(values))
66
-
67
- values = [float((v.get('value') or 0) * (v.get('coefficient') or 0)) for v in values]
68
-
69
- # fail if some factors are missing
70
- return None if not all_with_factors else (list_sum(values) if has_values else default_no_values)
71
-
72
-
73
43
  def _term_factor_value(model: str, term_id: str, lookup_name: str, lookup_term_id: str, group_key: str = None):
74
44
  def get_value(data: dict):
75
45
  node_term_id = data.get('term', {}).get('@id')
76
46
  value = _node_value(data)
77
47
  coefficient = get_region_lookup_value(lookup_name, lookup_term_id, node_term_id, model=model, term=term_id)
78
- coefficient = safe_parse_float(extract_grouped_data(coefficient, group_key) if group_key else coefficient)
48
+ coefficient = safe_parse_float(
49
+ extract_grouped_data(coefficient, group_key) if group_key else coefficient,
50
+ default=None
51
+ )
79
52
  if value is not None and coefficient is not None:
80
53
  debugValues(data, model=model, term=term_id,
81
54
  node=node_term_id,
@@ -90,23 +63,59 @@ def _aware_factor_value(model: str, term_id: str, lookup_name: str, aware_id: st
90
63
  lookup_col = column_name('awareWaterBasinId')
91
64
 
92
65
  def get_value(data: dict):
66
+ node_term_id = data.get('term', {}).get('@id')
67
+ value = _node_value(data)
68
+
93
69
  try:
94
- node_term_id = data.get('term', {}).get('@id')
95
- value = _node_value(data)
96
70
  coefficient = _get_single_table_value(lookup, lookup_col, int(aware_id), column_name(node_term_id))
97
- coefficient = safe_parse_float(extract_grouped_data(coefficient, group_key)) if group_key else coefficient
71
+ coefficient = safe_parse_float(
72
+ extract_grouped_data(coefficient, group_key),
73
+ default=None
74
+ ) if group_key else coefficient
98
75
  if value is not None and coefficient is not None:
99
76
  debugValues(data, model=model, term=term_id,
100
77
  node=node_term_id,
101
78
  value=value,
102
79
  coefficient=coefficient)
103
- return value * coefficient
104
- return None
105
80
  except ValueError: # factor does not exist
106
- return None
81
+ coefficient = None
82
+
83
+ return {'id': node_term_id, 'value': value, 'coefficient': coefficient}
107
84
  return get_value
108
85
 
109
86
 
87
+ def all_factor_value(
88
+ model: str,
89
+ term_id: str,
90
+ node: dict,
91
+ lookup_name: str,
92
+ lookup_col: str,
93
+ blank_nodes: List[dict],
94
+ grouped_key: Optional[str] = None,
95
+ default_no_values=0,
96
+ factor_value_func=_factor_value
97
+ ):
98
+ values = list(map(factor_value_func(model, term_id, lookup_name, lookup_col, grouped_key), blank_nodes))
99
+
100
+ has_values = len(values) > 0
101
+ missing_values = set([v.get('id') for v in values if v.get('value') and v.get('coefficient') is None])
102
+ all_with_factors = not missing_values
103
+
104
+ for missing_value in missing_values:
105
+ debugMissingLookup(lookup_name, 'termid', missing_value, lookup_col, None, model=model, term=term_id)
106
+
107
+ debugValues(node, model=model, term=term_id,
108
+ all_with_factors=all_with_factors,
109
+ missing_lookup_factor=';'.join(missing_values),
110
+ has_values=has_values,
111
+ values_used=log_as_table(values))
112
+
113
+ values = [float((v.get('value') or 0) * (v.get('coefficient') or 0)) for v in values]
114
+
115
+ # fail if some factors are missing
116
+ return None if not all_with_factors else (list_sum(values) if has_values else default_no_values)
117
+
118
+
110
119
  def _country_in_lookup(country_id: str):
111
120
  def in_lookup(lookup_name: str):
112
121
  return (
@@ -10,7 +10,7 @@ from hestia_earth.utils.date import diff_in_days
10
10
 
11
11
  from . import flatten_args
12
12
  from .blank_node import most_relevant_blank_node_by_id
13
- from .method import include_methodModel
13
+ from .method import include_method
14
14
  from .term import download_term, get_lookup_value
15
15
 
16
16
 
@@ -26,10 +26,10 @@ MEASUREMENT_REDUCE = {
26
26
  MEASUREMENT_METHOD_CLASSIFICATIONS = [e.value for e in MeasurementMethodClassification]
27
27
 
28
28
 
29
- def _new_measurement(term, model=None):
29
+ def _new_measurement(term, method=None):
30
30
  node = {'@type': SchemaType.MEASUREMENT.value}
31
31
  node['term'] = linked_node(term if isinstance(term, dict) else download_term(term))
32
- return include_methodModel(node, term_id=model)
32
+ return include_method(node, term_id=method)
33
33
 
34
34
 
35
35
  def measurement_value(measurement: dict, is_larger_unit: bool = False) -> float:
@@ -1 +1 @@
1
- VERSION = '0.70.0'
1
+ VERSION = '0.70.1'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hestia-earth-models
3
- Version: 0.70.0
3
+ Version: 0.70.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==31.*
15
- Requires-Dist: hestia-earth-utils>=0.14.0
15
+ Requires-Dist: hestia-earth-utils>=0.14.1
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