hestia-earth-models 0.64.11__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 (196) 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 +36 -19
  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/faostat2018/utils.py +72 -12
  18. hestia_earth/models/hestia/__init__.py +13 -0
  19. hestia_earth/models/hestia/landCover.py +727 -0
  20. hestia_earth/models/ipcc2013ExcludingFeedbacks/gwp100.py +2 -2
  21. hestia_earth/models/ipcc2013IncludingFeedbacks/gwp100.py +2 -2
  22. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +4 -8
  23. hestia_earth/models/ipcc2019/animal/fatContent.py +1 -1
  24. hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +91 -0
  25. hestia_earth/models/ipcc2019/animal/trueProteinContent.py +1 -1
  26. hestia_earth/models/ipcc2019/animal/utils.py +17 -12
  27. hestia_earth/models/ipcc2019/belowGroundBiomass.py +4 -8
  28. hestia_earth/models/ipcc2019/biomass_utils.py +11 -0
  29. hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +1 -1
  30. hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +8 -4
  31. hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +7 -3
  32. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +52 -6
  33. hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +7 -3
  34. hestia_earth/models/ipcc2019/n2OToAirExcretaDirect.py +14 -9
  35. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +9 -3
  36. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +1 -2
  37. hestia_earth/models/koble2014/aboveGroundCropResidue.py +5 -1
  38. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsClimateChange.py +2 -2
  39. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  40. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  41. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealth.py +2 -2
  42. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthClimateChange.py +2 -2
  43. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  44. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  45. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  46. hestia_earth/models/lcImpactAllEffects100Years/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  47. hestia_earth/models/lcImpactAllEffects100Years/damageToMarineEcosystemsPdfYear.py +2 -2
  48. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  49. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  50. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  51. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsClimateChange.py +2 -2
  52. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  53. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  54. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealth.py +2 -2
  55. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthClimateChange.py +2 -2
  56. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  57. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  58. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  59. hestia_earth/models/lcImpactAllEffectsInfinite/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  60. hestia_earth/models/lcImpactAllEffectsInfinite/damageToMarineEcosystemsPdfYear.py +2 -2
  61. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  62. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  63. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  64. hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  65. hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  66. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealth.py +2 -2
  67. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthClimateChange.py +2 -2
  68. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  69. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  70. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  71. hestia_earth/models/lcImpactCertainEffects100Years/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  72. hestia_earth/models/lcImpactCertainEffects100Years/damageToMarineEcosystemsPdfYear.py +2 -2
  73. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  74. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  75. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  76. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEcotoxicity.py +2 -3
  77. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsPdfYear.py +2 -2
  78. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealth.py +2 -2
  79. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthClimateChange.py +2 -2
  80. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthHumanToxicityCancerogenic.py +2 -3
  81. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthHumanToxicityNonCancerogenic.py +2 -3
  82. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  83. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToMarineEcosystemsMarineEcotoxicity.py +2 -3
  84. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToMarineEcosystemsPdfYear.py +2 -2
  85. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  86. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsPdfYear.py +2 -2
  87. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialEcotoxicity.py +2 -3
  88. hestia_earth/models/linkedImpactAssessment/emissions.py +3 -0
  89. hestia_earth/models/log.py +4 -3
  90. hestia_earth/models/mocking/search-results.json +575 -575
  91. hestia_earth/models/pooreNemecek2018/excretaKgN.py +4 -4
  92. hestia_earth/models/pooreNemecek2018/excretaKgVs.py +4 -4
  93. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterCropResidueDecomposition.py +1 -1
  94. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterExcreta.py +1 -1
  95. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterInorganicFertiliser.py +1 -1
  96. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterOrganicFertiliser.py +1 -1
  97. hestia_earth/models/pooreNemecek2018/{saplings.py → saplingsDepreciatedAmountPerCycle.py} +1 -1
  98. hestia_earth/models/pooreNemecek2018/utils.py +7 -1
  99. hestia_earth/models/recipe2016Egalitarian/damageToFreshwaterEcosystemsSpeciesYear.py +2 -2
  100. hestia_earth/models/recipe2016Egalitarian/damageToHumanHealth.py +2 -2
  101. hestia_earth/models/recipe2016Egalitarian/damageToMarineEcosystemsSpeciesYear.py +2 -2
  102. hestia_earth/models/recipe2016Egalitarian/damageToTerrestrialEcosystemsSpeciesYear.py +2 -2
  103. hestia_earth/models/recipe2016Egalitarian/freshwaterAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  104. hestia_earth/models/recipe2016Egalitarian/freshwaterEutrophicationPotential.py +2 -2
  105. hestia_earth/models/recipe2016Egalitarian/humanCarcinogenicToxicity.py +2 -3
  106. hestia_earth/models/recipe2016Egalitarian/humanNonCarcinogenicToxicity.py +2 -3
  107. hestia_earth/models/recipe2016Egalitarian/marineAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  108. hestia_earth/models/recipe2016Egalitarian/marineEutrophicationPotential.py +2 -2
  109. hestia_earth/models/recipe2016Egalitarian/ozoneDepletionPotential.py +2 -2
  110. hestia_earth/models/recipe2016Egalitarian/terrestrialAcidificationPotential.py +2 -2
  111. hestia_earth/models/recipe2016Egalitarian/terrestrialEcotoxicityPotential14Dcbeq.py +2 -3
  112. hestia_earth/models/recipe2016Hierarchist/damageToFreshwaterEcosystemsSpeciesYear.py +2 -2
  113. hestia_earth/models/recipe2016Hierarchist/damageToHumanHealth.py +2 -2
  114. hestia_earth/models/recipe2016Hierarchist/damageToMarineEcosystemsSpeciesYear.py +2 -2
  115. hestia_earth/models/recipe2016Hierarchist/damageToTerrestrialEcosystemsSpeciesYear.py +2 -2
  116. hestia_earth/models/recipe2016Hierarchist/freshwaterAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  117. hestia_earth/models/recipe2016Hierarchist/freshwaterEutrophicationPotential.py +2 -2
  118. hestia_earth/models/recipe2016Hierarchist/humanCarcinogenicToxicity.py +2 -3
  119. hestia_earth/models/recipe2016Hierarchist/humanNonCarcinogenicToxicity.py +2 -3
  120. hestia_earth/models/recipe2016Hierarchist/marineAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  121. hestia_earth/models/recipe2016Hierarchist/marineEutrophicationPotential.py +2 -2
  122. hestia_earth/models/recipe2016Hierarchist/ozoneDepletionPotential.py +2 -2
  123. hestia_earth/models/recipe2016Hierarchist/terrestrialAcidificationPotential.py +2 -2
  124. hestia_earth/models/recipe2016Hierarchist/terrestrialEcotoxicityPotential14Dcbeq.py +2 -3
  125. hestia_earth/models/recipe2016Individualist/damageToFreshwaterEcosystemsSpeciesYear.py +2 -2
  126. hestia_earth/models/recipe2016Individualist/damageToHumanHealth.py +2 -2
  127. hestia_earth/models/recipe2016Individualist/damageToMarineEcosystemsSpeciesYear.py +2 -2
  128. hestia_earth/models/recipe2016Individualist/damageToTerrestrialEcosystemsSpeciesYear.py +2 -2
  129. hestia_earth/models/recipe2016Individualist/freshwaterAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  130. hestia_earth/models/recipe2016Individualist/freshwaterEutrophicationPotential.py +2 -2
  131. hestia_earth/models/recipe2016Individualist/humanCarcinogenicToxicity.py +2 -3
  132. hestia_earth/models/recipe2016Individualist/humanNonCarcinogenicToxicity.py +2 -3
  133. hestia_earth/models/recipe2016Individualist/marineAquaticEcotoxicityPotential14Dcbeq.py +2 -3
  134. hestia_earth/models/recipe2016Individualist/marineEutrophicationPotential.py +2 -2
  135. hestia_earth/models/recipe2016Individualist/ozoneDepletionPotential.py +2 -2
  136. hestia_earth/models/recipe2016Individualist/terrestrialAcidificationPotential.py +2 -2
  137. hestia_earth/models/recipe2016Individualist/terrestrialEcotoxicityPotential14Dcbeq.py +2 -3
  138. hestia_earth/models/site/management.py +142 -144
  139. hestia_earth/models/stehfestBouwman2006/n2OToAirCropResidueDecompositionDirect.py +1 -1
  140. hestia_earth/models/stehfestBouwman2006/n2OToAirExcretaDirect.py +1 -1
  141. hestia_earth/models/stehfestBouwman2006/n2OToAirInorganicFertiliserDirect.py +1 -1
  142. hestia_earth/models/stehfestBouwman2006/n2OToAirOrganicFertiliserDirect.py +1 -1
  143. hestia_earth/models/stehfestBouwman2006/noxToAirCropResidueDecomposition.py +1 -1
  144. hestia_earth/models/stehfestBouwman2006/noxToAirExcreta.py +1 -1
  145. hestia_earth/models/stehfestBouwman2006/noxToAirInorganicFertiliser.py +1 -1
  146. hestia_earth/models/stehfestBouwman2006/noxToAirOrganicFertiliser.py +1 -1
  147. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirCropResidueDecomposition.py +1 -1
  148. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirExcreta.py +1 -1
  149. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirInorganicFertiliser.py +1 -1
  150. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirOrganicFertiliser.py +1 -1
  151. hestia_earth/models/usetoxV2/freshwaterEcotoxicityPotentialCtue.py +2 -3
  152. hestia_earth/models/utils/__init__.py +4 -1
  153. hestia_earth/models/utils/blank_node.py +34 -14
  154. hestia_earth/models/utils/emission.py +1 -8
  155. hestia_earth/models/utils/lookup.py +2 -1
  156. hestia_earth/models/utils/management.py +11 -0
  157. hestia_earth/models/utils/pesticideAI.py +11 -17
  158. hestia_earth/models/utils/term.py +2 -1
  159. hestia_earth/models/version.py +1 -1
  160. {hestia_earth_models-0.64.11.dist-info → hestia_earth_models-0.64.13.dist-info}/METADATA +4 -4
  161. {hestia_earth_models-0.64.11.dist-info → hestia_earth_models-0.64.13.dist-info}/RECORD +192 -188
  162. {hestia_earth_models-0.64.11.dist-info → hestia_earth_models-0.64.13.dist-info}/WHEEL +1 -1
  163. tests/models/cycle/completeness/test_seed.py +1 -1
  164. tests/models/cycle/test_endDate.py +18 -2
  165. tests/models/cycle/test_startDate.py +21 -3
  166. tests/models/faostat2018/test_faostat_utils.py +84 -0
  167. tests/models/hestia/__init__.py +0 -0
  168. tests/models/hestia/test_landCover.py +210 -0
  169. tests/models/ipcc2019/animal/test_milkYieldPerAnimal.py +21 -0
  170. tests/models/ipcc2019/test_aboveGroundBiomass.py +2 -1
  171. tests/models/ipcc2019/test_belowGroundBiomass.py +2 -1
  172. tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +4 -3
  173. tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +3 -3
  174. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +49 -2
  175. tests/models/ipcc2019/test_n2OToAirExcretaDirect.py +12 -0
  176. tests/models/ipcc2019/test_organicCarbonPerHa.py +1 -0
  177. tests/models/koble2014/test_aboveGroundCropResidue.py +13 -0
  178. tests/models/pooreNemecek2018/test_no3ToGroundwaterCropResidueDecomposition.py +3 -2
  179. tests/models/pooreNemecek2018/test_no3ToGroundwaterExcreta.py +3 -2
  180. tests/models/pooreNemecek2018/test_no3ToGroundwaterInorganicFertiliser.py +3 -2
  181. tests/models/pooreNemecek2018/test_no3ToGroundwaterOrganicFertiliser.py +3 -2
  182. tests/models/pooreNemecek2018/{test_saplings.py → test_saplingsDepreciatedAmountPerCycle.py} +1 -1
  183. tests/models/site/test_management.py +18 -151
  184. tests/models/utils/test_blank_node.py +57 -1
  185. tests/models/utils/test_emission.py +1 -6
  186. tests/models/utils/test_site.py +33 -2
  187. tests/models/pooreNemecek2018/test_no3ToGroundwaterSoilFlux.py +0 -90
  188. tests/models/stehfestBouwman2006/test_n2OToAirSoilFlux.py +0 -41
  189. tests/models/stehfestBouwman2006/test_noxToAirSoilFlux.py +0 -40
  190. tests/models/stehfestBouwman2006GisImplementation/test_noxToAirSoilFlux.py +0 -33
  191. /hestia_earth/models/pooreNemecek2018/{no3ToGroundwaterSoilFlux.py → no3ToGroundwaterSoilFlux_utils.py} +0 -0
  192. /hestia_earth/models/stehfestBouwman2006/{n2OToAirSoilFlux.py → n2OToAirSoilFlux_utils.py} +0 -0
  193. /hestia_earth/models/stehfestBouwman2006/{noxToAirSoilFlux.py → noxToAirSoilFlux_utils.py} +0 -0
  194. /hestia_earth/models/stehfestBouwman2006GisImplementation/{noxToAirSoilFlux.py → noxToAirSoilFlux_utils.py} +0 -0
  195. {hestia_earth_models-0.64.11.dist-info → hestia_earth_models-0.64.13.dist-info}/LICENSE +0 -0
  196. {hestia_earth_models-0.64.11.dist-info → hestia_earth_models-0.64.13.dist-info}/top_level.txt +0 -0
@@ -1,152 +1,20 @@
1
1
  import json
2
- from unittest.mock import patch
3
-
2
+ from unittest.mock import Mock, patch
4
3
  import pytest
5
- from hestia_earth.schema import TermTermType, SiteSiteType
4
+ from hestia_earth.schema import SiteSiteType
6
5
 
7
- from hestia_earth.models.site.management import MODEL, MODEL_KEY, run, _should_run
8
- from tests.utils import fixtures_path
6
+ from tests.utils import fixtures_path, fake_new_management
7
+ from hestia_earth.models.site.management import MODEL, MODEL_KEY, run
9
8
 
10
- CLASS_PATH = f"hestia_earth.models.{MODEL}.{MODEL_KEY}"
9
+ class_path = f"hestia_earth.models.{MODEL}.{MODEL_KEY}"
11
10
  fixtures_folder = f"{fixtures_path}/{MODEL}/{MODEL_KEY}"
12
11
 
13
- TERM_BY_ID = {
14
- 'genericCropPlant': {'@type': 'Term', '@id': 'genericCropPlant', 'termType': TermTermType.LANDCOVER.value},
15
- 'wheatPlant': {'@type': 'Term', '@id': 'wheatPlant', 'termType': TermTermType.LANDCOVER.value},
16
- 'oatPlant': {'@type': 'Term', '@id': 'oatPlant', 'termType': TermTermType.LANDCOVER.value},
17
- 'agatiTree': {'@type': 'Term', '@id': 'agatiTree', 'termType': TermTermType.LANDCOVER.value},
18
- 'wildGarlicPlant': {'@type': 'Term', '@id': 'wildGarlicPlant', 'termType': TermTermType.LANDCOVER.value},
19
- 'animalHousing': {
20
- "@type": "Term",
21
- "@id": "animalHousing",
22
- "name": "Animal housing",
23
- "termType": TermTermType.LANDCOVER.value,
24
- "units": "% area"
25
- }
26
- }
27
-
28
- LAND_COVER_TERM_BY_SITE_TYPE = {
12
+ _LAND_COVER_TERM_BY_SITE_TYPE = {
29
13
  SiteSiteType.ANIMAL_HOUSING.value: "animalHousing",
30
14
  SiteSiteType.CROPLAND.value: "cropland"
31
15
  }
32
16
 
33
17
 
34
- def lookup_side_effect(*args, **kwargs):
35
- # Values taken from real lookups.
36
- _ = kwargs
37
- if args[0]["@id"] == "ureaKgN" and args[1] == "nitrogenContent":
38
- return 45.5
39
- if args[0]["@id"] == "compostKgMass" and args[1] == "ANIMAL_MANURE":
40
- return False
41
- return True
42
-
43
-
44
- @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda id, *args: TERM_BY_ID[id])
45
- @patch(f"{CLASS_PATH}.related_cycles")
46
- def test_should_run(mock_related_cycles, *args):
47
- # no cycles => do not run
48
- mock_related_cycles.return_value = []
49
- should_run, *args = _should_run({})
50
- assert should_run is False
51
-
52
- # no products => do not run
53
- mock_related_cycles.return_value = [{"products": []}]
54
- should_run, *args = _should_run({})
55
- assert should_run is False
56
-
57
- # with irrelevant termType => do not run
58
- mock_related_cycles.return_value = [
59
- {
60
- "products": [
61
- {"term": {"termType": TermTermType.BUILDING.value}},
62
- {"term": {"termType": TermTermType.EXCRETA.value}}
63
- ],
64
- "startDate": "2021",
65
- "endDate": "2022"
66
- }
67
- ]
68
- should_run, *args = _should_run({})
69
- assert should_run is False
70
-
71
- # products and practices but no relevant terms/termTypes => do not run
72
- mock_related_cycles.return_value = [
73
- {
74
- "practices": [
75
- {"term": {"@id": "soilAssociationOrganicStandard"}},
76
- {"term": {"@id": "noTillage"}}
77
- ],
78
- "products": [
79
- {"term": {"termType": TermTermType.BUILDING.value}},
80
- {"term": {"termType": TermTermType.EXCRETA.value}}
81
- ]
82
- }
83
- ]
84
- should_run, *args = _should_run({})
85
- assert should_run is False
86
-
87
- # # practices with relevant termType => run
88
- mock_related_cycles.return_value = [
89
- {
90
- "practices": [
91
- {"term": {"termType": TermTermType.WATERREGIME.value}},
92
- {"term": {"termType": TermTermType.MACHINERY.value}}
93
- ],
94
- "startDate": "2021",
95
- "endDate": "2022"
96
- }
97
- ]
98
- should_run, *args = _should_run({})
99
- assert should_run is True
100
-
101
- # with relevant product, blank site_type => no run
102
- mock_related_cycles.return_value = [
103
- {
104
- "products": [
105
- {
106
- "term": {
107
- "termType": TermTermType.CROP.value,
108
- "@id": "genericCropProduct"
109
- },
110
- "value": [51],
111
- "startDate": "2001",
112
- "endDate": "2002"
113
- }
114
- ],
115
- "startDate": "2021",
116
- "endDate": "2022"
117
- }
118
- ]
119
- should_run, *args = _should_run({})
120
- assert should_run is False
121
-
122
- # with relevant product and site_type => run
123
- mock_related_cycles.return_value = [
124
- {
125
- "products": [
126
- {
127
- "term": {
128
- "termType": TermTermType.CROP.value,
129
- "@id": "genericCropProduct"
130
- },
131
- "value": [51],
132
- "startDate": "2001",
133
- "endDate": "2002"
134
- }
135
- ],
136
- "startDate": "2021",
137
- "endDate": "2022"
138
- }
139
- ]
140
- should_run, *args = _should_run({"siteType": "cropland"})
141
- assert should_run is True
142
- assert args[0] == [{
143
- 'term': TERM_BY_ID['genericCropPlant'],
144
- 'value': 100,
145
- 'endDate': '2022',
146
- 'startDate': '2021'
147
- }]
148
-
149
-
150
18
  @pytest.mark.parametrize(
151
19
  "test_name,fixture_path",
152
20
  [
@@ -167,23 +35,22 @@ def test_should_run(mock_related_cycles, *args):
167
35
  # - sassafrasTree (86) x 2 condenses 2001-01-01 to 2004-12-31
168
36
  # - bananaPlant (87) does not condense [non-consecutive years]
169
37
  # - durianTree (89) does not condense [dates overwritten See 808]
170
- ("Site Type", f"{fixtures_folder}/inputs/site_type")
38
+ ("Site Type", f"{fixtures_folder}/inputs/site_type"),
39
+ ("Multiple products but only 1 with landCover id", f"{fixtures_folder}/multiple-products"),
171
40
  ]
172
41
  )
173
42
  @patch(
174
- f"{CLASS_PATH}.get_landCover_term_id_from_site_type",
175
- side_effect=lambda site_type: LAND_COVER_TERM_BY_SITE_TYPE[site_type]
43
+ f"{class_path}.get_landCover_term_id_from_site_type",
44
+ side_effect=lambda site_type: _LAND_COVER_TERM_BY_SITE_TYPE[site_type]
176
45
  )
177
- @patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda term_id, *args: TERM_BY_ID[term_id])
178
- @patch(f"{CLASS_PATH}.related_cycles")
179
- @patch(f"{CLASS_PATH}._get_lookup_with_debug", side_effect=lookup_side_effect)
46
+ @patch(f"{class_path}._new_management", side_effect=fake_new_management)
47
+ @patch(f"{class_path}.related_cycles")
180
48
  def test_run(
181
- mock_get_lookup_with_debug,
182
- mock_related_cycles,
183
- mock_download,
184
- mock_land_cover_lookup,
185
- test_name,
186
- fixture_path
49
+ mock_related_cycles: Mock,
50
+ mock_new_management: Mock,
51
+ mock_land_cover_lookup: Mock,
52
+ test_name: str,
53
+ fixture_path: str
187
54
  ):
188
55
  with open(f"{fixture_path}/cycles.jsonld", encoding='utf-8') as f:
189
56
  cycles = json.load(f)
@@ -200,4 +67,4 @@ def test_run(
200
67
  expected = json.load(f)
201
68
 
202
69
  result = run(site)
203
- assert result == expected
70
+ assert result == expected, test_name
@@ -24,7 +24,8 @@ from hestia_earth.models.utils.blank_node import (
24
24
  GroupNodesByYearMode,
25
25
  split_node_by_dates,
26
26
  _most_recent_nodes,
27
- _shallowest_node
27
+ _shallowest_node,
28
+ validate_start_date_end_date
28
29
  )
29
30
 
30
31
 
@@ -184,6 +185,19 @@ def test_condense_nodes():
184
185
  "value": [7]}
185
186
  ],
186
187
  ),
188
+ (
189
+ "same-blank-nodes-sum",
190
+ [
191
+ {"startDate": "2001-01-01", "endDate": "2001-11-30", "term": {"@id": "bananaPlant", "units": "% area"},
192
+ "value": [50]},
193
+ {"startDate": "2001-01-01", "endDate": "2001-11-30", "term": {"@id": "bananaPlant", "units": "% area"},
194
+ "value": [50]}
195
+ ],
196
+ [
197
+ {"startDate": "2001-01-01", "endDate": "2001-11-30", "term": {"@id": "bananaPlant", "units": "% area"},
198
+ "value": [100]}
199
+ ]
200
+ )
187
201
  ]
188
202
  )
189
203
  def test_condense_nodes_(test_name, input_nodes, expected_output_nodes):
@@ -872,6 +886,18 @@ def test_group_nodes_by_year_missing_dates():
872
886
  assert result == EXPECTED
873
887
 
874
888
 
889
+ def test_group_nodes_by_year_incorrect_dates():
890
+
891
+ NODES = [
892
+ {"value": [0], "endDate": "2000-09-14", "startDate": "2000-09-15"},
893
+ ]
894
+
895
+ EXPECTED = {}
896
+
897
+ result = group_nodes_by_year(NODES, mode=GroupNodesByYearMode.START_AND_END_DATE)
898
+ assert result == EXPECTED
899
+
900
+
875
901
  @mark.parametrize(
876
902
  "system_datetime",
877
903
  [
@@ -1176,3 +1202,33 @@ def test_shallowest_measurement():
1176
1202
  expected = json.load(f)
1177
1203
 
1178
1204
  assert _shallowest_node(measurements) == expected
1205
+
1206
+
1207
+ @mark.parametrize(
1208
+ "node, expected",
1209
+ [
1210
+ (
1211
+ {"startDate": "2000", "endDate": "2001"},
1212
+ True
1213
+ ),
1214
+ (
1215
+ {"startDate": "2001", "endDate": "2000"},
1216
+ False
1217
+ ),
1218
+ (
1219
+ {"startDate": "2000-01-01T00:00:00", "endDate": "2000-01-01T00:00:00"},
1220
+ False
1221
+ ),
1222
+ (
1223
+ {"endDate": "2000"},
1224
+ True
1225
+ ),
1226
+ (
1227
+ {},
1228
+ True
1229
+ ),
1230
+ ],
1231
+ ids=["correct", "reversed", "equal", "no start date", "no start date, no end date"])
1232
+ def test_validate_start_date_end_date(node: dict, expected: bool):
1233
+ # Closes #972
1234
+ assert validate_start_date_end_date(node) == expected
@@ -4,7 +4,7 @@ from unittest.mock import patch
4
4
  from hestia_earth.schema import EmissionMethodTier
5
5
 
6
6
  from tests.utils import TERM
7
- from hestia_earth.models.utils.emission import _new_emission, is_in_system_boundary, min_emission_method_tier
7
+ from hestia_earth.models.utils.emission import _new_emission, min_emission_method_tier
8
8
 
9
9
  class_path = 'hestia_earth.models.utils.emission'
10
10
 
@@ -27,11 +27,6 @@ def test_new_emission(*args):
27
27
  }
28
28
 
29
29
 
30
- def test_is_in_system_boundary():
31
- assert is_in_system_boundary('ch4ToAirCropResidueBurning') is True
32
- assert is_in_system_boundary('codToWaterInputsProduction') is False
33
-
34
-
35
30
  @mark.parametrize(
36
31
  "input, expected",
37
32
  [
@@ -1,7 +1,8 @@
1
- from unittest.mock import patch
1
+ import pytest
2
+ from unittest.mock import Mock, patch
2
3
  from hestia_earth.schema import SiteSiteType
3
4
 
4
- from hestia_earth.models.utils.site import region_level_1_id, related_cycles, valid_site_type
5
+ from hestia_earth.models.utils.site import region_level_1_id, related_cycles, valid_site_type, get_land_cover_term_id
5
6
 
6
7
  class_path = 'hestia_earth.models.utils.site'
7
8
  CYCLE = {'@id': 'id'}
@@ -30,3 +31,33 @@ def test_valid_site_type():
30
31
 
31
32
  site = {'siteType': SiteSiteType.CROPLAND.value}
32
33
  assert not valid_site_type(site, [SiteSiteType.OTHER_NATURAL_VEGETATION.value])
34
+
35
+
36
+ _LAND_COVER_TERMS = [
37
+ {'@type': 'Term', 'name': 'Glass or high accessible cover', '@id': 'glassOrHighAccessibleCover'},
38
+ {'@type': 'Term', 'name': 'Sea or ocean', '@id': 'seaOrOcean'},
39
+ {'@type': 'Term', 'name': 'River or stream', '@id': 'riverOrStream'},
40
+ {'@type': 'Term', 'name': 'Other natural vegetation', '@id': 'otherNaturalVegetation'},
41
+ {'@type': 'Term', 'name': 'Food retailer', '@id': 'foodRetailer'},
42
+ {'@type': 'Term', 'name': 'Agri-food processor', '@id': 'agriFoodProcessor'},
43
+ {'@type': 'Term', 'name': 'Permanent pasture', '@id': 'permanentPasture'},
44
+ {'@type': 'Term', 'name': 'Animal housing', '@id': 'animalHousing'},
45
+ {'@type': 'Term', 'name': 'Forest', '@id': 'forest'},
46
+ {'@type': 'Term', 'name': 'Lake', '@id': 'lake'},
47
+ {'@type': 'Term', 'name': 'Pond', '@id': 'pond'},
48
+ {'@type': 'Term', 'name': 'Cropland', '@id': 'cropland'},
49
+ ]
50
+
51
+
52
+ @pytest.mark.parametrize(
53
+ 'site_type,expected_landCover_id',
54
+ [
55
+ (SiteSiteType.CROPLAND.value, 'cropland'),
56
+ (SiteSiteType.SEA_OR_OCEAN.value, 'seaOrOcean'),
57
+ (SiteSiteType.AGRI_FOOD_PROCESSOR.value, 'agriFoodProcessor'),
58
+ (SiteSiteType.GLASS_OR_HIGH_ACCESSIBLE_COVER.value, 'glassOrHighAccessibleCover'),
59
+ ]
60
+ )
61
+ @patch(f"{class_path}.get_land_cover_siteTypes", return_value=_LAND_COVER_TERMS)
62
+ def test_get_land_cover_term_id(mock_terms: Mock, site_type: str, expected_landCover_id: str):
63
+ assert get_land_cover_term_id(site_type) == expected_landCover_id, site_type
@@ -1,90 +0,0 @@
1
- from unittest.mock import patch
2
- import json
3
- from tests.utils import fixtures_path, fake_new_emission, FLOODED_RICE_TERMS
4
-
5
- from hestia_earth.models.pooreNemecek2018.no3ToGroundwaterSoilFlux import MODEL, TERM_ID, run, _should_run
6
-
7
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
-
10
-
11
- @patch(f"{class_path}.get_rice_paddy_terms", return_value=FLOODED_RICE_TERMS)
12
- @patch(f"{class_path}.find_primary_product", return_value={'term': {'@id': 'product'}})
13
- @patch(f"{class_path}.get_crop_residue_decomposition_N_total", return_value=10)
14
- @patch(f"{class_path}.most_relevant_measurement_value", return_value=0)
15
- @patch(f"{class_path}.get_max_rooting_depth", return_value=None)
16
- def test_should_run(mock_rooting_depth, mock_measurement, *args):
17
- # no measurements => no run
18
- cycle = {}
19
- should_run, *args = _should_run(cycle)
20
- assert not should_run
21
-
22
- # with measurements => no run
23
- mock_measurement.return_value = 10
24
- should_run, *args = _should_run(cycle)
25
- assert not should_run
26
-
27
- # no rootingDepth => no run
28
- should_run, *args = _should_run({})
29
- assert not should_run
30
-
31
- # with rootingDepth => run
32
- mock_rooting_depth.return_value = 10
33
- should_run, *args = _should_run({})
34
- assert should_run is True
35
-
36
-
37
- @patch(f"{class_path}.get_rice_paddy_terms", return_value=FLOODED_RICE_TERMS)
38
- @patch(f"{class_path}.get_max_rooting_depth", return_value=0.9)
39
- @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
40
- def test_run(*args):
41
- with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
42
- cycle = json.load(f)
43
-
44
- with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
45
- expected = json.load(f)
46
-
47
- value = run(cycle)
48
- assert value == expected
49
-
50
-
51
- @patch(f"{class_path}.get_rice_paddy_terms", return_value=FLOODED_RICE_TERMS)
52
- @patch(f"{class_path}.get_max_rooting_depth", return_value=0.9)
53
- @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
54
- def test_run_with_high_conditions(*args):
55
- with open(f"{fixtures_folder}/with-high-conditions/cycle.jsonld", encoding='utf-8') as f:
56
- cycle = json.load(f)
57
-
58
- with open(f"{fixtures_folder}/with-high-conditions/result.jsonld", encoding='utf-8') as f:
59
- expected = json.load(f)
60
-
61
- value = run(cycle)
62
- assert value == expected
63
-
64
-
65
- @patch(f"{class_path}.get_rice_paddy_terms", return_value=FLOODED_RICE_TERMS)
66
- @patch(f"{class_path}.get_max_rooting_depth", return_value=0.9)
67
- @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
68
- def test_run_with_low_conditions(*args):
69
- with open(f"{fixtures_folder}/with-low-conditions/cycle.jsonld", encoding='utf-8') as f:
70
- cycle = json.load(f)
71
-
72
- with open(f"{fixtures_folder}/with-low-conditions/result.jsonld", encoding='utf-8') as f:
73
- expected = json.load(f)
74
-
75
- value = run(cycle)
76
- assert value == expected
77
-
78
-
79
- @patch(f"{class_path}.get_rice_paddy_terms", return_value=FLOODED_RICE_TERMS)
80
- @patch(f"{class_path}.get_max_rooting_depth", return_value=0.9)
81
- @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
82
- def test_run_with_flooded_rice(*args):
83
- with open(f"{fixtures_folder}/with-flooded-rice/cycle.jsonld", encoding='utf-8') as f:
84
- cycle = json.load(f)
85
-
86
- with open(f"{fixtures_folder}/with-flooded-rice/result.jsonld", encoding='utf-8') as f:
87
- expected = json.load(f)
88
-
89
- value = run(cycle)
90
- assert value == expected
@@ -1,41 +0,0 @@
1
- from unittest.mock import patch
2
- import json
3
- from tests.utils import fixtures_path, fake_new_emission
4
-
5
- from hestia_earth.models.stehfestBouwman2006.n2OToAirSoilFlux import MODEL, TERM_ID, run, _should_run, _get_value
6
-
7
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
-
10
-
11
- @patch(f"{class_path}.find_primary_product", return_value={'@id': 'product'})
12
- @patch(f"{class_path}._get_crop_crouping", return_value='Cereals')
13
- @patch(f"{class_path}.get_crop_residue_decomposition_N_total", return_value=10)
14
- @patch(f"{class_path}.most_relevant_measurement_value", return_value=0)
15
- def test_should_run(mock_measurement, *args):
16
- # no measurements => no run
17
- cycle = {}
18
- should_run, *args = _should_run(cycle)
19
- assert not should_run
20
-
21
- # with measurements => run
22
- mock_measurement.return_value = 10
23
- should_run, *args = _should_run(cycle)
24
- assert should_run is True
25
-
26
-
27
- def test_handle_overflow_error():
28
- value = _get_value({}, [10, 10, 10, 10, 1, 'Other'], 10000000)
29
- assert round(value) == 1131197
30
-
31
-
32
- @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
33
- def test_run(*args):
34
- with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
35
- cycle = json.load(f)
36
-
37
- with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
38
- expected = json.load(f)
39
-
40
- value = run(cycle)
41
- assert value == expected
@@ -1,40 +0,0 @@
1
- from unittest.mock import patch
2
- import json
3
- from tests.utils import fixtures_path, fake_new_emission
4
-
5
- from hestia_earth.models.stehfestBouwman2006.noxToAirSoilFlux import MODEL, TERM_ID, run, _should_run, _get_value
6
-
7
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
-
10
-
11
- @patch(f"{class_path}.get_crop_residue_decomposition_N_total", return_value=10)
12
- @patch(f"{class_path}.most_relevant_measurement_value", return_value=0)
13
- def test_should_run(mock_measurement, *args):
14
- # no measurements => no run
15
- cycle = {'inputs': [], 'measurements': []}
16
- should_run, *args = _should_run(cycle)
17
- assert not should_run
18
-
19
- # with measurements => run
20
- mock_measurement.return_value = 10
21
- cycle['measurements'] = [{}]
22
- should_run, *args = _should_run(cycle)
23
- assert should_run is True
24
-
25
-
26
- def test_handle_overflow_error():
27
- value = _get_value({}, 1, 100, 10000000)
28
- assert round(value) == 535554
29
-
30
-
31
- @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
32
- def test_run(*args):
33
- with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
34
- cycle = json.load(f)
35
-
36
- with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
37
- expected = json.load(f)
38
-
39
- value = run(cycle)
40
- assert value == expected
@@ -1,33 +0,0 @@
1
- from unittest.mock import patch
2
- import json
3
- from tests.utils import fixtures_path, fake_new_emission
4
-
5
- from hestia_earth.models.stehfestBouwman2006GisImplementation.noxToAirSoilFlux import MODEL, TERM_ID, run, _should_run
6
-
7
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
8
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
9
-
10
-
11
- @patch(f"{class_path}.get_crop_residue_decomposition_N_total", return_value=10)
12
- def test_should_run(*args):
13
- # no country => no run
14
- cycle = {'inputs': [], 'site': {}}
15
- should_run, *args = _should_run(cycle)
16
- assert not should_run
17
-
18
- # with country => run
19
- cycle['site'] = {'country': {'@id': 'country'}}
20
- should_run, *args = _should_run(cycle)
21
- assert should_run is True
22
-
23
-
24
- @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
25
- def test_run(*args):
26
- with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
27
- cycle = json.load(f)
28
-
29
- with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
30
- expected = json.load(f)
31
-
32
- value = run(cycle)
33
- assert value == expected