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
@@ -33,11 +33,137 @@ from .organicCarbonPerHa_utils import (
33
33
  )
34
34
  from . import MODEL
35
35
 
36
- _LOOKUPS = {
36
+ REQUIREMENTS = {
37
+ "Site": {
38
+ "siteType": "cropland",
39
+ "measurements": [
40
+ {
41
+ "@type": "Measurement",
42
+ "term.@id": "sandContent",
43
+ "value": "",
44
+ "depthUpper": "0",
45
+ "depthLower": "30",
46
+ "optional": {
47
+ "dates": ""
48
+ }
49
+ },
50
+ {
51
+ "@type": "Measurement",
52
+ "term.@id": "temperatureMonthly",
53
+ "value": "",
54
+ "dates": ""
55
+ },
56
+ {
57
+ "@type": "Measurement",
58
+ "term.@id": "precipitationMonthly",
59
+ "value": "",
60
+ "dates": ""
61
+ },
62
+ {
63
+ "@type": "Measurement",
64
+ "term.@id": "potentialEvapotranspirationMonthly",
65
+ "value": "",
66
+ "dates": ""
67
+ }
68
+ ],
69
+ "related": {
70
+ "Cycle": [{
71
+ "endDate": "",
72
+ "products": [
73
+ {
74
+ "@type": "Product",
75
+ "term.@id": [
76
+ "aboveGroundCropResidueLeftOnField",
77
+ "aboveGroundCropResidueIncorporated",
78
+ "belowGroundCropResidue",
79
+ "discardedCropLeftOnField",
80
+ "discardedCropIncorporated"
81
+ ],
82
+ "value": "",
83
+ "properties": [
84
+ {
85
+ "@type": "Property",
86
+ "term.@id": "carbonContent",
87
+ "value": ""
88
+ },
89
+ {
90
+ "@type": "Property",
91
+ "term.@id": "nitrogenContent",
92
+ "value": ""
93
+ },
94
+ {
95
+ "@type": "Property",
96
+ "term.@id": "ligninContent",
97
+ "value": ""
98
+ }
99
+ ]
100
+ }
101
+ ],
102
+ "inputs": [
103
+ {
104
+ "@type": "Input",
105
+ "term.termType": ["organicFertiliser", "soilAmendment"],
106
+ "value": "",
107
+ "properties": [
108
+ {
109
+ "@type": "Property",
110
+ "term.@id": "carbonContent",
111
+ "value": ""
112
+ },
113
+ {
114
+ "@type": "Property",
115
+ "term.@id": "nitrogenContent",
116
+ "value": ""
117
+ },
118
+ {
119
+ "@type": "Property",
120
+ "term.@id": "ligninContent",
121
+ "value": ""
122
+ }
123
+ ]
124
+ }
125
+ ],
126
+ "practices": [
127
+ {
128
+ "@type": "Practice",
129
+ "term.termType": "tillage",
130
+ "value": ""
131
+ },
132
+ {
133
+ "@type": "Practice",
134
+ "term.termType": "waterRegime",
135
+ "name": "irrigated",
136
+ "value": "",
137
+ "startDate": "",
138
+ "endDate": ""
139
+ }
140
+ ],
141
+ "optional": {
142
+ "startDate": ""
143
+ }
144
+ }]
145
+ }
146
+ }
147
+ }
148
+ LOOKUPS = {
37
149
  "crop": "IPCC_LAND_USE_CATEGORY",
38
150
  "landCover": "IPCC_LAND_USE_CATEGORY",
39
151
  "tillage": "IPCC_TILLAGE_MANAGEMENT_CATEGORY"
40
152
  }
153
+ RETURNS = {
154
+ "Measurement": [{
155
+ "value": "",
156
+ "sd": "",
157
+ "min": "",
158
+ "max": "",
159
+ "statsDefinition": "simulated",
160
+ "observations": "",
161
+ "dates": "",
162
+ "depthUpper": "0",
163
+ "depthLower": "30",
164
+ "methodClassification": "tier 2 model"
165
+ }]
166
+ }
41
167
 
42
168
  TERM_ID = 'organicCarbonPerHa'
43
169
  _METHOD_CLASSIFICATION = MeasurementMethodClassification.TIER_2_MODEL.value
@@ -124,7 +250,7 @@ def _measurement(
124
250
  dict
125
251
  A valid HESTIA `Measurement` node, see: https://www.hestia.earth/schema/Measurement.
126
252
  """
127
- measurement = _new_measurement(TERM_ID) | descriptive_stats_dict
253
+ measurement = _new_measurement(TERM_ID, MODEL) | descriptive_stats_dict
128
254
  measurement["dates"] = [f"{year}-12-31" for year in timestamps]
129
255
  measurement["depthUpper"] = DEPTH_UPPER
130
256
  measurement["depthLower"] = DEPTH_LOWER
@@ -1173,7 +1299,7 @@ def _compile_inventory(
1173
1299
  TODO: implement long-term average climate data and annual climate data as back ups for monthly data
1174
1300
  TODO: implement randomisation for `irrigationMonthly` if `startDate` and `endDate` are not provided
1175
1301
  """
1176
- grouped_cycles = group_nodes_by_year(cycles)
1302
+ grouped_cycles = group_nodes_by_year(cycles, include_spillovers=True)
1177
1303
  grouped_measurements = group_nodes_by_year(measurement_nodes, mode=GroupNodesByYearMode.DATES)
1178
1304
 
1179
1305
  grouped_climate_data = _get_grouped_climate_measurements(grouped_measurements)
@@ -1322,9 +1448,23 @@ def _get_carbon_sources(cycle: dict) -> list[CarbonSource]:
1322
1448
  A formatted list of `CarbonSource`s.
1323
1449
  """
1324
1450
  inputs_and_products = cycle.get("inputs", []) + cycle.get("products", [])
1451
+
1452
+ group_fac = cycle.get('fraction_of_group_duration')
1453
+ node_fac = cycle.get('fraction_of_node_duration')
1454
+
1455
+ scaling_fac = group_fac if round(group_fac * 100) >= round(node_fac * 100) else 1
1456
+
1457
+ kwargs = {
1458
+ "cycle": cycle,
1459
+ "scaling_factor": scaling_fac
1460
+ }
1461
+
1325
1462
  return non_empty_list([
1326
1463
  next(
1327
- (_func(node, cycle) for validator, _func in _CARBON_SOURCE_DECISION_TREE.items() if validator(node)),
1464
+ (
1465
+ _func(node, **kwargs) for validator, _func in _CARBON_SOURCE_DECISION_TREE.items()
1466
+ if validator(node)
1467
+ ),
1328
1468
  None
1329
1469
  ) for node in inputs_and_products
1330
1470
  ])
@@ -1348,7 +1488,9 @@ def _should_run_carbon_source_ag_residue(node: dict) -> bool:
1348
1488
  return node.get("term", {}).get("@id") == _ABOVE_GROUND_CROP_RESIDUE_TOTAL_TERM_ID
1349
1489
 
1350
1490
 
1351
- def _calc_carbon_source_ag_crop_residue(node: dict, cycle: dict) -> Union[CarbonSource, None]:
1491
+ def _calc_carbon_source_ag_crop_residue(
1492
+ node: dict, *, cycle: dict, scaling_factor: float, **_
1493
+ ) -> Union[CarbonSource, None]:
1352
1494
  """
1353
1495
  Extract and format the carbon source data for above-ground crop residues.
1354
1496
 
@@ -1360,6 +1502,11 @@ def _calc_carbon_source_ag_crop_residue(node: dict, cycle: dict) -> Union[Carbon
1360
1502
  ----------
1361
1503
  node : dict
1362
1504
  A HESTIA [Product](https://www.hestia.earth/schema/Product) node with `term.termType` == `landCover`.
1505
+ cycle : dict
1506
+ The HESTIA [Cycle](https://www.hestia.earth/schema/Cycle) that produces the crop residue.
1507
+ scaling_factor : float
1508
+ The scaling factor for the mass of carbon input, calculated by estimating how much the cycle overlaps
1509
+ with the current inventory year.
1363
1510
 
1364
1511
  Returns
1365
1512
  -------
@@ -1371,7 +1518,7 @@ def _calc_carbon_source_ag_crop_residue(node: dict, cycle: dict) -> Union[Carbon
1371
1518
  get_node_value(practice) for practice in cycle.get("practices", [])
1372
1519
  if node_term_match(practice, _CROP_RESIDUE_MANAGEMENT_TERM_IDS)
1373
1520
  ])
1374
- mass = value * max(residue_left_on_field, _MIN_RESIDUE_LEFT_ON_FIELD) / 100
1521
+ mass = value * max(residue_left_on_field, _MIN_RESIDUE_LEFT_ON_FIELD) * scaling_factor / 100
1375
1522
 
1376
1523
  carbon_content, nitrogen_content, lignin_content, dry_matter = _retrieve_carbon_source_properties(node)
1377
1524
 
@@ -1400,7 +1547,7 @@ def _should_run_carbon_source_cover_crop(node: dict) -> bool:
1400
1547
  bool
1401
1548
  Whether the node satisfies the critera.
1402
1549
  """
1403
- LOOKUP = _LOOKUPS["landCover"]
1550
+ LOOKUP = LOOKUPS["landCover"]
1404
1551
  TARGET_LOOKUP_VALUES = IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE[IpccLandUseCategory.ANNUAL_CROPS]
1405
1552
 
1406
1553
  return (
@@ -1410,7 +1557,7 @@ def _should_run_carbon_source_cover_crop(node: dict) -> bool:
1410
1557
  )
1411
1558
 
1412
1559
 
1413
- def _calc_carbon_source_cover_crop(node: dict, *_) -> Union[CarbonSource, None]:
1560
+ def _calc_carbon_source_cover_crop(node: dict, *, scaling_factor: float, **_) -> Union[CarbonSource, None]:
1414
1561
  """
1415
1562
  Extract and format the carbon source data for an annual cover crop.
1416
1563
 
@@ -1420,6 +1567,9 @@ def _calc_carbon_source_cover_crop(node: dict, *_) -> Union[CarbonSource, None]:
1420
1567
  ----------
1421
1568
  node : dict
1422
1569
  A HESTIA [Product](https://www.hestia.earth/schema/Product) node with `term.termType` == `landCover`.
1570
+ scaling_factor : float
1571
+ The scaling factor for the mass of carbon input, calculated by estimating how much the cycle overlaps
1572
+ with the current inventory year.
1423
1573
 
1424
1574
  Returns
1425
1575
  -------
@@ -1428,7 +1578,7 @@ def _calc_carbon_source_cover_crop(node: dict, *_) -> Union[CarbonSource, None]:
1428
1578
  """
1429
1579
  value = get_node_value(node)
1430
1580
  carbon_source = CarbonSource(
1431
- _DEFAULT_COVER_CROP_BIOMASS * value / 100,
1581
+ _DEFAULT_COVER_CROP_BIOMASS * value * scaling_factor / 100,
1432
1582
  _Parameter.DEFAULT_CARBON_CONTENT.value.get("value"),
1433
1583
  _Parameter.DEFAULT_NITROGEN_CONTENT.value.get("value"),
1434
1584
  _Parameter.DEFAULT_NITROGEN_CONTENT.value.get("value")
@@ -1457,7 +1607,7 @@ def _should_run_carbon_source(node: dict) -> bool:
1457
1607
  ])
1458
1608
 
1459
1609
 
1460
- def _calc_carbon_source(node: dict, *_) -> Union[CarbonSource, None]:
1610
+ def _calc_carbon_source(node: dict, *, scaling_factor: float, **_) -> Union[CarbonSource, None]:
1461
1611
  """
1462
1612
  Extract and format the carbon source data for an input or product.
1463
1613
 
@@ -1466,13 +1616,17 @@ def _calc_carbon_source(node: dict, *_) -> Union[CarbonSource, None]:
1466
1616
  node : dict
1467
1617
  A HESTIA [Input](https://www.hestia.earth/schema/Input) or [Product](https://www.hestia.earth/schema/Product)
1468
1618
  node.
1619
+ scaling_factor : float
1620
+ The scaling factor for the mass of carbon input, calculated by estimating how much the cycle overlaps
1621
+ with the current inventory year.
1622
+
1469
1623
 
1470
1624
  Returns
1471
1625
  -------
1472
1626
  CarbonSource | None
1473
1627
  The carbon source data of the cover crop, or `None` if carbon source data incomplete.
1474
1628
  """
1475
- mass = get_node_value(node)
1629
+ mass = get_node_value(node) * scaling_factor
1476
1630
  carbon_content, nitrogen_content, lignin_content, dry_matter = _retrieve_carbon_source_properties(node)
1477
1631
 
1478
1632
  carbon_source = CarbonSource(
@@ -1673,7 +1827,7 @@ def _check_cycle_tillage_management_category(
1673
1827
  bool
1674
1828
  Whether or not the cycle meets the requirements for the category.
1675
1829
  """
1676
- LOOKUP = _LOOKUPS["tillage"]
1830
+ LOOKUP = LOOKUPS["tillage"]
1677
1831
  target_lookup_values = IPCC_MANAGEMENT_CATEGORY_TO_TILLAGE_MANAGEMENT_LOOKUP_VALUE.get(key, None)
1678
1832
 
1679
1833
  practices = cycle.get("practices", [])
@@ -1720,7 +1874,7 @@ def _get_grouped_is_paddy_rice(grouped_cycles: dict) -> dict:
1720
1874
 
1721
1875
 
1722
1876
  def _check_is_paddy_rice(cycles: list[dict]) -> bool:
1723
- LOOKUP = _LOOKUPS["crop"]
1877
+ LOOKUP = LOOKUPS["crop"]
1724
1878
  TARGET_LOOKUP_VALUES = IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE.get(
1725
1879
  IpccLandUseCategory.PADDY_RICE_CULTIVATION, None
1726
1880
  )
@@ -1,13 +1,15 @@
1
1
  from enum import Enum
2
+ from numpy import inf
2
3
  from numpy.typing import NDArray
3
4
  from typing import NamedTuple, Optional
4
5
 
5
6
  from hestia_earth.schema import MeasurementStatsDefinition, SiteSiteType
6
7
 
7
8
  from hestia_earth.models.utils.array_builders import (
8
- repeat_single, plus_minus_uncertainty_to_normal_1d, truncated_normal_1d
9
+ repeat_single, truncated_normal_1d
9
10
  )
10
11
  from hestia_earth.models.utils.blank_node import cumulative_nodes_term_match, node_term_match
12
+ from hestia_earth.models.utils.stats import calc_z_critical
11
13
  from hestia_earth.models.utils.term import get_cover_crop_property_terms, get_irrigated_terms
12
14
 
13
15
  STATS_DEFINITION = MeasurementStatsDefinition.SIMULATED.value
@@ -238,7 +240,9 @@ def sample_plus_minus_uncertainty(
238
240
  *, iterations: int, value: float, uncertainty: float, seed: Optional[int] = None, **_
239
241
  ) -> NDArray:
240
242
  """Randomly sample a model parameter with a plus/minus uncertainty distribution."""
241
- return plus_minus_uncertainty_to_normal_1d(shape=(1, iterations), value=value, uncertainty=uncertainty, seed=seed)
243
+ n_sds = calc_z_critical(95)
244
+ sigma = (value * (uncertainty / 100)) / n_sds
245
+ return truncated_normal_1d(shape=(1, iterations), mu=value, sigma=sigma, low=0, high=inf, seed=seed)
242
246
 
243
247
 
244
248
  def sample_plus_minus_error(
@@ -246,9 +250,7 @@ def sample_plus_minus_error(
246
250
  ) -> NDArray:
247
251
  """Randomly sample a model parameter with a truncated normal distribution described using plus/minus error."""
248
252
  sd = value * (error / 200)
249
- low = value - (value * (error / 100))
250
- high = value + (value * (error / 100))
251
- return truncated_normal_1d(shape=(1, iterations), mu=value, sigma=sd, low=low, high=high, seed=seed)
253
+ return truncated_normal_1d(shape=(1, iterations), mu=value, sigma=sd, low=0, high=inf, seed=seed)
252
254
 
253
255
 
254
256
  def sample_constant(*, iterations: int, value: float, **_) -> NDArray:
@@ -39,7 +39,7 @@ def _run_practice(cycle: dict, ratio: float, practice: dict):
39
39
  rescale_ratio=ratio,
40
40
  value_before_rescale=value)
41
41
  logShouldRun(cycle, MODEL, term.get('@id'), True)
42
- return _practice(term, round(value * ratio, 2))
42
+ return _practice(term, round(value * ratio, 7))
43
43
 
44
44
 
45
45
  def _run(cycle: dict):
@@ -45,7 +45,7 @@ def _get_default_percent(cycle: dict, term: dict, country_id: str):
45
45
  def _run(cycle: dict, remaining_value: float, primary_product: dict, country_id: str):
46
46
  term = primary_product.get('term', {})
47
47
  value = _get_default_percent(cycle, term, country_id)
48
- return [] if value is None else [_practice(TERM_ID, min(round(value * 100, 2), remaining_value))]
48
+ return [] if value is None else [_practice(TERM_ID, min(round(value * 100, 7), remaining_value))]
49
49
 
50
50
 
51
51
  def run(cycle: dict):
@@ -43,7 +43,7 @@ def _get_default_percent(cycle: dict, term: dict, country_id: str):
43
43
  def _run(cycle: dict, remaining_value: float, primary_product: dict, country_id: str):
44
44
  term = primary_product.get('term', {})
45
45
  value = _get_default_percent(cycle, term, country_id)
46
- return [] if value is None else [_practice(TERM_ID, min(round(value * 100, 2), remaining_value))]
46
+ return [] if value is None else [_practice(TERM_ID, min(round(value * 100, 7), remaining_value))]
47
47
 
48
48
 
49
49
  def run(cycle: dict):
@@ -43,7 +43,7 @@ def _should_run(term_id: str, cycle: dict, require_country: bool = False):
43
43
  not is_from_model(p)
44
44
  ])
45
45
  ]
46
- has_provided_cropResidue_products = len(provided_cropResidue_products) > 0
46
+ no_provided_cropResidue_products = len(provided_cropResidue_products) == 0
47
47
 
48
48
  country_id = cycle.get('site', {}).get('country', {}).get('@id')
49
49
 
@@ -53,13 +53,13 @@ def _should_run(term_id: str, cycle: dict, require_country: bool = False):
53
53
  has_remaining_value=has_remaining_value,
54
54
  crop_residue_values=residue_values,
55
55
  country_id=country_id,
56
- has_provided_cropResidue_products=has_provided_cropResidue_products,
56
+ no_provided_cropResidue_products=no_provided_cropResidue_products,
57
57
  provided_cropResidue_product_ids=log_blank_nodes_id(provided_cropResidue_products))
58
58
 
59
59
  should_run = all([
60
60
  has_primary_product, crop_residue_incomplete, has_remaining_value,
61
61
  not require_country or country_id,
62
- not has_provided_cropResidue_products
62
+ no_provided_cropResidue_products
63
63
  ])
64
64
  logShouldRun(cycle, MODEL, term_id, should_run)
65
65
  return should_run, remaining_value, primary_product, country_id