hestia-earth-models 0.64.13__py3-none-any.whl → 0.65.0__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.
- hestia_earth/models/agribalyse2016/fuelElectricity.py +1 -1
- hestia_earth/models/cache_sites.py +15 -24
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandTransformation.py +6 -9
- hestia_earth/models/cycle/input/hestiaAggregatedData.py +46 -22
- hestia_earth/models/cycle/materialAndSubstrate.py +158 -0
- hestia_earth/models/cycle/pre_checks/cache_sources.py +3 -25
- hestia_earth/models/cycle/product/economicValueShare.py +2 -2
- hestia_earth/models/environmentalFootprintV3/soilQualityIndexLandTransformation.py +11 -33
- hestia_earth/models/faostat2018/landTransformation100YearAverageDuringCycle.py +34 -0
- hestia_earth/models/faostat2018/landTransformation20YearAverageDuringCycle.py +34 -0
- hestia_earth/models/faostat2018/utils.py +47 -3
- hestia_earth/models/hestia/landCover.py +5 -5
- hestia_earth/models/hestia/seed_emissions.py +275 -0
- hestia_earth/models/ipcc2019/aboveGroundBiomass.py +2 -2
- hestia_earth/models/ipcc2019/belowGroundBiomass.py +8 -2
- hestia_earth/models/ipcc2019/biomass_utils.py +11 -4
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +21 -12
- hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +1 -2
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +2 -1
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +2 -1
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +8 -7
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +2 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +28 -34
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +8 -12
- hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +13 -30
- hestia_earth/models/linkedImpactAssessment/{landTransformationFromCropland20YearAverageInputsProduction.py → landTransformation100YearAverageInputsProduction.py} +5 -2
- hestia_earth/models/linkedImpactAssessment/{landTransformationFromCropland100YearAverageInputsProduction.py → landTransformation20YearAverageInputsProduction.py} +5 -2
- hestia_earth/models/linkedImpactAssessment/utils.py +69 -12
- hestia_earth/models/mocking/__init__.py +1 -1
- hestia_earth/models/mocking/search-results.json +1026 -1026
- hestia_earth/models/pooreNemecek2018/excretaKgN.py +45 -41
- hestia_earth/models/pooreNemecek2018/excretaKgVs.py +89 -63
- hestia_earth/models/pooreNemecek2018/saplingsDepreciatedAmountPerCycle.py +8 -8
- hestia_earth/models/pooreNemecek2018/utils.py +60 -19
- hestia_earth/models/preload_requests.py +24 -4
- hestia_earth/models/schererPfister2015/nErosionSoilFlux.py +4 -3
- hestia_earth/models/schererPfister2015/pErosionSoilFlux.py +4 -3
- hestia_earth/models/schererPfister2015/utils.py +12 -9
- hestia_earth/models/site/management.py +70 -55
- hestia_earth/models/site/pre_checks/cache_sources.py +2 -20
- hestia_earth/models/utils/__init__.py +12 -1
- hestia_earth/models/utils/aggregated.py +1 -1
- hestia_earth/models/utils/blank_node.py +20 -12
- hestia_earth/models/utils/cache_sources.py +15 -0
- hestia_earth/models/utils/constant.py +3 -0
- hestia_earth/models/utils/crop.py +5 -0
- hestia_earth/models/utils/indicator.py +3 -1
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.64.13.dist-info → hestia_earth_models-0.65.0.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.64.13.dist-info → hestia_earth_models-0.65.0.dist-info}/RECORD +81 -108
- tests/models/cml2001Baseline/test_abioticResourceDepletionMineralsAndMetals.py +1 -1
- tests/models/cycle/input/test_hestiaAggregatedData.py +5 -2
- tests/models/cycle/test_materialsAndSubstrate.py +49 -0
- tests/models/environmentalFootprintV3/test_soilQualityIndexLandTransformation.py +39 -28
- tests/models/{hyde32/test_landTransformationFromForest20YearAverageDuringCycle.py → faostat2018/test_landTransformation100YearAverageDuringCycle.py} +5 -5
- tests/models/{hyde32/test_landTransformationFromForest100YearAverageDuringCycle.py → faostat2018/test_landTransformation20YearAverageDuringCycle.py} +5 -5
- tests/models/faostat2018/test_utils.py +28 -0
- tests/models/hestia/test_landCover.py +2 -1
- tests/models/hestia/test_seed_emissions.py +27 -0
- tests/models/ipcc2019/test_aboveGroundBiomass.py +40 -4
- tests/models/ipcc2019/test_belowGroundBiomass.py +40 -4
- tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +52 -15
- tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +50 -14
- tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +53 -32
- tests/models/ipcc2019/test_organicCarbonPerHa.py +91 -108
- tests/models/ipcc2019/test_organicCarbonPerHa_tier_1_utils.py +33 -50
- tests/models/ipcc2019/test_organicCarbonPerHa_tier_2_utils.py +0 -52
- tests/models/linkedImpactAssessment/test_freshwaterWithdrawalsInputsProduction.py +6 -4
- tests/models/linkedImpactAssessment/test_landOccupationInputsProduction.py +6 -4
- tests/models/linkedImpactAssessment/{test_landTransformationFromForest100YearAverageInputsProduction.py → test_landTransformation100YearAverageInputsProduction.py} +7 -5
- tests/models/linkedImpactAssessment/{test_landTransformationFromForest20YearAverageInputsProduction.py → test_landTransformation20YearAverageInputsProduction.py} +7 -5
- tests/models/pooreNemecek2018/test_excretaKgN.py +2 -2
- tests/models/pooreNemecek2018/test_excretaKgVs.py +1 -1
- tests/models/pooreNemecek2018/test_utils.py +26 -0
- tests/models/site/test_management.py +10 -27
- tests/models/test_cache_sites.py +40 -12
- tests/models/utils/test_blank_node.py +0 -8
- tests/models/utils/test_cache_sources.py +21 -0
- hestia_earth/models/blonkConsultants2016/landTransformationFromForest20YearAverageDuringCycle.py +0 -90
- hestia_earth/models/faostat2018/landTransformationFromCropland100YearAverage.py +0 -74
- hestia_earth/models/faostat2018/landTransformationFromCropland20YearAverage.py +0 -74
- hestia_earth/models/hyde32/__init__.py +0 -13
- hestia_earth/models/hyde32/landTransformationFromCropland100YearAverageDuringCycle.py +0 -60
- hestia_earth/models/hyde32/landTransformationFromCropland20YearAverageDuringCycle.py +0 -60
- hestia_earth/models/hyde32/landTransformationFromForest100YearAverageDuringCycle.py +0 -60
- hestia_earth/models/hyde32/landTransformationFromForest20YearAverageDuringCycle.py +0 -60
- hestia_earth/models/hyde32/landTransformationFromOtherNaturalVegetation100YearAverageDuringCycle.py +0 -61
- hestia_earth/models/hyde32/landTransformationFromOtherNaturalVegetation20YearAverageDuringCycle.py +0 -61
- hestia_earth/models/hyde32/landTransformationFromPermanentPasture100YearAverageDuringCycle.py +0 -61
- hestia_earth/models/hyde32/landTransformationFromPermanentPasture20YearAverageDuringCycle.py +0 -61
- hestia_earth/models/hyde32/utils.py +0 -72
- hestia_earth/models/linkedImpactAssessment/landTransformationFromForest100YearAverageInputsProduction.py +0 -36
- hestia_earth/models/linkedImpactAssessment/landTransformationFromForest20YearAverageInputsProduction.py +0 -36
- hestia_earth/models/linkedImpactAssessment/landTransformationFromOtherNaturalVegetation100YearAverageInputsProduction.py +0 -36
- hestia_earth/models/linkedImpactAssessment/landTransformationFromOtherNaturalVegetation20YearAverageInputsProduction.py +0 -36
- hestia_earth/models/linkedImpactAssessment/landTransformationFromPermanentPasture100YearAverageInputsProduction.py +0 -36
- hestia_earth/models/linkedImpactAssessment/landTransformationFromPermanentPasture20YearAverageInputsProduction.py +0 -36
- tests/models/blonkConsultants2016/test_landTransformationFromForest20YearAverageDuringCycle.py +0 -36
- tests/models/cycle/pre_checks/test_cache_sources.py +0 -25
- tests/models/faostat2018/test_landTransformationFromCropland100YearAverage.py +0 -40
- tests/models/faostat2018/test_landTransformationFromCropland20YearAverage.py +0 -40
- tests/models/hyde32/__init__.py +0 -0
- tests/models/hyde32/test_landTransformationFromCropland100YearAverageDuringCycle.py +0 -21
- tests/models/hyde32/test_landTransformationFromCropland20YearAverageDuringCycle.py +0 -21
- tests/models/hyde32/test_landTransformationFromOtherNaturalVegetation100YearAverageDuringCycle.py +0 -23
- tests/models/hyde32/test_landTransformationFromOtherNaturalVegetation20YearAverageDuringCycle.py +0 -21
- tests/models/hyde32/test_landTransformationFromPermanentPasture100YearAverageDuringCycle.py +0 -21
- tests/models/hyde32/test_landTransformationFromPermanentPasture20YearAverageDuringCycle.py +0 -21
- tests/models/linkedImpactAssessment/test_landTransformationFromCropland100YearAverageInputsProduction.py +0 -23
- tests/models/linkedImpactAssessment/test_landTransformationFromCropland20YearAverageInputsProduction.py +0 -23
- tests/models/linkedImpactAssessment/test_landTransformationFromOtherNaturalVegetation100YearAverageInputsProduction.py +0 -23
- tests/models/linkedImpactAssessment/test_landTransformationFromOtherNaturalVegetation20YearAverageInputsProduction.py +0 -23
- tests/models/linkedImpactAssessment/test_landTransformationFromPermanentPasture100YearAverageInputsProduction.py +0 -24
- tests/models/linkedImpactAssessment/test_landTransformationFromPermanentPasture20YearAverageInputsProduction.py +0 -24
- tests/models/site/pre_checks/test_cache_sources.py +0 -21
- {hestia_earth_models-0.64.13.dist-info → hestia_earth_models-0.65.0.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.64.13.dist-info → hestia_earth_models-0.65.0.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.64.13.dist-info → hestia_earth_models-0.65.0.dist-info}/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ from hestia_earth.models.log import logRequirements, logShouldRun
|
|
|
4
4
|
from hestia_earth.models.utils.blank_node import cumulative_nodes_term_match
|
|
5
5
|
from hestia_earth.models.utils.emission import _new_emission
|
|
6
6
|
|
|
7
|
-
from .organicCarbonPerHa_tier_1_utils import _assign_ipcc_land_use_category
|
|
7
|
+
from .organicCarbonPerHa_tier_1_utils import _assign_ipcc_land_use_category, get_valid_management_nodes
|
|
8
8
|
from .co2ToAirCarbonStockChange_utils import create_run_function, create_should_run_function
|
|
9
9
|
from . import MODEL
|
|
10
10
|
|
|
@@ -125,6 +125,7 @@ def run(cycle: dict) -> list[dict]:
|
|
|
125
125
|
"""
|
|
126
126
|
should_run_exec = create_should_run_function(
|
|
127
127
|
carbon_stock_term_id=_CARBON_STOCK_TERM_ID,
|
|
128
|
+
get_valid_management_nodes_func=get_valid_management_nodes,
|
|
128
129
|
should_compile_inventory_func=_should_compile_inventory_func,
|
|
129
130
|
summarise_land_use_func=lambda nodes: _assign_ipcc_land_use_category(nodes, None),
|
|
130
131
|
detect_land_use_change_func=lambda a, b: a != b,
|
|
@@ -21,24 +21,25 @@ from hestia_earth.schema import MeasurementMethodClassification, SiteSiteType, T
|
|
|
21
21
|
from hestia_earth.utils.model import find_term_match, filter_list_term_type
|
|
22
22
|
from hestia_earth.utils.blank_node import get_node_value
|
|
23
23
|
|
|
24
|
+
from hestia_earth.models.utils import split_on_condition
|
|
24
25
|
from hestia_earth.models.utils.array_builders import gen_seed
|
|
25
26
|
from hestia_earth.models.utils.blank_node import (
|
|
26
|
-
cumulative_nodes_match, cumulative_nodes_lookup_match, cumulative_nodes_term_match,
|
|
27
|
-
|
|
27
|
+
cumulative_nodes_match, cumulative_nodes_lookup_match, cumulative_nodes_term_match, node_lookup_match,
|
|
28
|
+
node_term_match, group_nodes_by_year, validate_start_date_end_date
|
|
28
29
|
)
|
|
29
30
|
from hestia_earth.models.utils.ecoClimateZone import EcoClimateZone, get_eco_climate_zone_value
|
|
30
31
|
from hestia_earth.models.utils.descriptive_stats import calc_descriptive_stats
|
|
31
32
|
from hestia_earth.models.utils.measurement import _new_measurement
|
|
32
33
|
from hestia_earth.models.utils.property import get_node_property
|
|
34
|
+
from hestia_earth.models.utils.term import get_residue_removed_or_burnt_terms, get_upland_rice_land_cover_terms
|
|
33
35
|
|
|
34
36
|
from .organicCarbonPerHa_utils import (
|
|
35
|
-
check_irrigation, DEPTH_LOWER, DEPTH_UPPER,
|
|
36
|
-
|
|
37
|
-
IPCC_SOIL_CATEGORY_TO_SOIL_TYPE_LOOKUP_VALUE, IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE,
|
|
38
|
-
IPCC_MANAGEMENT_CATEGORY_TO_GRASSLAND_MANAGEMENT_TERM_ID,
|
|
37
|
+
check_irrigation, DEPTH_LOWER, DEPTH_UPPER, IPCC_SOIL_CATEGORY_TO_SOIL_TYPE_LOOKUP_VALUE,
|
|
38
|
+
IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE, IPCC_MANAGEMENT_CATEGORY_TO_GRASSLAND_MANAGEMENT_TERM_ID,
|
|
39
39
|
IPCC_MANAGEMENT_CATEGORY_TO_TILLAGE_MANAGEMENT_LOOKUP_VALUE, IpccSoilCategory, IpccCarbonInputCategory,
|
|
40
|
-
IpccLandUseCategory, IpccManagementCategory, MIN_AREA_THRESHOLD, sample_constant,
|
|
41
|
-
sample_plus_minus_uncertainty, SITE_TYPE_TO_IPCC_LAND_USE_CATEGORY,
|
|
40
|
+
IpccLandUseCategory, IpccManagementCategory, is_cover_crop, MIN_AREA_THRESHOLD, sample_constant,
|
|
41
|
+
sample_plus_minus_error, sample_plus_minus_uncertainty, SITE_TYPE_TO_IPCC_LAND_USE_CATEGORY,
|
|
42
|
+
SUPER_MAJORITY_AREA_THRESHOLD, STATS_DEFINITION
|
|
42
43
|
)
|
|
43
44
|
|
|
44
45
|
_LOOKUPS = {
|
|
@@ -647,7 +648,7 @@ def should_run(site: dict) -> tuple[bool, dict, dict]:
|
|
|
647
648
|
A tuple containing `(should_run_, inventory, kwargs, logs)`.
|
|
648
649
|
"""
|
|
649
650
|
site_type = site.get("siteType", "")
|
|
650
|
-
management_nodes = site
|
|
651
|
+
management_nodes = get_valid_management_nodes(site)
|
|
651
652
|
measurement_nodes = site.get("measurements", [])
|
|
652
653
|
|
|
653
654
|
eco_climate_zone = get_eco_climate_zone_value(site, as_enum=True)
|
|
@@ -695,6 +696,11 @@ def should_run(site: dict) -> tuple[bool, dict, dict]:
|
|
|
695
696
|
return should_run_, inventory, kwargs, logs
|
|
696
697
|
|
|
697
698
|
|
|
699
|
+
def get_valid_management_nodes(site: dict) -> list[dict]:
|
|
700
|
+
"""Retrieve valid mangement nodes from a site."""
|
|
701
|
+
return [node for node in site.get("management", []) if validate_start_date_end_date(node)]
|
|
702
|
+
|
|
703
|
+
|
|
698
704
|
def run(
|
|
699
705
|
inventory: dict,
|
|
700
706
|
*,
|
|
@@ -1209,22 +1215,20 @@ def _assign_ipcc_land_use_category(
|
|
|
1209
1215
|
DECISION_TREE = _LAND_USE_CATEGORY_DECISION_TREE
|
|
1210
1216
|
DEFAULT = IpccLandUseCategory.OTHER
|
|
1211
1217
|
|
|
1212
|
-
land_cover_nodes =
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
if validate_start_date_end_date(node)
|
|
1219
|
-
]
|
|
1218
|
+
cover_crop_nodes, land_cover_nodes = split_on_condition(
|
|
1219
|
+
filter_list_term_type(management_nodes, [TermTermType.LANDCOVER]),
|
|
1220
|
+
is_cover_crop
|
|
1221
|
+
)
|
|
1222
|
+
|
|
1223
|
+
water_regime_nodes = filter_list_term_type(management_nodes, [TermTermType.WATERREGIME])
|
|
1220
1224
|
|
|
1221
1225
|
has_irrigation = check_irrigation(water_regime_nodes)
|
|
1222
1226
|
has_upland_rice = _has_upland_rice(land_cover_nodes)
|
|
1223
1227
|
has_irrigated_upland_rice = has_upland_rice and has_irrigation
|
|
1224
|
-
has_long_fallow = _has_long_fallow(
|
|
1228
|
+
has_long_fallow = _has_long_fallow(cover_crop_nodes)
|
|
1225
1229
|
has_wetland_soils = ipcc_soil_category is IpccSoilCategory.WETLAND_SOILS
|
|
1226
1230
|
|
|
1227
|
-
should_run_ =
|
|
1231
|
+
should_run_ = land_cover_nodes or cover_crop_nodes
|
|
1228
1232
|
|
|
1229
1233
|
return next(
|
|
1230
1234
|
(
|
|
@@ -1257,7 +1261,7 @@ def _has_upland_rice(land_cover_nodes: list[dict]) -> bool:
|
|
|
1257
1261
|
"""
|
|
1258
1262
|
return cumulative_nodes_term_match(
|
|
1259
1263
|
land_cover_nodes,
|
|
1260
|
-
target_term_ids=
|
|
1264
|
+
target_term_ids=get_upland_rice_land_cover_terms(),
|
|
1261
1265
|
cumulative_threshold=SUPER_MAJORITY_AREA_THRESHOLD
|
|
1262
1266
|
)
|
|
1263
1267
|
|
|
@@ -1278,14 +1282,7 @@ def _has_long_fallow(land_cover_nodes: list[dict]) -> bool:
|
|
|
1278
1282
|
bool
|
|
1279
1283
|
`True` if long fallow is present, `False` otherwise.
|
|
1280
1284
|
"""
|
|
1281
|
-
|
|
1282
|
-
TARGET_LOOKUP_VALUE = "Set aside"
|
|
1283
|
-
return cumulative_nodes_lookup_match(
|
|
1284
|
-
land_cover_nodes,
|
|
1285
|
-
lookup=LOOKUP,
|
|
1286
|
-
target_lookup_values=TARGET_LOOKUP_VALUE,
|
|
1287
|
-
cumulative_threshold=SUPER_MAJORITY_AREA_THRESHOLD
|
|
1288
|
-
) or cumulative_nodes_match(
|
|
1285
|
+
return cumulative_nodes_match(
|
|
1289
1286
|
lambda node: get_node_property(node, _LONG_FALLOW_CROP_TERM_ID, False).get("value", 0),
|
|
1290
1287
|
land_cover_nodes,
|
|
1291
1288
|
cumulative_threshold=SUPER_MAJORITY_AREA_THRESHOLD
|
|
@@ -1337,7 +1334,6 @@ def _check_ipcc_land_use_category(*, key: IpccLandUseCategory, land_cover_nodes:
|
|
|
1337
1334
|
|
|
1338
1335
|
_IPCC_LAND_USE_CATEGORY_TO_VALIDATION_KWARGS = {
|
|
1339
1336
|
IpccLandUseCategory.ANNUAL_CROPS_WET: {"has_wetland_soils"},
|
|
1340
|
-
IpccLandUseCategory.SET_ASIDE: {"has_long_fallow"},
|
|
1341
1337
|
}
|
|
1342
1338
|
"""
|
|
1343
1339
|
Keyword arguments that need to be validated in addition to the `landCover` lookup match for specific
|
|
@@ -1345,6 +1341,7 @@ Keyword arguments that need to be validated in addition to the `landCover` looku
|
|
|
1345
1341
|
"""
|
|
1346
1342
|
|
|
1347
1343
|
_IPCC_LAND_USE_CATEGORY_TO_OVERRIDE_KWARGS = {
|
|
1344
|
+
IpccLandUseCategory.SET_ASIDE: {"has_long_fallow"},
|
|
1348
1345
|
IpccLandUseCategory.PADDY_RICE_CULTIVATION: {"has_irrigated_upland_rice"}
|
|
1349
1346
|
}
|
|
1350
1347
|
"""
|
|
@@ -1960,10 +1957,7 @@ def _get_carbon_input_kwargs(
|
|
|
1960
1957
|
)
|
|
1961
1958
|
|
|
1962
1959
|
has_cover_crop = cumulative_nodes_match(
|
|
1963
|
-
|
|
1964
|
-
get_node_property(node, term_id, False).get("value", False)
|
|
1965
|
-
for term_id in get_cover_crop_property_terms_with_cache()
|
|
1966
|
-
),
|
|
1960
|
+
is_cover_crop,
|
|
1967
1961
|
land_cover_nodes,
|
|
1968
1962
|
cumulative_threshold=MIN_AREA_THRESHOLD
|
|
1969
1963
|
)
|
|
@@ -2007,7 +2001,7 @@ def _get_carbon_input_kwargs(
|
|
|
2007
2001
|
|
|
2008
2002
|
has_residue_removed_or_burnt = cumulative_nodes_term_match(
|
|
2009
2003
|
crop_residue_management_nodes,
|
|
2010
|
-
target_term_ids=
|
|
2004
|
+
target_term_ids=get_residue_removed_or_burnt_terms(),
|
|
2011
2005
|
cumulative_threshold=MIN_AREA_THRESHOLD
|
|
2012
2006
|
)
|
|
2013
2007
|
|
|
@@ -25,22 +25,21 @@ from hestia_earth.models.utils.array_builders import (
|
|
|
25
25
|
avg_run_in_columnwise, gen_seed, grouped_avg, repeat_1d_array_as_columns
|
|
26
26
|
)
|
|
27
27
|
from hestia_earth.models.utils.blank_node import (
|
|
28
|
-
cumulative_nodes_lookup_match, cumulative_nodes_term_match, group_nodes_by_year,
|
|
29
|
-
|
|
28
|
+
cumulative_nodes_lookup_match, cumulative_nodes_term_match, group_nodes_by_year, group_nodes_by_year_and_month,
|
|
29
|
+
GroupNodesByYearMode, node_lookup_match, node_term_match
|
|
30
30
|
)
|
|
31
31
|
from hestia_earth.models.utils.cycle import check_cycle_site_ids_identical
|
|
32
32
|
from hestia_earth.models.utils.descriptive_stats import calc_descriptive_stats
|
|
33
33
|
from hestia_earth.models.utils.measurement import _new_measurement
|
|
34
34
|
from hestia_earth.models.utils.property import get_node_property
|
|
35
35
|
from hestia_earth.models.utils.site import related_cycles
|
|
36
|
+
from hestia_earth.models.utils.term import get_upland_rice_crop_terms, get_upland_rice_land_cover_terms
|
|
36
37
|
|
|
37
38
|
from .organicCarbonPerHa_utils import (
|
|
38
39
|
CarbonSource, check_consecutive, DEPTH_LOWER, DEPTH_UPPER, check_irrigation,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
MIN_AREA_THRESHOLD, MIN_YIELD_THRESHOLD, sample_constant, sample_plus_minus_uncertainty, sample_truncated_normal,
|
|
43
|
-
STATS_DEFINITION
|
|
40
|
+
IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE, IPCC_MANAGEMENT_CATEGORY_TO_TILLAGE_MANAGEMENT_LOOKUP_VALUE,
|
|
41
|
+
IpccLandUseCategory, IpccManagementCategory, is_cover_crop, MIN_AREA_THRESHOLD, MIN_YIELD_THRESHOLD,
|
|
42
|
+
sample_constant, sample_plus_minus_uncertainty, sample_truncated_normal, STATS_DEFINITION
|
|
44
43
|
)
|
|
45
44
|
|
|
46
45
|
_LOOKUPS = {
|
|
@@ -1410,10 +1409,7 @@ def _should_run_carbon_source_cover_crop(node: dict) -> bool:
|
|
|
1410
1409
|
node_lookup_match(
|
|
1411
1410
|
node, LOOKUP, IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE[IpccLandUseCategory.ANNUAL_CROPS]
|
|
1412
1411
|
),
|
|
1413
|
-
|
|
1414
|
-
get_node_property(node, term_id, False).get("value", False)
|
|
1415
|
-
for term_id in get_cover_crop_property_terms_with_cache()
|
|
1416
|
-
)
|
|
1412
|
+
is_cover_crop(node)
|
|
1417
1413
|
])
|
|
1418
1414
|
|
|
1419
1415
|
|
|
@@ -1744,7 +1740,7 @@ def _check_is_paddy_rice(cycles: list[dict]) -> bool:
|
|
|
1744
1740
|
cycle.get("products", []) + cycle.get("practices", []),
|
|
1745
1741
|
[TermTermType.CROP, TermTermType.FORAGE, TermTermType.LANDCOVER]
|
|
1746
1742
|
),
|
|
1747
|
-
target_term_ids=
|
|
1743
|
+
target_term_ids=get_upland_rice_crop_terms() + get_upland_rice_land_cover_terms(),
|
|
1748
1744
|
cumulative_threshold=MIN_YIELD_THRESHOLD,
|
|
1749
1745
|
default_node_value=MIN_YIELD_THRESHOLD
|
|
1750
1746
|
) for cycle in cycles)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
|
-
from functools import lru_cache
|
|
3
2
|
from numpy.typing import NDArray
|
|
4
3
|
from typing import NamedTuple, Optional
|
|
5
4
|
|
|
@@ -8,11 +7,8 @@ from hestia_earth.schema import MeasurementStatsDefinition, SiteSiteType
|
|
|
8
7
|
from hestia_earth.models.utils.array_builders import (
|
|
9
8
|
repeat_single, plus_minus_uncertainty_to_normal_1d, truncated_normal_1d
|
|
10
9
|
)
|
|
11
|
-
from hestia_earth.models.utils.blank_node import cumulative_nodes_term_match
|
|
12
|
-
from hestia_earth.models.utils.term import
|
|
13
|
-
get_cover_crop_property_terms, get_irrigated_terms, get_residue_removed_or_burnt_terms, get_upland_rice_crop_terms,
|
|
14
|
-
get_upland_rice_land_cover_terms
|
|
15
|
-
)
|
|
10
|
+
from hestia_earth.models.utils.blank_node import cumulative_nodes_term_match, node_term_match
|
|
11
|
+
from hestia_earth.models.utils.term import get_cover_crop_property_terms, get_irrigated_terms
|
|
16
12
|
|
|
17
13
|
STATS_DEFINITION = MeasurementStatsDefinition.SIMULATED.value
|
|
18
14
|
DEPTH_UPPER = 0
|
|
@@ -23,26 +19,6 @@ SUPER_MAJORITY_AREA_THRESHOLD = 100 - MIN_AREA_THRESHOLD
|
|
|
23
19
|
MIN_YIELD_THRESHOLD = 1
|
|
24
20
|
|
|
25
21
|
|
|
26
|
-
def get_cover_crop_property_terms_with_cache():
|
|
27
|
-
return lru_cache()(get_cover_crop_property_terms)()
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
def get_irrigated_terms_with_cache():
|
|
31
|
-
return lru_cache()(get_irrigated_terms)()
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def get_residue_removed_or_burnt_terms_with_cache():
|
|
35
|
-
return lru_cache()(get_residue_removed_or_burnt_terms)()
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def get_upland_rice_crop_terms_with_cache():
|
|
39
|
-
return lru_cache()(get_upland_rice_crop_terms)()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def get_upland_rice_land_cover_terms_with_cache():
|
|
43
|
-
return lru_cache()(get_upland_rice_land_cover_terms)()
|
|
44
|
-
|
|
45
|
-
|
|
46
22
|
class IpccSoilCategory(Enum):
|
|
47
23
|
"""
|
|
48
24
|
Enum representing IPCC Soil Categories.
|
|
@@ -106,9 +82,7 @@ IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE = {
|
|
|
106
82
|
IpccLandUseCategory.PADDY_RICE_CULTIVATION: "Paddy rice cultivation",
|
|
107
83
|
IpccLandUseCategory.ANNUAL_CROPS_WET: "Annual crops",
|
|
108
84
|
IpccLandUseCategory.ANNUAL_CROPS: "Annual crops",
|
|
109
|
-
IpccLandUseCategory.SET_ASIDE:
|
|
110
|
-
"Annual crops", "Paddy rice cultivation", "Perennial crops", "Set aside"
|
|
111
|
-
],
|
|
85
|
+
IpccLandUseCategory.SET_ASIDE: "Set aside",
|
|
112
86
|
IpccLandUseCategory.FOREST: "Forest",
|
|
113
87
|
IpccLandUseCategory.NATIVE: "Native"
|
|
114
88
|
}
|
|
@@ -236,11 +210,20 @@ def check_irrigation(water_regime_nodes: list[dict]) -> bool:
|
|
|
236
210
|
"""
|
|
237
211
|
return cumulative_nodes_term_match(
|
|
238
212
|
water_regime_nodes,
|
|
239
|
-
target_term_ids=
|
|
213
|
+
target_term_ids=get_irrigated_terms(),
|
|
240
214
|
cumulative_threshold=MIN_AREA_THRESHOLD
|
|
241
215
|
)
|
|
242
216
|
|
|
243
217
|
|
|
218
|
+
def is_cover_crop(node: dict) -> bool:
|
|
219
|
+
"""Check if a `landCover` node represents a cover crop."""
|
|
220
|
+
COVER_CROP_TERM_IDS = get_cover_crop_property_terms()
|
|
221
|
+
return any(
|
|
222
|
+
prop.get("value", False) for prop in node.get("properties", [])
|
|
223
|
+
if node_term_match(prop, COVER_CROP_TERM_IDS)
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
|
|
244
227
|
def sample_truncated_normal(
|
|
245
228
|
*, iterations: int, value: float, sd: float, min: float, max: float, seed: Optional[int] = None, **_
|
|
246
229
|
) -> NDArray:
|
|
@@ -17,7 +17,10 @@ REQUIREMENTS = {
|
|
|
17
17
|
"@type": "ImpactAssessment",
|
|
18
18
|
"emissionsResourceUse": [{
|
|
19
19
|
"@type": "Indicator",
|
|
20
|
-
"term.@id":
|
|
20
|
+
"term.@id": [
|
|
21
|
+
"landTransformation100YearAverageDuringCycle",
|
|
22
|
+
"landTransformation100YearAverageInputsProduction"
|
|
23
|
+
],
|
|
21
24
|
"value": "> 0"
|
|
22
25
|
}]
|
|
23
26
|
}
|
|
@@ -30,7 +33,7 @@ RETURNS = {
|
|
|
30
33
|
"value": ""
|
|
31
34
|
}]
|
|
32
35
|
}
|
|
33
|
-
TERM_ID = '
|
|
36
|
+
TERM_ID = 'landTransformation100YearAverageInputsProduction'
|
|
34
37
|
|
|
35
38
|
|
|
36
39
|
def run(impact_assessment: dict): return run_inputs_production(impact_assessment, TERM_ID)
|
|
@@ -17,7 +17,10 @@ REQUIREMENTS = {
|
|
|
17
17
|
"@type": "ImpactAssessment",
|
|
18
18
|
"emissionsResourceUse": [{
|
|
19
19
|
"@type": "Indicator",
|
|
20
|
-
"term.@id":
|
|
20
|
+
"term.@id": [
|
|
21
|
+
"landTransformation20YearAverageDuringCycle",
|
|
22
|
+
"landTransformation20YearAverageInputsProduction"
|
|
23
|
+
],
|
|
21
24
|
"value": "> 0"
|
|
22
25
|
}]
|
|
23
26
|
}
|
|
@@ -30,7 +33,7 @@ RETURNS = {
|
|
|
30
33
|
"value": ""
|
|
31
34
|
}]
|
|
32
35
|
}
|
|
33
|
-
TERM_ID = '
|
|
36
|
+
TERM_ID = 'landTransformation20YearAverageInputsProduction'
|
|
34
37
|
|
|
35
38
|
|
|
36
39
|
def run(impact_assessment: dict): return run_inputs_production(impact_assessment, TERM_ID)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
from
|
|
1
|
+
from functools import reduce
|
|
2
|
+
from hestia_earth.utils.tools import non_empty_list, flatten, list_sum
|
|
2
3
|
|
|
3
|
-
from hestia_earth.models.log import
|
|
4
|
-
from hestia_earth.models.utils import sum_values
|
|
4
|
+
from hestia_earth.models.log import log_as_table, logRequirements, logShouldRun
|
|
5
|
+
from hestia_earth.models.utils import sum_values, _include
|
|
5
6
|
from hestia_earth.models.utils.indicator import _new_indicator
|
|
6
7
|
from hestia_earth.models.utils.impact_assessment import get_product, convert_value_from_cycle
|
|
7
|
-
from hestia_earth.models.utils.input import
|
|
8
|
+
from hestia_earth.models.utils.input import load_impacts
|
|
8
9
|
from . import MODEL
|
|
9
10
|
|
|
10
11
|
|
|
@@ -14,17 +15,72 @@ def _indicator(term_id: str, value: float):
|
|
|
14
15
|
return indicator
|
|
15
16
|
|
|
16
17
|
|
|
18
|
+
def _run_indicators(product: dict, term_id: str):
|
|
19
|
+
def run(values: list):
|
|
20
|
+
indicator = values[0].get('indicator')
|
|
21
|
+
values_from_cycle = non_empty_list([
|
|
22
|
+
list_sum(value.get('input').get('value')) * value.get('indicator').get('value')
|
|
23
|
+
for value in values
|
|
24
|
+
])
|
|
25
|
+
value = convert_value_from_cycle(product, sum_values(values_from_cycle), model=MODEL, term_id=term_id)
|
|
26
|
+
return _indicator(term_id, value) | _include(indicator, ['landCover', 'previousLandCover'])
|
|
27
|
+
return run
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _group_indicator(group: dict, value: dict):
|
|
31
|
+
group_key = ';'.join(non_empty_list([
|
|
32
|
+
value.get('indicator').get('landCover', {}).get('@id'),
|
|
33
|
+
value.get('indicator').get('previousLandCover', {}).get('@id')
|
|
34
|
+
]))
|
|
35
|
+
group[group_key] = group.get(group_key, []) + [value]
|
|
36
|
+
return group
|
|
37
|
+
|
|
38
|
+
|
|
17
39
|
def _run_inputs_production(impact_assessment: dict, product: dict, term_id: str):
|
|
18
40
|
cycle = impact_assessment.get('cycle', {})
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
41
|
+
|
|
42
|
+
# group all indicators per `landCover` and `previousLandCover`
|
|
43
|
+
all_indicators = flatten([
|
|
44
|
+
{
|
|
45
|
+
'indicator': indicator,
|
|
46
|
+
'input': input
|
|
47
|
+
}
|
|
48
|
+
for input in load_impacts(cycle.get('inputs', []))
|
|
49
|
+
for indicator in (
|
|
50
|
+
input.get('impactAssessment', {}).get('emissionsResourceUse', []) +
|
|
51
|
+
input.get('impactAssessment', {}).get('impacts', [])
|
|
52
|
+
)
|
|
53
|
+
if indicator.get('term', {}).get('@id') in [
|
|
54
|
+
term_id,
|
|
55
|
+
term_id.replace('InputsProduction', 'DuringCycle')
|
|
56
|
+
]
|
|
22
57
|
])
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
58
|
+
valid_indicators = [
|
|
59
|
+
value
|
|
60
|
+
for value in all_indicators
|
|
61
|
+
if all([
|
|
62
|
+
value.get('indicator').get('value', -1) > 0,
|
|
63
|
+
list_sum(value.get('input').get('value', [-1]), 0) > 0
|
|
64
|
+
])
|
|
65
|
+
]
|
|
66
|
+
grouped_indicators = reduce(_group_indicator, valid_indicators, {})
|
|
67
|
+
has_indicators = bool(valid_indicators)
|
|
68
|
+
|
|
69
|
+
logRequirements(impact_assessment, model=MODEL, term=term_id,
|
|
70
|
+
indicators=log_as_table([
|
|
71
|
+
{
|
|
72
|
+
'indicator-id': value.get('indicator').get('term', {}).get('@id'),
|
|
73
|
+
'indicator-value': value.get('indicator').get('value'),
|
|
74
|
+
'input-id': value.get('input').get('term', {}).get('@id'),
|
|
75
|
+
'input-value': list_sum(value.get('input').get('value')),
|
|
76
|
+
}
|
|
77
|
+
for value in all_indicators
|
|
78
|
+
]))
|
|
79
|
+
|
|
80
|
+
should_run = all([has_indicators])
|
|
81
|
+
logShouldRun(impact_assessment, MODEL, term_id, should_run)
|
|
82
|
+
|
|
83
|
+
return flatten(map(_run_indicators(product, term_id), grouped_indicators.values()))
|
|
28
84
|
|
|
29
85
|
|
|
30
86
|
def _should_run_inputs_production(impact_assessment: dict, term_id: str):
|
|
@@ -35,6 +91,7 @@ def _should_run_inputs_production(impact_assessment: dict, term_id: str):
|
|
|
35
91
|
product=product_id)
|
|
36
92
|
|
|
37
93
|
should_run = all([product])
|
|
94
|
+
logShouldRun(impact_assessment, MODEL, term_id, should_run)
|
|
38
95
|
return should_run, product
|
|
39
96
|
|
|
40
97
|
|