hestia-earth-models 0.64.12__py3-none-any.whl → 0.64.13__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.

Potentially problematic release.


This version of hestia-earth-models might be problematic. Click here for more details.

Files changed (184) hide show
  1. hestia_earth/models/aware/scarcityWeightedWaterUse.py +1 -1
  2. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandOccupation.py +1 -1
  3. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandTransformation.py +1 -1
  4. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsTotalLandUseEffects.py +3 -2
  5. hestia_earth/models/cml2001Baseline/eutrophicationPotentialExcludingFate.py +2 -2
  6. hestia_earth/models/cml2001Baseline/terrestrialAcidificationPotentialIncludingFateAverageEurope.py +2 -2
  7. hestia_earth/models/cml2001NonBaseline/eutrophicationPotentialIncludingFateAverageEurope.py +2 -2
  8. hestia_earth/models/cml2001NonBaseline/terrestrialAcidificationPotentialExcludingFate.py +2 -2
  9. hestia_earth/models/cycle/completeness/seed.py +6 -4
  10. hestia_earth/models/cycle/concentrateFeed.py +9 -4
  11. hestia_earth/models/cycle/endDate.py +10 -1
  12. hestia_earth/models/cycle/milkYield.py +6 -5
  13. hestia_earth/models/cycle/startDate.py +6 -4
  14. hestia_earth/models/edip2003/ozoneDepletionPotential.py +2 -2
  15. hestia_earth/models/emissionNotRelevant/__init__.py +3 -2
  16. hestia_earth/models/environmentalFootprintV3/freshwaterEcotoxicityPotentialCtue.py +2 -3
  17. hestia_earth/models/hestia/landCover.py +28 -26
  18. hestia_earth/models/ipcc2013ExcludingFeedbacks/gwp100.py +2 -2
  19. hestia_earth/models/ipcc2013IncludingFeedbacks/gwp100.py +2 -2
  20. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +4 -8
  21. hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +2 -2
  22. hestia_earth/models/ipcc2019/belowGroundBiomass.py +4 -8
  23. hestia_earth/models/ipcc2019/biomass_utils.py +11 -0
  24. hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +1 -1
  25. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +7 -3
  26. hestia_earth/models/ipcc2019/n2OToAirExcretaDirect.py +14 -9
  27. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +9 -3
  28. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +1 -2
  29. hestia_earth/models/koble2014/aboveGroundCropResidue.py +5 -1
  30. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsClimateChange.py +2 -2
  31. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  32. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  33. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealth.py +2 -2
  34. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthClimateChange.py +2 -2
  35. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  36. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  37. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  38. hestia_earth/models/lcImpactAllEffects100Years/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  39. hestia_earth/models/lcImpactAllEffects100Years/damageToMarineEcosystemsPdfYear.py +2 -2
  40. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  41. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  42. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  43. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsClimateChange.py +2 -2
  44. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  45. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  46. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealth.py +2 -2
  47. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthClimateChange.py +2 -2
  48. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  49. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  50. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  51. hestia_earth/models/lcImpactAllEffectsInfinite/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  52. hestia_earth/models/lcImpactAllEffectsInfinite/damageToMarineEcosystemsPdfYear.py +2 -2
  53. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  54. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  55. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  56. hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  57. hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  58. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealth.py +2 -2
  59. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthClimateChange.py +2 -2
  60. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  61. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  62. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  63. hestia_earth/models/lcImpactCertainEffects100Years/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  64. hestia_earth/models/lcImpactCertainEffects100Years/damageToMarineEcosystemsPdfYear.py +2 -2
  65. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  66. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  67. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  68. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  69. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  70. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealth.py +2 -2
  71. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthClimateChange.py +2 -2
  72. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  73. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  74. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  75. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  76. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToMarineEcosystemsPdfYear.py +2 -2
  77. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  78. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  79. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  80. hestia_earth/models/linkedImpactAssessment/emissions.py +3 -0
  81. hestia_earth/models/log.py +4 -3
  82. hestia_earth/models/mocking/search-results.json +471 -471
  83. hestia_earth/models/pooreNemecek2018/excretaKgN.py +4 -4
  84. hestia_earth/models/pooreNemecek2018/excretaKgVs.py +4 -4
  85. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterCropResidueDecomposition.py +1 -1
  86. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterExcreta.py +1 -1
  87. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterInorganicFertiliser.py +1 -1
  88. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterOrganicFertiliser.py +1 -1
  89. hestia_earth/models/pooreNemecek2018/{saplings.py → saplingsDepreciatedAmountPerCycle.py} +1 -1
  90. hestia_earth/models/pooreNemecek2018/utils.py +7 -1
  91. hestia_earth/models/recipe2016Egalitarian/damageToFreshwaterEcosystemsSpeciesYear.py +2 -2
  92. hestia_earth/models/recipe2016Egalitarian/damageToHumanHealth.py +2 -2
  93. hestia_earth/models/recipe2016Egalitarian/damageToMarineEcosystemsSpeciesYear.py +2 -2
  94. hestia_earth/models/recipe2016Egalitarian/damageToTerrestrialEcosystemsSpeciesYear.py +2 -2
  95. hestia_earth/models/recipe2016Egalitarian/freshwaterAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  96. hestia_earth/models/recipe2016Egalitarian/freshwaterEutrophicationPotential.py +2 -2
  97. hestia_earth/models/recipe2016Egalitarian/humanCarcinogenicToxicity.py +2 -3
  98. hestia_earth/models/recipe2016Egalitarian/humanNonCarcinogenicToxicity.py +2 -3
  99. hestia_earth/models/recipe2016Egalitarian/marineAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  100. hestia_earth/models/recipe2016Egalitarian/marineEutrophicationPotential.py +2 -2
  101. hestia_earth/models/recipe2016Egalitarian/ozoneDepletionPotential.py +2 -2
  102. hestia_earth/models/recipe2016Egalitarian/terrestrialAcidificationPotential.py +2 -2
  103. hestia_earth/models/recipe2016Egalitarian/terrestrialEcotoxicityPotential14Dcbeq.py +2 -3
  104. hestia_earth/models/recipe2016Hierarchist/damageToFreshwaterEcosystemsSpeciesYear.py +2 -2
  105. hestia_earth/models/recipe2016Hierarchist/damageToHumanHealth.py +2 -2
  106. hestia_earth/models/recipe2016Hierarchist/damageToMarineEcosystemsSpeciesYear.py +2 -2
  107. hestia_earth/models/recipe2016Hierarchist/damageToTerrestrialEcosystemsSpeciesYear.py +2 -2
  108. hestia_earth/models/recipe2016Hierarchist/freshwaterAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  109. hestia_earth/models/recipe2016Hierarchist/freshwaterEutrophicationPotential.py +2 -2
  110. hestia_earth/models/recipe2016Hierarchist/humanCarcinogenicToxicity.py +2 -3
  111. hestia_earth/models/recipe2016Hierarchist/humanNonCarcinogenicToxicity.py +2 -3
  112. hestia_earth/models/recipe2016Hierarchist/marineAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  113. hestia_earth/models/recipe2016Hierarchist/marineEutrophicationPotential.py +2 -2
  114. hestia_earth/models/recipe2016Hierarchist/ozoneDepletionPotential.py +2 -2
  115. hestia_earth/models/recipe2016Hierarchist/terrestrialAcidificationPotential.py +2 -2
  116. hestia_earth/models/recipe2016Hierarchist/terrestrialEcotoxicityPotential14Dcbeq.py +2 -3
  117. hestia_earth/models/recipe2016Individualist/damageToFreshwaterEcosystemsSpeciesYear.py +2 -2
  118. hestia_earth/models/recipe2016Individualist/damageToHumanHealth.py +2 -2
  119. hestia_earth/models/recipe2016Individualist/damageToMarineEcosystemsSpeciesYear.py +2 -2
  120. hestia_earth/models/recipe2016Individualist/damageToTerrestrialEcosystemsSpeciesYear.py +2 -2
  121. hestia_earth/models/recipe2016Individualist/freshwaterAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  122. hestia_earth/models/recipe2016Individualist/freshwaterEutrophicationPotential.py +2 -2
  123. hestia_earth/models/recipe2016Individualist/humanCarcinogenicToxicity.py +2 -3
  124. hestia_earth/models/recipe2016Individualist/humanNonCarcinogenicToxicity.py +2 -3
  125. hestia_earth/models/recipe2016Individualist/marineAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  126. hestia_earth/models/recipe2016Individualist/marineEutrophicationPotential.py +2 -2
  127. hestia_earth/models/recipe2016Individualist/ozoneDepletionPotential.py +2 -2
  128. hestia_earth/models/recipe2016Individualist/terrestrialAcidificationPotential.py +2 -2
  129. hestia_earth/models/recipe2016Individualist/terrestrialEcotoxicityPotential14Dcbeq.py +2 -3
  130. hestia_earth/models/site/management.py +142 -144
  131. hestia_earth/models/stehfestBouwman2006/n2OToAirCropResidueDecompositionDirect.py +1 -1
  132. hestia_earth/models/stehfestBouwman2006/n2OToAirExcretaDirect.py +1 -1
  133. hestia_earth/models/stehfestBouwman2006/n2OToAirInorganicFertiliserDirect.py +1 -1
  134. hestia_earth/models/stehfestBouwman2006/n2OToAirOrganicFertiliserDirect.py +1 -1
  135. hestia_earth/models/stehfestBouwman2006/noxToAirCropResidueDecomposition.py +1 -1
  136. hestia_earth/models/stehfestBouwman2006/noxToAirExcreta.py +1 -1
  137. hestia_earth/models/stehfestBouwman2006/noxToAirInorganicFertiliser.py +1 -1
  138. hestia_earth/models/stehfestBouwman2006/noxToAirOrganicFertiliser.py +1 -1
  139. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirCropResidueDecomposition.py +1 -1
  140. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirExcreta.py +1 -1
  141. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirInorganicFertiliser.py +1 -1
  142. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirOrganicFertiliser.py +1 -1
  143. hestia_earth/models/usetoxV2/freshwaterEcotoxicityPotentialCtue.py +2 -3
  144. hestia_earth/models/utils/__init__.py +4 -1
  145. hestia_earth/models/utils/blank_node.py +34 -14
  146. hestia_earth/models/utils/emission.py +1 -8
  147. hestia_earth/models/utils/management.py +11 -0
  148. hestia_earth/models/utils/pesticideAI.py +11 -17
  149. hestia_earth/models/utils/term.py +2 -1
  150. hestia_earth/models/version.py +1 -1
  151. {hestia_earth_models-0.64.12.dist-info → hestia_earth_models-0.64.13.dist-info}/METADATA +4 -4
  152. {hestia_earth_models-0.64.12.dist-info → hestia_earth_models-0.64.13.dist-info}/RECORD +180 -183
  153. {hestia_earth_models-0.64.12.dist-info → hestia_earth_models-0.64.13.dist-info}/WHEEL +1 -1
  154. tests/models/cycle/completeness/test_seed.py +1 -1
  155. tests/models/cycle/test_endDate.py +18 -2
  156. tests/models/cycle/test_startDate.py +21 -3
  157. tests/models/hestia/test_landCover.py +3 -2
  158. tests/models/ipcc2019/test_aboveGroundBiomass.py +2 -1
  159. tests/models/ipcc2019/test_belowGroundBiomass.py +2 -1
  160. tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +4 -3
  161. tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +3 -3
  162. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +1 -1
  163. tests/models/ipcc2019/test_n2OToAirExcretaDirect.py +12 -0
  164. tests/models/ipcc2019/test_organicCarbonPerHa.py +1 -0
  165. tests/models/koble2014/test_aboveGroundCropResidue.py +13 -0
  166. tests/models/pooreNemecek2018/test_no3ToGroundwaterCropResidueDecomposition.py +3 -2
  167. tests/models/pooreNemecek2018/test_no3ToGroundwaterExcreta.py +3 -2
  168. tests/models/pooreNemecek2018/test_no3ToGroundwaterInorganicFertiliser.py +3 -2
  169. tests/models/pooreNemecek2018/test_no3ToGroundwaterOrganicFertiliser.py +3 -2
  170. tests/models/pooreNemecek2018/{test_saplings.py → test_saplingsDepreciatedAmountPerCycle.py} +1 -1
  171. tests/models/site/test_management.py +18 -151
  172. tests/models/utils/test_blank_node.py +57 -1
  173. tests/models/utils/test_emission.py +1 -6
  174. tests/models/utils/test_site.py +33 -2
  175. tests/models/pooreNemecek2018/test_no3ToGroundwaterSoilFlux.py +0 -90
  176. tests/models/stehfestBouwman2006/test_n2OToAirSoilFlux.py +0 -41
  177. tests/models/stehfestBouwman2006/test_noxToAirSoilFlux.py +0 -40
  178. tests/models/stehfestBouwman2006GisImplementation/test_noxToAirSoilFlux.py +0 -33
  179. /hestia_earth/models/pooreNemecek2018/{no3ToGroundwaterSoilFlux.py → no3ToGroundwaterSoilFlux_utils.py} +0 -0
  180. /hestia_earth/models/stehfestBouwman2006/{n2OToAirSoilFlux.py → n2OToAirSoilFlux_utils.py} +0 -0
  181. /hestia_earth/models/stehfestBouwman2006/{noxToAirSoilFlux.py → noxToAirSoilFlux_utils.py} +0 -0
  182. /hestia_earth/models/stehfestBouwman2006GisImplementation/{noxToAirSoilFlux.py → noxToAirSoilFlux_utils.py} +0 -0
  183. {hestia_earth_models-0.64.12.dist-info → hestia_earth_models-0.64.13.dist-info}/LICENSE +0 -0
  184. {hestia_earth_models-0.64.12.dist-info → hestia_earth_models-0.64.13.dist-info}/top_level.txt +0 -0
@@ -102,7 +102,7 @@ def _run(impact_assessment: dict):
102
102
  multiply_values([fresh_water, factor]),
103
103
  inputs_value
104
104
  ])
105
- return _indicator(value)
105
+ return _indicator(value) if value is not None else None
106
106
 
107
107
 
108
108
  def _should_run(impact_assessment: dict):
@@ -83,7 +83,7 @@ def _run(impact_assessment: dict):
83
83
  multiply_values([land_occupation_m2_kg, factor]),
84
84
  inputs_value
85
85
  ])
86
- return _indicator(value)
86
+ return _indicator(value) if value is not None else None
87
87
 
88
88
 
89
89
  def _should_run(impact_assessment: dict):
@@ -81,7 +81,7 @@ def _run(impact_assessment: dict):
81
81
  multiply_values([landTransformation, region_factor]),
82
82
  inputs_value
83
83
  ])
84
- return _indicator(value)
84
+ return _indicator(value) if value is not None else None
85
85
 
86
86
 
87
87
  def _should_run(impact_assessment: dict):
@@ -59,8 +59,9 @@ def run(impact_assessment: dict):
59
59
  inputs_value = convert_value_from_cycle(
60
60
  product, sum_input_impacts(cycle.get('inputs', []), TERM_ID), model=MODEL, term_id=TERM_ID
61
61
  )
62
+ value = sum_values([landUseEffects, inputs_value])
62
63
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
63
64
  landUseEffects=landUseEffects,
64
65
  inputs_value=inputs_value)
65
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
66
- return _indicator(sum_values([landUseEffects, inputs_value]))
66
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
67
+ return _indicator(value) if value is not None else None
@@ -29,5 +29,5 @@ def run(impact_assessment: dict):
29
29
  value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['emission'])
30
30
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
31
31
  value=value)
32
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
33
- return _indicator(value)
32
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
33
+ return _indicator(value) if value is not None else None
@@ -29,5 +29,5 @@ def run(impact_assessment: dict):
29
29
  value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['emission'])
30
30
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
31
31
  value=value)
32
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
33
- return _indicator(value)
32
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
33
+ return _indicator(value) if value is not None else None
@@ -29,5 +29,5 @@ def run(impact_assessment: dict):
29
29
  value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['emission'])
30
30
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
31
31
  value=value)
32
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
33
- return _indicator(value)
32
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
33
+ return _indicator(value) if value is not None else None
@@ -29,5 +29,5 @@ def run(impact_assessment: dict):
29
29
  value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['emission'])
30
30
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
31
31
  value=value)
32
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
33
- return _indicator(value)
32
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
33
+ return _indicator(value) if value is not None else None
@@ -15,7 +15,7 @@ REQUIREMENTS = {
15
15
  "Cycle": {
16
16
  "completeness.seed": "False",
17
17
  "inputs": [
18
- {"@type": "Input", "value": "", "term.@id": ["seed", "saplings"]}
18
+ {"@type": "Input", "value": "", "term.@id": ["seed", "saplingsDepreciatedAmountPerCycle"]}
19
19
  ],
20
20
  "site": {
21
21
  "@type": "Site",
@@ -46,11 +46,13 @@ def run(cycle: dict):
46
46
 
47
47
  product = find_primary_product(cycle) or {}
48
48
  term_id = product.get('term', {}).get('@id')
49
- has_saplings = find_term_match(cycle.get('inputs', []), 'saplings', None) and is_plantation(MODEL, None, term_id)
49
+ has_saplingsDepreciatedAmountPerCycle = find_term_match(cycle.get('inputs', []),
50
+ 'saplingsDepreciatedAmountPerCycle',
51
+ None) and is_plantation(MODEL, None, term_id)
50
52
 
51
53
  logRequirements(cycle, model=MODEL, term=None, key=MODEL_KEY,
52
54
  site_type_allowed=site_type_allowed,
53
55
  has_seed=has_seed,
54
- has_saplings=has_saplings)
56
+ has_saplingsDepreciatedAmountPerCycle=has_saplingsDepreciatedAmountPerCycle)
55
57
 
56
- return all([site_type_allowed, has_seed or has_saplings])
58
+ return all([site_type_allowed, has_seed or has_saplingsDepreciatedAmountPerCycle])
@@ -72,7 +72,7 @@ def _calculate_value(cycle: dict, product: dict, inputs: list, property_id: str,
72
72
  valid_values = [
73
73
  (value.get('property-value'), value.get('input-value'))
74
74
  for value in values
75
- if all([value.get('property-value'), value.get('input-value')])
75
+ if all([value.get('property-value') is not None, value.get('input-value') is not None])
76
76
  ]
77
77
  ratio_inputs_with_props = len(valid_values) / len(inputs) if len(inputs) and len(valid_values) else 0
78
78
  min_ratio = _min_ratio(property_id)
@@ -106,15 +106,20 @@ def _calculate_default_value(cycle: dict, product: dict, inputs: list, property_
106
106
 
107
107
  def _calculate_N_value(cycle: dict, product: dict, inputs: list, property_id: str):
108
108
  term_id = product.get('term', {}).get('@id')
109
+
110
+ def fallback_value(input: dict):
111
+ value = get_node_property_value(
112
+ MODEL, input, 'crudeProteinContent', handle_percents=False, term=term_id, property=property_id
113
+ )
114
+ return value * 0.16 if value is not None else None
115
+
109
116
  values = [{
110
117
  'input-id': i.get('term', {}).get('@id'),
111
118
  'input-value': list_sum(i.get('value', [])),
112
119
  'property-id': property_id,
113
120
  'property-value': get_node_property_value(
114
121
  MODEL, i, property_id, handle_percents=False, term=term_id, property=property_id
115
- ) or get_node_property_value(
116
- MODEL, i, 'crudeProteinContent', default=0, handle_percents=False, term=term_id, property=property_id
117
- ) * 0.16
122
+ ) or fallback_value(input=i)
118
123
  } for i in inputs]
119
124
  return _calculate_value(cycle, product, inputs, property_id, values)
120
125
 
@@ -8,6 +8,7 @@ assumed it ended on the 14th of the month.
8
8
  from hestia_earth.utils.date import is_in_months
9
9
 
10
10
  from hestia_earth.models.log import logRequirements, logShouldRun
11
+ from hestia_earth.models.utils import last_day_of_month
11
12
  from . import MODEL
12
13
 
13
14
  REQUIREMENTS = {
@@ -24,9 +25,17 @@ RETURNS = {
24
25
  MODEL_KEY = 'endDate'
25
26
 
26
27
 
28
+ def _end_of_month(date: str):
29
+ year = int(date[0:4])
30
+ month = int(date[5:7])
31
+ return last_day_of_month(year, month).strftime('%Y-%m-%d')
32
+
33
+
27
34
  def _run(cycle: dict):
28
35
  endDate = cycle.get('endDate')
29
- return f"{endDate}-14"
36
+ is_same_month = endDate[0:7] == cycle.get('startDate', '')[0:7]
37
+ # end of the month if same month as startDate
38
+ return _end_of_month(endDate) if is_same_month else f"{endDate}-14"
30
39
 
31
40
 
32
41
  def _should_run(cycle: dict):
@@ -87,15 +87,16 @@ def _run(cycle: dict, product: dict):
87
87
 
88
88
  live_animal_term_id = get_liveAnimal_term_id(product, model_key=MODEL_KEY)
89
89
  live_animal_node = find_term_match(cycle.get('animals', []), live_animal_term_id)
90
+ animal_value = live_animal_node.get('value', 0)
90
91
 
91
- value = list_sum(product.get('value')) / cycleDuration / live_animal_node.get('value')
92
- sd = list_sum(product.get('sd')) / cycleDuration / live_animal_node.get('value') if all([
92
+ value = list_sum(product.get('value')) / cycleDuration / animal_value
93
+ sd = list_sum(product.get('sd')) / cycleDuration / animal_value if all([
93
94
  list_sum(product.get('sd', [])) > 0
94
95
  ]) else None
95
- min = list_sum(product.get('min')) / cycleDuration / live_animal_node.get('value') if all([
96
+ min = list_sum(product.get('min')) / cycleDuration / animal_value if all([
96
97
  list_sum(product.get('min', [])) > 0
97
98
  ]) else None
98
- max = list_sum(product.get('max')) / cycleDuration / live_animal_node.get('value') if all([
99
+ max = list_sum(product.get('max')) / cycleDuration / animal_value if all([
99
100
  list_sum(product.get('max', [])) > 0
100
101
  ]) else None
101
102
 
@@ -136,7 +137,7 @@ def _should_run_product(cycle: dict, product: dict):
136
137
  missing_milkYield_practice=missing_milkYield_practice)
137
138
 
138
139
  should_run = all([
139
- has_product_value, has_live_animal_node_value, practice_id, missing_milkYield_practice
140
+ cycleDuration, has_product_value, has_live_animal_node_value, practice_id, missing_milkYield_practice
140
141
  ])
141
142
  logShouldRun(cycle, MODEL, term_id, should_run, model_key=MODEL_KEY)
142
143
  return should_run
@@ -36,22 +36,24 @@ def _run_by_cycleDuration(cycle: dict):
36
36
 
37
37
  def _should_run_by_cycleDuration(cycle: dict):
38
38
  has_endDate = cycle.get('endDate') is not None
39
- has_day_precision = has_endDate and is_in_days(cycle.get('endDate'))
39
+ has_endDate_day_precision = has_endDate and is_in_days(cycle.get('endDate'))
40
40
  has_cycleDuration = cycle.get('cycleDuration') is not None
41
41
 
42
42
  logRequirements(cycle, model=MODEL, key=MODEL_KEY, by='cycleDuration',
43
43
  has_endDate=has_endDate,
44
- has_day_precision=has_day_precision,
44
+ has_endDate_day_precision=has_endDate_day_precision,
45
45
  has_cycleDuration=has_cycleDuration)
46
46
 
47
- should_run = all([has_endDate, has_day_precision, has_cycleDuration])
47
+ should_run = all([has_endDate, has_endDate_day_precision, has_cycleDuration])
48
48
  logShouldRun(cycle, MODEL, None, should_run, key=MODEL_KEY, by='cycleDuration')
49
49
  return should_run
50
50
 
51
51
 
52
52
  def _run_by_startDate(cycle: dict):
53
53
  startDate = cycle.get('startDate')
54
- return f"{startDate}-15"
54
+ is_same_month = startDate[0:7] == cycle.get('endDate', '')[0:7]
55
+ # start of the month if same month as end date
56
+ return f"{startDate}-01" if is_same_month else f"{startDate}-15"
55
57
 
56
58
 
57
59
  def _should_run_by_startDate(cycle: dict):
@@ -30,5 +30,5 @@ def run(impact_assessment: dict):
30
30
  value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['emission'])
31
31
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
32
32
  value=value)
33
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
34
- return _indicator(value)
33
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
34
+ return _indicator(value) if value is not None else None
@@ -4,9 +4,10 @@ Emission not relevant
4
4
  The emission is not relevant for this Site, Cycle, or Product.
5
5
  """
6
6
  from hestia_earth.schema import NodeType, TermTermType, EmissionMethodTier
7
+ from hestia_earth.utils.emission import emission_is_in_system_boundary
7
8
 
8
9
  from hestia_earth.models.log import logRequirements, logShouldRun
9
- from hestia_earth.models.utils.emission import _new_emission, is_in_system_boundary
10
+ from hestia_earth.models.utils.emission import _new_emission
10
11
  from hestia_earth.models.utils.blank_node import _run_required
11
12
  from hestia_earth.models.utils.term import get_all_emission_terms
12
13
 
@@ -38,7 +39,7 @@ def _emission(term_id: str):
38
39
  def _should_run_emission(cycle: dict):
39
40
  def run(term_id: str):
40
41
  is_not_relevant = not _run_required(MODEL, {'@id': term_id, 'termType': TermTermType.EMISSION.value}, cycle)
41
- in_system_boundary = is_in_system_boundary(term_id)
42
+ in_system_boundary = emission_is_in_system_boundary(term_id)
42
43
 
43
44
  should_run = all([is_not_relevant, in_system_boundary])
44
45
  if should_run:
@@ -1,5 +1,5 @@
1
1
  from hestia_earth.models.utils.indicator import _new_indicator
2
- from hestia_earth.models.utils.pesticideAI import impact_lookup_value, impact_value_set_none
2
+ from hestia_earth.models.utils.pesticideAI import impact_lookup_value
3
3
  from . import MODEL
4
4
 
5
5
  REQUIREMENTS = {
@@ -30,5 +30,4 @@ def _indicator(value: float):
30
30
 
31
31
  def run(impact_assessment: dict):
32
32
  value = impact_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['pesticideAI'])
33
- should_run = any([value is not None, impact_value_set_none(impact_assessment)])
34
- return _indicator(value) if should_run else None
33
+ return _indicator(value) if value is not None else None
@@ -6,17 +6,18 @@ functionality of the Blonk model.
6
6
  """
7
7
  import math
8
8
  from collections import defaultdict
9
-
10
9
  from hestia_earth.schema import SiteSiteType, TermTermType
11
- from hestia_earth.utils.lookup import (download_lookup, get_table_value, column_name,
12
- extract_grouped_data_closest_date, _is_missing_value, extract_grouped_data)
10
+ from hestia_earth.utils.lookup import (
11
+ download_lookup, get_table_value, column_name,
12
+ extract_grouped_data_closest_date, _is_missing_value, extract_grouped_data
13
+ )
13
14
  from hestia_earth.utils.model import filter_list_term_type
14
15
  from hestia_earth.utils.tools import safe_parse_float, to_precision, non_empty_value
15
16
 
16
- from hestia_earth.models.cycle.input.hestiaAggregatedData import MODEL_ID
17
17
  from hestia_earth.models.log import logRequirements, log_as_table, logShouldRun
18
+ from hestia_earth.models.utils.management import _new_management
18
19
  from hestia_earth.models.utils.term import get_lookup_value
19
- from hestia_earth.models.hestia import MODEL
20
+ from . import MODEL
20
21
 
21
22
  REQUIREMENTS = {
22
23
  "Site": {
@@ -46,9 +47,7 @@ RETURNS = {
46
47
  ],
47
48
  "value": "",
48
49
  "endDate": "",
49
- "startDate": "",
50
- "methodModel": "HESTIA",
51
- "methodClassification": ["modelled using other measurements", "expert opinion"]
50
+ "startDate": ""
52
51
  }]
53
52
  }
54
53
  LOOKUPS = {
@@ -67,7 +66,8 @@ LOOKUPS = {
67
66
  "crop": ["cropGroupingFaostatArea", "IPCC_LAND_USE_CATEGORY"],
68
67
  "landCover": ["cropGroupingFaostatProduction", "FAOSTAT_LAND_AREA_CATEGORY"]
69
68
  }
70
- MODEL_KEY = "landCover"
69
+ MODEL_KEY = 'landCover'
70
+
71
71
  LAND_AREA = LOOKUPS["region-faostatArea"][3]
72
72
  TOTAL_CROPLAND = "Cropland"
73
73
  ANNUAL_CROPLAND = "Arable land"
@@ -105,12 +105,20 @@ IPCC_LAND_USE_CATEGORY_PERENNIAL = "Perennial crops"
105
105
  OUTPUT_SIGNIFICANT_DIGITS = 3
106
106
 
107
107
 
108
+ def _management(term_id: str, value: float, start_date: str, end_date: str):
109
+ node = _new_management(term_id, MODEL)
110
+ node['value'] = value
111
+ node['startDate'] = start_date
112
+ node['endDate'] = end_date
113
+ return node
114
+
115
+
108
116
  def _is_missing_or_none(value) -> bool:
109
117
  return value is None or _is_missing_value(value)
110
118
 
111
119
 
112
120
  def _safe_divide(numerator, denominator, default=0) -> float:
113
- return default if denominator == 0 else numerator / denominator
121
+ return default if not denominator else numerator / denominator
114
122
 
115
123
 
116
124
  def site_area_sum_to_100(dict_of_percentages: dict):
@@ -432,22 +440,16 @@ def _run_make_management_nodes(existing_nodes: list, percentage_transformed_from
432
440
  for land_type, ratio in percentage_transformed_from.items()
433
441
  ]
434
442
  values = [v for v in values if v.get("land_management_key") not in existing_nodes_set]
435
- nodes = [
436
- {
437
- "term": {
438
- "@type": "Term",
439
- "@id": LAND_USE_TERMS_FOR_TRANSFORMATION[value.get("land_type")][0],
440
- "name": LAND_USE_TERMS_FOR_TRANSFORMATION[value.get("land_type")][1],
441
- "termType": TermTermType.LANDCOVER.value
442
- },
443
- "value": value.get("percentage"),
444
- "startDate": value.get("land_management_key")[1],
445
- "endDate": value.get("land_management_key")[2],
446
- "@type": "Management"
447
- } for value in values
448
- ]
449
443
 
450
- return nodes
444
+ return [
445
+ _management(
446
+ term_id=LAND_USE_TERMS_FOR_TRANSFORMATION[value.get("land_type")][0],
447
+ value=value.get("percentage"),
448
+ start_date=value.get("land_management_key")[1],
449
+ end_date=value.get("land_management_key")[2]
450
+ )
451
+ for value in values
452
+ ]
451
453
 
452
454
 
453
455
  def get_ratio_of_expanded_area(country_id: str, fao_name: str, end_year: int) -> float:
@@ -696,7 +698,7 @@ def _should_run_historical_land_use_change_single_crop(
696
698
  sum_of_site_areas_is_100
697
699
  ]
698
700
  )
699
- logShouldRun(site, MODEL_ID, term=term.get("@id"), should_run=should_run, key=MODEL_KEY)
701
+ logShouldRun(site, MODEL, term=term.get("@id"), should_run=should_run, key=MODEL_KEY)
700
702
 
701
703
  return should_run, site_area
702
704
 
@@ -29,5 +29,5 @@ def run(impact_assessment: dict):
29
29
  value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['emission'])
30
30
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
31
31
  value=value)
32
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
33
- return _indicator(value)
32
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
33
+ return _indicator(value) if value is not None else None
@@ -29,5 +29,5 @@ def run(impact_assessment: dict):
29
29
  value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS['emission'])
30
30
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
31
31
  value=value)
32
- logShouldRun(impact_assessment, MODEL, TERM_ID, True)
33
- return _indicator(value)
32
+ logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
33
+ return _indicator(value) if value is not None else None
@@ -7,11 +7,9 @@ from typing import Optional, Union
7
7
  from hestia_earth.schema import (
8
8
  MeasurementMethodClassification,
9
9
  MeasurementStatsDefinition,
10
- SiteSiteType,
11
- TermTermType
10
+ SiteSiteType
12
11
  )
13
12
 
14
- from hestia_earth.utils.model import filter_list_term_type
15
13
  from hestia_earth.utils.tools import non_empty_list
16
14
 
17
15
  from hestia_earth.models.log import log_as_table, logRequirements, logShouldRun
@@ -24,8 +22,8 @@ from hestia_earth.models.utils.measurement import _new_measurement
24
22
 
25
23
  from . import MODEL
26
24
  from .biomass_utils import (
27
- BiomassCategory, detect_land_cover_change, group_by_biomass_category, group_by_term_id, sample_biomass_equilibrium,
28
- summarise_land_cover_nodes
25
+ BiomassCategory, get_valid_land_cover_terms, detect_land_cover_change, group_by_biomass_category, group_by_term_id,
26
+ sample_biomass_equilibrium, summarise_land_cover_nodes
29
27
  )
30
28
 
31
29
 
@@ -94,8 +92,6 @@ _ITERATIONS = 10000
94
92
  _METHOD_CLASSIFICATION = MeasurementMethodClassification.TIER_1_MODEL.value
95
93
  _STATS_DEFINITION = MeasurementStatsDefinition.SIMULATED.value
96
94
 
97
- _LAND_COVER_TERM_TYPE = TermTermType.LANDCOVER
98
-
99
95
  _EQUILIBRIUM_TRANSITION_PERIOD = 20
100
96
  _EXCLUDED_ECO_CLIMATE_ZONES = {EcoClimateZone.POLAR_MOIST, EcoClimateZone.POLAR_DRY}
101
97
  _EXCLUDED_SITE_TYPES = {
@@ -156,7 +152,7 @@ def _should_run(site: dict) -> tuple[bool, dict, dict]:
156
152
  site_type = site.get("siteType")
157
153
  eco_climate_zone = get_eco_climate_zone_value(site, as_enum=True)
158
154
 
159
- land_cover = filter_list_term_type(site.get("management", []), _LAND_COVER_TERM_TYPE)
155
+ land_cover = get_valid_land_cover_terms(site)
160
156
 
161
157
  has_valid_site_type = site_type not in _EXCLUDED_SITE_TYPES
162
158
  has_valid_eco_climate_zone = all([
@@ -51,9 +51,9 @@ def _run_animal(data: dict):
51
51
  animal = data.get('animal')
52
52
  value = data.get('value')
53
53
  practice_id = get_lookup_value(animal.get('term'), LOOKUPS['liveAnimal'][1])
54
- return animal | {
54
+ return animal | ({
55
55
  'practices': merge_blank_nodes(animal.get('practices', []), [_practice(practice_id, value)])
56
- }
56
+ } if practice_id else {})
57
57
 
58
58
 
59
59
  def _should_run(cycle: dict):
@@ -7,11 +7,9 @@ from typing import Optional, Union
7
7
  from hestia_earth.schema import (
8
8
  MeasurementMethodClassification,
9
9
  MeasurementStatsDefinition,
10
- SiteSiteType,
11
- TermTermType
10
+ SiteSiteType
12
11
  )
13
12
 
14
- from hestia_earth.utils.model import filter_list_term_type
15
13
  from hestia_earth.utils.tools import non_empty_list
16
14
 
17
15
  from hestia_earth.models.log import log_as_table, logRequirements, logShouldRun
@@ -24,8 +22,8 @@ from hestia_earth.models.utils.measurement import _new_measurement
24
22
 
25
23
  from . import MODEL
26
24
  from .biomass_utils import (
27
- BiomassCategory, detect_land_cover_change, group_by_biomass_category, sample_biomass_equilibrium,
28
- summarise_land_cover_nodes
25
+ BiomassCategory, get_valid_land_cover_terms, detect_land_cover_change, group_by_biomass_category,
26
+ sample_biomass_equilibrium, summarise_land_cover_nodes
29
27
  )
30
28
 
31
29
 
@@ -81,8 +79,6 @@ _ITERATIONS = 10000
81
79
  _METHOD_CLASSIFICATION = MeasurementMethodClassification.TIER_1_MODEL.value
82
80
  _STATS_DEFINITION = MeasurementStatsDefinition.SIMULATED.value
83
81
 
84
- _LAND_COVER_TERM_TYPE = TermTermType.LANDCOVER
85
-
86
82
  _EQUILIBRIUM_TRANSITION_PERIOD = 20
87
83
  _EXCLUDED_ECO_CLIMATE_ZONES = {EcoClimateZone.POLAR_MOIST, EcoClimateZone.POLAR_DRY}
88
84
  _EXCLUDED_SITE_TYPES = {
@@ -149,7 +145,7 @@ def _should_run(site: dict) -> tuple[bool, dict, dict]:
149
145
  site_type = site.get("siteType")
150
146
  eco_climate_zone = get_eco_climate_zone_value(site, as_enum=True)
151
147
 
152
- land_cover = filter_list_term_type(site.get("management", []), _LAND_COVER_TERM_TYPE)
148
+ land_cover = get_valid_land_cover_terms(site)
153
149
 
154
150
  has_valid_site_type = site_type not in _EXCLUDED_SITE_TYPES
155
151
  has_valid_eco_climate_zone = all([
@@ -5,9 +5,12 @@ from numpy import random
5
5
  from numpy.typing import NDArray
6
6
  from typing import Callable, Optional, Union
7
7
 
8
+ from hestia_earth.schema import TermTermType
8
9
  from hestia_earth.utils.blank_node import get_node_value
10
+ from hestia_earth.utils.model import filter_list_term_type
9
11
 
10
12
  from hestia_earth.models.utils.array_builders import repeat_single, truncated_normal_1d
13
+ from hestia_earth.models.utils.blank_node import validate_start_date_end_date
11
14
  from hestia_earth.models.utils.ecoClimateZone import EcoClimateZone, get_ecoClimateZone_lookup_grouped_value
12
15
  from hestia_earth.models.utils.term import get_lookup_value
13
16
 
@@ -404,3 +407,11 @@ _KWARGS_TO_SAMPLE_FUNC = {
404
407
  ("value", "error"): sample_plus_minus_error,
405
408
  ("value",): sample_constant
406
409
  }
410
+
411
+
412
+ def get_valid_land_cover_terms(site: dict) -> list[dict]:
413
+ """Retrieve valid `landCover` nodes from a site's management."""
414
+ return [
415
+ node for node in filter_list_term_type(site.get("management", []), TermTermType.LANDCOVER)
416
+ if validate_start_date_end_date(node)
417
+ ]
@@ -250,7 +250,7 @@ def _should_run(cycle: dict):
250
250
  milk_yield=milk_yield,
251
251
  enteric_factor=enteric_factor,
252
252
  enteric_sd=enteric_sd,
253
- default_values=default_values)
253
+ default_values=';'.join(map(str, default_values)))
254
254
 
255
255
  logRequirements(cycle, model=MODEL, term=TERM_ID,
256
256
  term_type_animalFeed_complete=is_animalFeed_complete,
@@ -24,7 +24,7 @@ from hestia_earth.models.utils import pairwise
24
24
  from hestia_earth.models.utils.array_builders import correlated_normal_2d, gen_seed
25
25
  from hestia_earth.models.utils.blank_node import (
26
26
  _gapfill_datestr, _get_datestr_format, DatestrGapfillMode, DatestrFormat, group_nodes_by_year, node_term_match,
27
- split_node_by_dates
27
+ split_node_by_dates, validate_start_date_end_date
28
28
  )
29
29
  from hestia_earth.models.utils.constant import Units, get_atomic_conversion
30
30
  from hestia_earth.models.utils.descriptive_stats import calc_descriptive_stats
@@ -408,7 +408,8 @@ def create_should_run_function(
408
408
  cycles = related_cycles(site)
409
409
 
410
410
  carbon_stock_measurements = [
411
- node for node in site.get("measurements", []) if all([
411
+ node for node in site.get("measurements", [])
412
+ if all([
412
413
  node_term_match(node, carbon_stock_term_id),
413
414
  _has_valid_array_fields(node),
414
415
  _has_valid_dates(node),
@@ -417,7 +418,10 @@ def create_should_run_function(
417
418
  ])
418
419
  ]
419
420
 
420
- land_cover_nodes = filter_list_term_type(site.get("management", []), TermTermType.LANDCOVER)
421
+ land_cover_nodes = [
422
+ node for node in filter_list_term_type(site.get("management", []), TermTermType.LANDCOVER)
423
+ if validate_start_date_end_date(node)
424
+ ]
421
425
 
422
426
  seed = gen_seed(site) # All cycles linked to the same site should be consistent
423
427
  rng = random.default_rng(seed)
@@ -10,7 +10,12 @@ from . import MODEL
10
10
 
11
11
  REQUIREMENTS = {
12
12
  "Cycle": {
13
- "completeness.excreta": "True",
13
+ "or": {
14
+ "completeness.excreta": "True",
15
+ "inputs": [
16
+ {"@type": "Input", "term.termType": "excreta", "units": "kg N"}
17
+ ]
18
+ },
14
19
  "practices": [
15
20
  {"@type": "Practice", "value": "", "term.termType": "excretaManagement"}
16
21
  ]
@@ -36,26 +41,26 @@ def _emission(value: float):
36
41
  return emission
37
42
 
38
43
 
39
- def _run(excretaKgN: float, N2O_N_EF: float):
40
- value = N2O_N_EF * excretaKgN * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
44
+ def _run(N_total: float, N2O_N_EF: float):
45
+ value = (N2O_N_EF or 0) * (N_total or 0) * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
41
46
  return [_emission(value)]
42
47
 
43
48
 
44
49
  def _should_run(cycle: dict):
45
- excretaKgN = total_excreta(cycle.get('inputs', []))
50
+ N_total = total_excreta(cycle.get('inputs', []))
46
51
  N2O_N_EF = get_lookup_factor(cycle.get('practices', []), LOOKUPS['excretaManagement'])
47
52
  term_type_complete = _is_term_type_complete(cycle, TermTermType.EXCRETA)
48
53
 
49
54
  logRequirements(cycle, model=MODEL, term=TERM_ID,
50
- excretaKgN=excretaKgN,
55
+ N_total=N_total,
51
56
  N2O_N_EF=N2O_N_EF,
52
57
  term_type_excreta_complete=term_type_complete)
53
58
 
54
- should_run = all([excretaKgN, N2O_N_EF])
59
+ should_run = all([N_total, N2O_N_EF]) or all([not N_total, term_type_complete])
55
60
  logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
56
- return should_run, excretaKgN, N2O_N_EF
61
+ return should_run, N_total, N2O_N_EF
57
62
 
58
63
 
59
64
  def run(cycle: dict):
60
- should_run, excretaKgN, N2O_N_EF = _should_run(cycle)
61
- return _run(excretaKgN, N2O_N_EF) if should_run else []
65
+ should_run, N_total, N2O_N_EF = _should_run(cycle)
66
+ return _run(N_total, N2O_N_EF) if should_run else []
@@ -24,7 +24,7 @@ from hestia_earth.utils.blank_node import get_node_value
24
24
  from hestia_earth.models.utils.array_builders import gen_seed
25
25
  from hestia_earth.models.utils.blank_node import (
26
26
  cumulative_nodes_match, cumulative_nodes_lookup_match, cumulative_nodes_term_match,
27
- node_lookup_match, node_term_match, group_nodes_by_year
27
+ node_lookup_match, node_term_match, group_nodes_by_year, validate_start_date_end_date
28
28
  )
29
29
  from hestia_earth.models.utils.ecoClimateZone import EcoClimateZone, get_eco_climate_zone_value
30
30
  from hestia_earth.models.utils.descriptive_stats import calc_descriptive_stats
@@ -1209,8 +1209,14 @@ def _assign_ipcc_land_use_category(
1209
1209
  DECISION_TREE = _LAND_USE_CATEGORY_DECISION_TREE
1210
1210
  DEFAULT = IpccLandUseCategory.OTHER
1211
1211
 
1212
- land_cover_nodes = filter_list_term_type(management_nodes, [TermTermType.LANDCOVER])
1213
- water_regime_nodes = filter_list_term_type(management_nodes, [TermTermType.WATERREGIME])
1212
+ land_cover_nodes = [
1213
+ node for node in filter_list_term_type(management_nodes, [TermTermType.LANDCOVER])
1214
+ if validate_start_date_end_date(node)
1215
+ ]
1216
+ water_regime_nodes = [
1217
+ node for node in filter_list_term_type(management_nodes, [TermTermType.WATERREGIME])
1218
+ if validate_start_date_end_date(node)
1219
+ ]
1214
1220
 
1215
1221
  has_irrigation = check_irrigation(water_regime_nodes)
1216
1222
  has_upland_rice = _has_upland_rice(land_cover_nodes)