hestia-earth-models 0.70.0__py3-none-any.whl → 0.70.2__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 (192) hide show
  1. hestia_earth/models/aware/scarcityWeightedWaterUse.py +8 -16
  2. hestia_earth/models/cml2001Baseline/resourceUseMineralsAndMetalsDuringCycle.py +2 -1
  3. hestia_earth/models/config/Cycle.json +98 -50
  4. hestia_earth/models/config/ImpactAssessment.json +12 -4
  5. hestia_earth/models/config/Site.json +40 -21
  6. hestia_earth/models/cycle/transformation.py +1 -1
  7. hestia_earth/models/cycle/utils.py +0 -6
  8. hestia_earth/models/data/ecoinventV3/__init__.py +15 -13
  9. hestia_earth/models/ecoalimV9/__init__.py +13 -0
  10. hestia_earth/models/ecoalimV9/cycle.py +128 -0
  11. hestia_earth/models/ecoalimV9/impact_assessment.py +125 -0
  12. hestia_earth/models/ecoalimV9/utils.py +31 -0
  13. hestia_earth/models/ecoinventV3/__init__.py +6 -14
  14. hestia_earth/models/ecoinventV3/utils.py +1 -29
  15. hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +8 -2
  16. hestia_earth/models/emissionNotRelevant/__init__.py +33 -8
  17. hestia_earth/models/{cycle → hestia}/aboveGroundCropResidue.py +4 -3
  18. hestia_earth/models/{cycle → hestia}/aboveGroundCropResidueTotal.py +1 -1
  19. hestia_earth/models/{site → hestia}/brackishWater.py +1 -1
  20. hestia_earth/models/{site → hestia}/cationExchangeCapacityPerKgSoil.py +1 -1
  21. hestia_earth/models/{cycle → hestia}/coldCarcassWeightPerHead.py +1 -1
  22. hestia_earth/models/{cycle → hestia}/coldDressedCarcassWeightPerHead.py +1 -1
  23. hestia_earth/models/{cycle → hestia}/concentrateFeed.py +1 -1
  24. hestia_earth/models/{cycle → hestia}/cropResidueManagement.py +1 -1
  25. hestia_earth/models/{cycle → hestia}/croppingIntensity.py +1 -1
  26. hestia_earth/models/{cycle → hestia}/energyContentLowerHeatingValue.py +1 -1
  27. hestia_earth/models/{cycle → hestia}/excretaKgMass.py +8 -3
  28. hestia_earth/models/{cycle → hestia}/excretaKgN.py +1 -1
  29. hestia_earth/models/{cycle → hestia}/excretaKgVs.py +1 -1
  30. hestia_earth/models/{cycle → hestia}/feedConversionRatio/__init__.py +1 -1
  31. hestia_earth/models/{site → hestia}/flowingWater.py +1 -1
  32. hestia_earth/models/{site → hestia}/freshWater.py +1 -1
  33. hestia_earth/models/{cycle → hestia}/inorganicFertiliser.py +1 -1
  34. hestia_earth/models/{cycle → hestia}/irrigatedTypeUnspecified.py +14 -19
  35. hestia_earth/models/hestia/landCover.py +30 -22
  36. hestia_earth/models/{cycle → hestia}/liveAnimal.py +1 -1
  37. hestia_earth/models/{cycle → hestia}/longFallowRatio.py +1 -1
  38. hestia_earth/models/{site → hestia}/management.py +4 -6
  39. hestia_earth/models/{cycle → hestia}/materialAndSubstrate.py +1 -1
  40. hestia_earth/models/{cycle → hestia}/milkYield.py +1 -1
  41. hestia_earth/models/{site → hestia}/netPrimaryProduction.py +1 -1
  42. hestia_earth/models/{site → hestia}/organicCarbonPerHa.py +1 -1
  43. hestia_earth/models/hestia/pToSurfaceWaterAquacultureSystems.py +148 -0
  44. hestia_earth/models/{cycle → hestia}/pastureGrass.py +1 -1
  45. hestia_earth/models/{cycle → hestia}/pastureSystem.py +1 -1
  46. hestia_earth/models/{site → hestia}/potentialEvapotranspirationAnnual.py +3 -3
  47. hestia_earth/models/{site → hestia}/potentialEvapotranspirationMonthly.py +3 -3
  48. hestia_earth/models/{site → hestia}/precipitationAnnual.py +3 -3
  49. hestia_earth/models/{site → hestia}/precipitationMonthly.py +3 -3
  50. hestia_earth/models/{site → hestia}/rainfallAnnual.py +3 -3
  51. hestia_earth/models/{site → hestia}/rainfallMonthly.py +3 -3
  52. hestia_earth/models/{cycle → hestia}/readyToCookWeightPerHead.py +1 -1
  53. hestia_earth/models/{cycle → hestia}/residueBurnt.py +1 -1
  54. hestia_earth/models/{cycle → hestia}/residueIncorporated.py +1 -1
  55. hestia_earth/models/{cycle → hestia}/residueLeftOnField.py +1 -1
  56. hestia_earth/models/hestia/residueRemoved.py +65 -13
  57. hestia_earth/models/{site → hestia}/salineWater.py +1 -1
  58. hestia_earth/models/{site → hestia}/soilMeasurement.py +1 -1
  59. hestia_earth/models/{cycle → hestia}/stockingDensityAnimalHousingAverage.py +1 -1
  60. hestia_earth/models/{site → hestia}/temperatureAnnual.py +3 -3
  61. hestia_earth/models/{site → hestia}/temperatureMonthly.py +3 -3
  62. hestia_earth/models/{site → hestia}/totalNitrogenPerKgSoil.py +1 -1
  63. hestia_earth/models/{cycle → hestia}/unknownPreSeasonWaterRegime.py +1 -1
  64. hestia_earth/models/hestia/utils.py +93 -0
  65. hestia_earth/models/{site → hestia}/waterDepth.py +1 -1
  66. hestia_earth/models/hestia/waterSalinity.py +78 -0
  67. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +1 -1
  68. hestia_earth/models/ipcc2019/belowGroundBiomass.py +1 -1
  69. hestia_earth/models/ipcc2019/biomass_utils.py +2 -4
  70. hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +166 -79
  71. hestia_earth/models/ipcc2019/ch4ToAirOrganicSoilCultivation.py +270 -0
  72. hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +0 -3
  73. hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +0 -3
  74. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +88 -63
  75. hestia_earth/models/ipcc2019/co2ToAirLimeHydrolysis.py +7 -5
  76. hestia_earth/models/ipcc2019/co2ToAirOrganicSoilCultivation.py +215 -0
  77. hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +0 -3
  78. hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +16 -9
  79. hestia_earth/models/ipcc2019/n2OToAirOrganicSoilCultivationDirect.py +161 -0
  80. hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +35 -47
  81. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +86 -1
  82. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py +127 -1
  83. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +7 -5
  84. hestia_earth/models/ipcc2019/organicSoilCultivation_utils.py +159 -0
  85. hestia_earth/models/mocking/search-results.json +1113 -1113
  86. hestia_earth/models/pooreNemecek2018/utils.py +8 -2
  87. hestia_earth/models/schmidt2007/ch4ToAirWasteTreatment.py +1 -4
  88. hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +1 -4
  89. hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +1 -4
  90. hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +1 -4
  91. hestia_earth/models/site/grouped_measurement.py +132 -0
  92. hestia_earth/models/utils/__init__.py +4 -3
  93. hestia_earth/models/utils/background_emissions.py +52 -0
  94. hestia_earth/models/utils/blank_node.py +47 -14
  95. hestia_earth/models/utils/constant.py +26 -20
  96. hestia_earth/models/utils/impact_assessment.py +26 -17
  97. hestia_earth/models/utils/lookup.py +48 -39
  98. hestia_earth/models/utils/measurement.py +3 -3
  99. hestia_earth/models/utils/product.py +39 -1
  100. hestia_earth/models/utils/property.py +14 -6
  101. hestia_earth/models/version.py +1 -1
  102. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/METADATA +2 -2
  103. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/RECORD +187 -171
  104. tests/models/aware/test_scarcityWeightedWaterUse.py +1 -12
  105. tests/models/ecoalimV9/__init__.py +0 -0
  106. tests/models/ecoalimV9/test_cycle.py +21 -0
  107. tests/models/ecoalimV9/test_impact_assessment.py +24 -0
  108. tests/models/environmentalFootprintV3_1/test_scarcityWeightedWaterUse.py +4 -2
  109. tests/models/{cycle → hestia}/test_aboveGroundCropResidue.py +1 -1
  110. tests/models/{cycle → hestia}/test_aboveGroundCropResidueTotal.py +1 -1
  111. tests/models/{site → hestia}/test_brackishWater.py +1 -1
  112. tests/models/{site → hestia}/test_cationExchangeCapacityPerKgSoil.py +1 -1
  113. tests/models/{cycle → hestia}/test_coldCarcassWeightPerHead.py +1 -1
  114. tests/models/{cycle → hestia}/test_coldDressedCarcassWeightPerHead.py +1 -1
  115. tests/models/{cycle → hestia}/test_concentrateFeed.py +1 -1
  116. tests/models/{cycle → hestia}/test_cropResidueManagement.py +1 -1
  117. tests/models/{cycle → hestia}/test_croppingIntensity.py +1 -1
  118. tests/models/{cycle → hestia}/test_energyContentLowerHeatingValue.py +5 -3
  119. tests/models/{cycle → hestia}/test_excretaKgMass.py +1 -1
  120. tests/models/{cycle → hestia}/test_excretaKgN.py +1 -1
  121. tests/models/{cycle → hestia}/test_excretaKgVs.py +1 -1
  122. tests/models/{cycle → hestia}/test_feedConversionRatio.py +3 -4
  123. tests/models/{site → hestia}/test_flowingWater.py +1 -1
  124. tests/models/{site → hestia}/test_freshWater.py +1 -1
  125. tests/models/{cycle → hestia}/test_inorganicFertiliser.py +1 -1
  126. tests/models/{cycle → hestia}/test_irrigatedTypeUnspecified.py +2 -5
  127. tests/models/hestia/test_landCover.py +4 -34
  128. tests/models/{cycle → hestia}/test_liveAnimal.py +1 -1
  129. tests/models/{cycle → hestia}/test_longFallowRatio.py +1 -1
  130. tests/models/{site → hestia}/test_management.py +1 -1
  131. tests/models/{cycle → hestia}/test_materialsAndSubstrate.py +1 -1
  132. tests/models/{cycle → hestia}/test_milkYield.py +1 -1
  133. tests/models/{site → hestia}/test_netPrimaryProduction.py +1 -1
  134. tests/models/{site → hestia}/test_organicCarbonPerHa.py +1 -1
  135. tests/models/{site → hestia}/test_organicCarbonPerKgSoil.py +1 -1
  136. tests/models/{site → hestia}/test_organicCarbonPerM3Soil.py +1 -1
  137. tests/models/{site → hestia}/test_organicMatterPerKgSoil.py +1 -1
  138. tests/models/{site → hestia}/test_organicMatterPerM3Soil.py +1 -1
  139. tests/models/hestia/test_pToSurfaceWaterAquacultureSystems.py +56 -0
  140. tests/models/{cycle → hestia}/test_pastureGrass.py +1 -1
  141. tests/models/{cycle → hestia}/test_pastureSystem.py +1 -1
  142. tests/models/{site → hestia}/test_potentialEvapotranspirationAnnual.py +1 -1
  143. tests/models/{site → hestia}/test_potentialEvapotranspirationMonthly.py +1 -1
  144. tests/models/{site → hestia}/test_precipitationAnnual.py +1 -1
  145. tests/models/{site → hestia}/test_precipitationMonthly.py +1 -1
  146. tests/models/{site → hestia}/test_rainfallAnnual.py +1 -1
  147. tests/models/{site → hestia}/test_rainfallMonthly.py +1 -1
  148. tests/models/{cycle → hestia}/test_readyToCookWeightPerHead.py +1 -1
  149. tests/models/{cycle → hestia}/test_residueBurnt.py +1 -1
  150. tests/models/{cycle → hestia}/test_residueIncorporated.py +1 -1
  151. tests/models/{cycle → hestia}/test_residueLeftOnField.py +1 -1
  152. tests/models/hestia/test_residueRemoved.py +15 -3
  153. tests/models/{site → hestia}/test_salineWater.py +1 -1
  154. tests/models/{site → hestia}/test_soilMeasurement.py +13 -21
  155. tests/models/{cycle → hestia}/test_stockingDensityAnimalHousingAverage.py +1 -1
  156. tests/models/{site → hestia}/test_temperatureAnnual.py +1 -1
  157. tests/models/{site → hestia}/test_temperatureMonthly.py +1 -1
  158. tests/models/{site → hestia}/test_totalNitrogenPerKgSoil.py +1 -1
  159. tests/models/{cycle → hestia}/test_unknownPreSeasonWaterRegime.py +1 -1
  160. tests/models/{site → hestia}/test_waterDepth.py +1 -1
  161. tests/models/hestia/test_waterSalinity.py +26 -0
  162. tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +2 -5
  163. tests/models/ipcc2019/test_ch4ToAirFloodedRice.py +10 -42
  164. tests/models/ipcc2019/test_ch4ToAirOrganicSoilCultivation.py +61 -0
  165. tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +11 -9
  166. tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +10 -8
  167. tests/models/ipcc2019/test_co2ToAirLimeHydrolysis.py +1 -1
  168. tests/models/ipcc2019/test_co2ToAirOrganicSoilCultivation.py +62 -0
  169. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +11 -8
  170. tests/models/ipcc2019/test_n2OToAirOrganicSoilCultivationDirect.py +61 -0
  171. tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +3 -2
  172. tests/models/site/test_grouped_measurement.py +20 -0
  173. tests/models/test_ecoinventV3AndEmberClimate.py +2 -2
  174. tests/models/test_emissionNotRelevant.py +0 -8
  175. tests/models/utils/test_measurement.py +1 -1
  176. hestia_earth/models/cycle/residueRemoved.py +0 -54
  177. hestia_earth/models/hestia/nh3ToSurfaceWaterAquacultureSystems.py +0 -64
  178. hestia_earth/models/site/utils.py +0 -93
  179. tests/models/cycle/test_residueRemoved.py +0 -37
  180. tests/models/hestia/test_nh3ToSurfaceWaterAquacultureSystems.py +0 -51
  181. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioCarbon.py +0 -0
  182. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioDryMatter.py +0 -0
  183. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioEnergy.py +0 -0
  184. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioFedWeight.py +0 -0
  185. /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioNitrogen.py +0 -0
  186. /hestia_earth/models/{site → hestia}/organicCarbonPerKgSoil.py +0 -0
  187. /hestia_earth/models/{site → hestia}/organicCarbonPerM3Soil.py +0 -0
  188. /hestia_earth/models/{site → hestia}/organicMatterPerKgSoil.py +0 -0
  189. /hestia_earth/models/{site → hestia}/organicMatterPerM3Soil.py +0 -0
  190. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/LICENSE +0 -0
  191. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/WHEEL +0 -0
  192. {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,159 @@
1
+ from enum import Enum
2
+ from typing import Literal
3
+
4
+ from hestia_earth.schema import SiteSiteType
5
+ from hestia_earth.utils.model import find_primary_product
6
+
7
+ from hestia_earth.models.log import debugMissingLookup
8
+ from hestia_earth.models.utils.constant import Units, get_atomic_conversion
9
+ from hestia_earth.models.utils.ecoClimateZone import EcoClimateZone, get_ecoClimateZone_lookup_grouped_value
10
+ from hestia_earth.models.utils.term import get_lookup_value
11
+
12
+ from . import MODEL
13
+
14
+ _PRODUCT_LOOKUP = "IPCC_2013_ORGANIC_SOIL_CULTIVATION_CATEGORY"
15
+ _DITCH_LOOKUP = "IPCC_2013_DRAINED_ORGANIC_SOILS_DITCH_FRAC_"
16
+ _FACTOR_LOOKUPS = {
17
+ "ch4ToAirOrganicSoilCultivation": "IPCC_2013_ORGANIC_SOILS_KG_CH4_HECTARE_",
18
+ "co2ToAirOrganicSoilCultivation": "IPCC_2013_ORGANIC_SOILS_TONNES_CO2-C_HECTARE_",
19
+ "n2OToAirOrganicSoilCultivationDirect": "IPCC_2013_ORGANIC_SOILS_KG_N2O-N_HECTARE_"
20
+ }
21
+ _NETHERLANDS_TERM_ID = "GADM-NLD"
22
+
23
+ _CONVERSION_FACTORS = {
24
+ "co2ToAirOrganicSoilCultivation": 1000 * get_atomic_conversion(Units.KG_CO2, Units.TO_C),
25
+ "ch4ToAirOrganicSoilCultivation": 1000,
26
+ "n2OToAirOrganicSoilCultivationDirect": 1000 * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
27
+ }
28
+ _DEFAULT_FACTOR = {"value": 0}
29
+ _EXCLUDED_ECO_CLIMATE_ZONES = [EcoClimateZone.POLAR_MOIST, EcoClimateZone.POLAR_DRY]
30
+
31
+
32
+ class OrganicSoilCategory(Enum):
33
+ ANNUAL_CROPS = "Annual crops"
34
+ PERENNIAL_CROPS = "Perennial crops"
35
+ ACACIA = "Acacia"
36
+ OIL_PALM = "Oil palm"
37
+ SAGO_PALM = "Sago palm"
38
+ PADDY_RICE_CULTIVATION = "Paddy rice cultivation"
39
+ GRASSLAND = "Grassland"
40
+ DITCH = "Ditch"
41
+ OTHER = "Other"
42
+
43
+
44
+ class DitchCategory(Enum):
45
+ AGRICULTURAL_LAND = "Agricultural land"
46
+ NETHERLANDS = "Netherlands"
47
+
48
+
49
+ def assign_organic_soil_category(cycle: dict, log_id: str) -> OrganicSoilCategory:
50
+ """
51
+ Assign an emission factor category to a cycle based on `site.siteType` and primary product.
52
+
53
+ Cropland cycles without a primary product cannot be categorised - the function will return
54
+ `OrganicSoilCategory.OTHER`.
55
+ """
56
+ site = cycle.get("site", {})
57
+ site_type = site.get("siteType", None)
58
+
59
+ if site_type == SiteSiteType.PERMANENT_PASTURE.value:
60
+ return OrganicSoilCategory.GRASSLAND
61
+
62
+ product = find_primary_product(cycle)
63
+
64
+ if product is None:
65
+ return OrganicSoilCategory.OTHER
66
+
67
+ lookup_value = get_lookup_value(product.get("term", {}), _PRODUCT_LOOKUP, model=MODEL, term=log_id)
68
+
69
+ return (
70
+ next(
71
+ (category for category in OrganicSoilCategory if lookup_value == category.value),
72
+ OrganicSoilCategory.OTHER
73
+ )
74
+ if lookup_value else OrganicSoilCategory.OTHER
75
+ )
76
+
77
+
78
+ def assign_ditch_category(cycle: dict) -> DitchCategory:
79
+ """
80
+ Assign a ditch category to a cycle based. Cycles that take place in Netherlands are given a special category, all
81
+ others return the default.
82
+ """
83
+ site = cycle.get("site", {})
84
+ country_id = site.get("country", {}).get("@id")
85
+ return DitchCategory.NETHERLANDS if country_id == _NETHERLANDS_TERM_ID else DitchCategory.AGRICULTURAL_LAND
86
+
87
+
88
+ def get_emission_factor(
89
+ emission_id: Literal[
90
+ "co2ToAirOrganicSoilCultivation",
91
+ "ch4ToAirOrganicSoilCultivation",
92
+ "n2OToAirOrganicSoilCultivationDirect"
93
+ ],
94
+ eco_climate_zone: EcoClimateZone,
95
+ organic_soil_category: OrganicSoilCategory
96
+ ) -> dict:
97
+ """
98
+ Retrieve emission factor data from the eco-climate zone lookup.
99
+ """
100
+ col_name = "".join([_FACTOR_LOOKUPS[emission_id], organic_soil_category.name])
101
+ row_value = eco_climate_zone.value
102
+
103
+ data = get_ecoClimateZone_lookup_grouped_value(row_value, col_name)
104
+ debugMissingLookup("ecoClimateZone.csv", "ecoClimateZone", row_value, col_name, data, model=MODEL, term=emission_id)
105
+
106
+ return data or _DEFAULT_FACTOR
107
+
108
+
109
+ def get_ditch_frac(
110
+ eco_climate_zone: EcoClimateZone,
111
+ ditch_category: DitchCategory,
112
+ **debug_kwargs: dict
113
+ ) -> dict:
114
+ """
115
+ Retrieve ditch fraction data from the eco-climate zone lookup.
116
+ """
117
+ col_name = "".join([_DITCH_LOOKUP, ditch_category.name])
118
+ row_value = eco_climate_zone.value
119
+
120
+ data = get_ecoClimateZone_lookup_grouped_value(row_value, col_name)
121
+ debugMissingLookup("ecoClimateZone.csv", "ecoClimateZone", row_value, col_name, data, model=MODEL, **debug_kwargs)
122
+
123
+ return data or _DEFAULT_FACTOR
124
+
125
+
126
+ def calc_emission(
127
+ emission_id: Literal[
128
+ "co2ToAirOrganicSoilCultivation",
129
+ "ch4ToAirOrganicSoilCultivation",
130
+ "n2OToAirOrganicSoilCultivationDirect"
131
+ ],
132
+ emission_factor: float,
133
+ histosol: float,
134
+ land_occupation: float
135
+ ):
136
+ """
137
+ Calculate the emission and convert it to kg/ha-1.
138
+ """
139
+ return emission_factor * land_occupation * histosol * _CONVERSION_FACTORS[emission_id] / 100
140
+
141
+
142
+ def remap_categories(
143
+ category: OrganicSoilCategory,
144
+ mapping: dict[OrganicSoilCategory, OrganicSoilCategory]
145
+ ) -> OrganicSoilCategory:
146
+ """
147
+ Remap emission factor categories for cases in which emission factors are not available for a specific category and
148
+ a more general one must be used.
149
+ """
150
+ return mapping.get(category, category)
151
+
152
+
153
+ def valid_eco_climate_zone(
154
+ eco_climate_zone: EcoClimateZone,
155
+ ):
156
+ """
157
+ Validate that the model should run for a specific eco-climate zone.
158
+ """
159
+ return isinstance(eco_climate_zone, EcoClimateZone) and eco_climate_zone not in _EXCLUDED_ECO_CLIMATE_ZONES