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.
- hestia_earth/models/aware/scarcityWeightedWaterUse.py +8 -16
- hestia_earth/models/cml2001Baseline/resourceUseMineralsAndMetalsDuringCycle.py +2 -1
- hestia_earth/models/config/Cycle.json +98 -50
- hestia_earth/models/config/ImpactAssessment.json +12 -4
- hestia_earth/models/config/Site.json +40 -21
- hestia_earth/models/cycle/transformation.py +1 -1
- hestia_earth/models/cycle/utils.py +0 -6
- hestia_earth/models/data/ecoinventV3/__init__.py +15 -13
- hestia_earth/models/ecoalimV9/__init__.py +13 -0
- hestia_earth/models/ecoalimV9/cycle.py +128 -0
- hestia_earth/models/ecoalimV9/impact_assessment.py +125 -0
- hestia_earth/models/ecoalimV9/utils.py +31 -0
- hestia_earth/models/ecoinventV3/__init__.py +6 -14
- hestia_earth/models/ecoinventV3/utils.py +1 -29
- hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +8 -2
- hestia_earth/models/emissionNotRelevant/__init__.py +33 -8
- hestia_earth/models/{cycle → hestia}/aboveGroundCropResidue.py +4 -3
- hestia_earth/models/{cycle → hestia}/aboveGroundCropResidueTotal.py +1 -1
- hestia_earth/models/{site → hestia}/brackishWater.py +1 -1
- hestia_earth/models/{site → hestia}/cationExchangeCapacityPerKgSoil.py +1 -1
- hestia_earth/models/{cycle → hestia}/coldCarcassWeightPerHead.py +1 -1
- hestia_earth/models/{cycle → hestia}/coldDressedCarcassWeightPerHead.py +1 -1
- hestia_earth/models/{cycle → hestia}/concentrateFeed.py +1 -1
- hestia_earth/models/{cycle → hestia}/cropResidueManagement.py +1 -1
- hestia_earth/models/{cycle → hestia}/croppingIntensity.py +1 -1
- hestia_earth/models/{cycle → hestia}/energyContentLowerHeatingValue.py +1 -1
- hestia_earth/models/{cycle → hestia}/excretaKgMass.py +8 -3
- hestia_earth/models/{cycle → hestia}/excretaKgN.py +1 -1
- hestia_earth/models/{cycle → hestia}/excretaKgVs.py +1 -1
- hestia_earth/models/{cycle → hestia}/feedConversionRatio/__init__.py +1 -1
- hestia_earth/models/{site → hestia}/flowingWater.py +1 -1
- hestia_earth/models/{site → hestia}/freshWater.py +1 -1
- hestia_earth/models/{cycle → hestia}/inorganicFertiliser.py +1 -1
- hestia_earth/models/{cycle → hestia}/irrigatedTypeUnspecified.py +14 -19
- hestia_earth/models/hestia/landCover.py +30 -22
- hestia_earth/models/{cycle → hestia}/liveAnimal.py +1 -1
- hestia_earth/models/{cycle → hestia}/longFallowRatio.py +1 -1
- hestia_earth/models/{site → hestia}/management.py +4 -6
- hestia_earth/models/{cycle → hestia}/materialAndSubstrate.py +1 -1
- hestia_earth/models/{cycle → hestia}/milkYield.py +1 -1
- hestia_earth/models/{site → hestia}/netPrimaryProduction.py +1 -1
- hestia_earth/models/{site → hestia}/organicCarbonPerHa.py +1 -1
- hestia_earth/models/hestia/pToSurfaceWaterAquacultureSystems.py +148 -0
- hestia_earth/models/{cycle → hestia}/pastureGrass.py +1 -1
- hestia_earth/models/{cycle → hestia}/pastureSystem.py +1 -1
- hestia_earth/models/{site → hestia}/potentialEvapotranspirationAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/potentialEvapotranspirationMonthly.py +3 -3
- hestia_earth/models/{site → hestia}/precipitationAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/precipitationMonthly.py +3 -3
- hestia_earth/models/{site → hestia}/rainfallAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/rainfallMonthly.py +3 -3
- hestia_earth/models/{cycle → hestia}/readyToCookWeightPerHead.py +1 -1
- hestia_earth/models/{cycle → hestia}/residueBurnt.py +1 -1
- hestia_earth/models/{cycle → hestia}/residueIncorporated.py +1 -1
- hestia_earth/models/{cycle → hestia}/residueLeftOnField.py +1 -1
- hestia_earth/models/hestia/residueRemoved.py +65 -13
- hestia_earth/models/{site → hestia}/salineWater.py +1 -1
- hestia_earth/models/{site → hestia}/soilMeasurement.py +1 -1
- hestia_earth/models/{cycle → hestia}/stockingDensityAnimalHousingAverage.py +1 -1
- hestia_earth/models/{site → hestia}/temperatureAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/temperatureMonthly.py +3 -3
- hestia_earth/models/{site → hestia}/totalNitrogenPerKgSoil.py +1 -1
- hestia_earth/models/{cycle → hestia}/unknownPreSeasonWaterRegime.py +1 -1
- hestia_earth/models/hestia/utils.py +93 -0
- hestia_earth/models/{site → hestia}/waterDepth.py +1 -1
- hestia_earth/models/hestia/waterSalinity.py +78 -0
- hestia_earth/models/ipcc2019/aboveGroundBiomass.py +1 -1
- hestia_earth/models/ipcc2019/belowGroundBiomass.py +1 -1
- hestia_earth/models/ipcc2019/biomass_utils.py +2 -4
- hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +166 -79
- hestia_earth/models/ipcc2019/ch4ToAirOrganicSoilCultivation.py +270 -0
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +0 -3
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +0 -3
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +88 -63
- hestia_earth/models/ipcc2019/co2ToAirLimeHydrolysis.py +7 -5
- hestia_earth/models/ipcc2019/co2ToAirOrganicSoilCultivation.py +215 -0
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +0 -3
- hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +16 -9
- hestia_earth/models/ipcc2019/n2OToAirOrganicSoilCultivationDirect.py +161 -0
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +35 -47
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +86 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py +127 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +7 -5
- hestia_earth/models/ipcc2019/organicSoilCultivation_utils.py +159 -0
- hestia_earth/models/mocking/search-results.json +1113 -1113
- hestia_earth/models/pooreNemecek2018/utils.py +8 -2
- hestia_earth/models/schmidt2007/ch4ToAirWasteTreatment.py +1 -4
- hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +1 -4
- hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +1 -4
- hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +1 -4
- hestia_earth/models/site/grouped_measurement.py +132 -0
- hestia_earth/models/utils/__init__.py +4 -3
- hestia_earth/models/utils/background_emissions.py +52 -0
- hestia_earth/models/utils/blank_node.py +47 -14
- hestia_earth/models/utils/constant.py +26 -20
- hestia_earth/models/utils/impact_assessment.py +26 -17
- hestia_earth/models/utils/lookup.py +48 -39
- hestia_earth/models/utils/measurement.py +3 -3
- hestia_earth/models/utils/product.py +39 -1
- hestia_earth/models/utils/property.py +14 -6
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/RECORD +187 -171
- tests/models/aware/test_scarcityWeightedWaterUse.py +1 -12
- tests/models/ecoalimV9/__init__.py +0 -0
- tests/models/ecoalimV9/test_cycle.py +21 -0
- tests/models/ecoalimV9/test_impact_assessment.py +24 -0
- tests/models/environmentalFootprintV3_1/test_scarcityWeightedWaterUse.py +4 -2
- tests/models/{cycle → hestia}/test_aboveGroundCropResidue.py +1 -1
- tests/models/{cycle → hestia}/test_aboveGroundCropResidueTotal.py +1 -1
- tests/models/{site → hestia}/test_brackishWater.py +1 -1
- tests/models/{site → hestia}/test_cationExchangeCapacityPerKgSoil.py +1 -1
- tests/models/{cycle → hestia}/test_coldCarcassWeightPerHead.py +1 -1
- tests/models/{cycle → hestia}/test_coldDressedCarcassWeightPerHead.py +1 -1
- tests/models/{cycle → hestia}/test_concentrateFeed.py +1 -1
- tests/models/{cycle → hestia}/test_cropResidueManagement.py +1 -1
- tests/models/{cycle → hestia}/test_croppingIntensity.py +1 -1
- tests/models/{cycle → hestia}/test_energyContentLowerHeatingValue.py +5 -3
- tests/models/{cycle → hestia}/test_excretaKgMass.py +1 -1
- tests/models/{cycle → hestia}/test_excretaKgN.py +1 -1
- tests/models/{cycle → hestia}/test_excretaKgVs.py +1 -1
- tests/models/{cycle → hestia}/test_feedConversionRatio.py +3 -4
- tests/models/{site → hestia}/test_flowingWater.py +1 -1
- tests/models/{site → hestia}/test_freshWater.py +1 -1
- tests/models/{cycle → hestia}/test_inorganicFertiliser.py +1 -1
- tests/models/{cycle → hestia}/test_irrigatedTypeUnspecified.py +2 -5
- tests/models/hestia/test_landCover.py +4 -34
- tests/models/{cycle → hestia}/test_liveAnimal.py +1 -1
- tests/models/{cycle → hestia}/test_longFallowRatio.py +1 -1
- tests/models/{site → hestia}/test_management.py +1 -1
- tests/models/{cycle → hestia}/test_materialsAndSubstrate.py +1 -1
- tests/models/{cycle → hestia}/test_milkYield.py +1 -1
- tests/models/{site → hestia}/test_netPrimaryProduction.py +1 -1
- tests/models/{site → hestia}/test_organicCarbonPerHa.py +1 -1
- tests/models/{site → hestia}/test_organicCarbonPerKgSoil.py +1 -1
- tests/models/{site → hestia}/test_organicCarbonPerM3Soil.py +1 -1
- tests/models/{site → hestia}/test_organicMatterPerKgSoil.py +1 -1
- tests/models/{site → hestia}/test_organicMatterPerM3Soil.py +1 -1
- tests/models/hestia/test_pToSurfaceWaterAquacultureSystems.py +56 -0
- tests/models/{cycle → hestia}/test_pastureGrass.py +1 -1
- tests/models/{cycle → hestia}/test_pastureSystem.py +1 -1
- tests/models/{site → hestia}/test_potentialEvapotranspirationAnnual.py +1 -1
- tests/models/{site → hestia}/test_potentialEvapotranspirationMonthly.py +1 -1
- tests/models/{site → hestia}/test_precipitationAnnual.py +1 -1
- tests/models/{site → hestia}/test_precipitationMonthly.py +1 -1
- tests/models/{site → hestia}/test_rainfallAnnual.py +1 -1
- tests/models/{site → hestia}/test_rainfallMonthly.py +1 -1
- tests/models/{cycle → hestia}/test_readyToCookWeightPerHead.py +1 -1
- tests/models/{cycle → hestia}/test_residueBurnt.py +1 -1
- tests/models/{cycle → hestia}/test_residueIncorporated.py +1 -1
- tests/models/{cycle → hestia}/test_residueLeftOnField.py +1 -1
- tests/models/hestia/test_residueRemoved.py +15 -3
- tests/models/{site → hestia}/test_salineWater.py +1 -1
- tests/models/{site → hestia}/test_soilMeasurement.py +13 -21
- tests/models/{cycle → hestia}/test_stockingDensityAnimalHousingAverage.py +1 -1
- tests/models/{site → hestia}/test_temperatureAnnual.py +1 -1
- tests/models/{site → hestia}/test_temperatureMonthly.py +1 -1
- tests/models/{site → hestia}/test_totalNitrogenPerKgSoil.py +1 -1
- tests/models/{cycle → hestia}/test_unknownPreSeasonWaterRegime.py +1 -1
- tests/models/{site → hestia}/test_waterDepth.py +1 -1
- tests/models/hestia/test_waterSalinity.py +26 -0
- tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +2 -5
- tests/models/ipcc2019/test_ch4ToAirFloodedRice.py +10 -42
- tests/models/ipcc2019/test_ch4ToAirOrganicSoilCultivation.py +61 -0
- tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +11 -9
- tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +10 -8
- tests/models/ipcc2019/test_co2ToAirLimeHydrolysis.py +1 -1
- tests/models/ipcc2019/test_co2ToAirOrganicSoilCultivation.py +62 -0
- tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +11 -8
- tests/models/ipcc2019/test_n2OToAirOrganicSoilCultivationDirect.py +61 -0
- tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +3 -2
- tests/models/site/test_grouped_measurement.py +20 -0
- tests/models/test_ecoinventV3AndEmberClimate.py +2 -2
- tests/models/test_emissionNotRelevant.py +0 -8
- tests/models/utils/test_measurement.py +1 -1
- hestia_earth/models/cycle/residueRemoved.py +0 -54
- hestia_earth/models/hestia/nh3ToSurfaceWaterAquacultureSystems.py +0 -64
- hestia_earth/models/site/utils.py +0 -93
- tests/models/cycle/test_residueRemoved.py +0 -37
- tests/models/hestia/test_nh3ToSurfaceWaterAquacultureSystems.py +0 -51
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioCarbon.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioDryMatter.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioEnergy.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioFedWeight.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioNitrogen.py +0 -0
- /hestia_earth/models/{site → hestia}/organicCarbonPerKgSoil.py +0 -0
- /hestia_earth/models/{site → hestia}/organicCarbonPerM3Soil.py +0 -0
- /hestia_earth/models/{site → hestia}/organicMatterPerKgSoil.py +0 -0
- /hestia_earth/models/{site → hestia}/organicMatterPerM3Soil.py +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,10 @@
|
|
1
|
+
from functools import reduce
|
1
2
|
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
2
3
|
from hestia_earth.utils.model import filter_list_term_type, find_term_match
|
3
|
-
from hestia_earth.utils.tools import list_sum, safe_parse_float
|
4
|
+
from hestia_earth.utils.tools import list_sum, safe_parse_float, non_empty_list
|
4
5
|
|
5
|
-
from hestia_earth.models.log import
|
6
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table, debugValues
|
7
|
+
from hestia_earth.models.utils import multiply_values
|
6
8
|
from hestia_earth.models.utils.term import get_lookup_value
|
7
9
|
from hestia_earth.models.utils.emission import _new_emission
|
8
10
|
from hestia_earth.models.utils.product import has_flooded_rice
|
@@ -12,48 +14,54 @@ from . import MODEL
|
|
12
14
|
|
13
15
|
REQUIREMENTS = {
|
14
16
|
"Cycle": {
|
15
|
-
"practices": [
|
17
|
+
"practices": [
|
18
|
+
{"@type": "Practice", "value": "", "term.@id": "croppingDuration"},
|
19
|
+
{"@type": "Practice", "value": "", "term.termType": ["landUseManagement", "waterRegime"]},
|
20
|
+
{"@type": "Practice", "value": "", "term.termType": "cropResidueManagement"}
|
21
|
+
],
|
22
|
+
"products": [{"@type": "Product", "value": "", "term.@id": "aboveGroundCropResidueIncorporated"}],
|
16
23
|
"site": {
|
17
24
|
"@type": "Site",
|
18
25
|
"country": {"@type": "Term", "termType": "region"}
|
19
26
|
},
|
20
27
|
"optional": {
|
21
28
|
"inputs": [
|
22
|
-
{
|
23
|
-
"@type": "Input",
|
24
|
-
"value": "",
|
25
|
-
"term.termType": "organicFertiliser"
|
26
|
-
},
|
29
|
+
{"@type": "Input", "value": "", "term.termType": "organicFertiliser"},
|
27
30
|
{
|
28
31
|
"@type": "Input",
|
29
32
|
"value": "",
|
30
33
|
"term.termType": "fertiliserBrandName",
|
31
34
|
"properties": [{"@type": "Property", "value": "", "key.termType": "organicFertiliser"}]
|
32
35
|
}
|
33
|
-
],
|
34
|
-
"products": [{"@type": "Product", "value": "", "term.@id": "aboveGroundCropResidueIncorporated"}],
|
35
|
-
"practices": [
|
36
|
-
{"@type": "Practice", "value": "", "term.termType": "cropResidueManagement"},
|
37
|
-
{"@type": "Practice", "value": "", "term.termType": "landUseManagement"},
|
38
|
-
{"@type": "Practice", "value": "", "term.termType": "waterRegime"}
|
39
36
|
]
|
40
37
|
}
|
41
38
|
}
|
42
39
|
}
|
43
40
|
LOOKUPS = {
|
44
41
|
"landUseManagement": [
|
45
|
-
"
|
46
|
-
"
|
47
|
-
"IPCC_2019_CH4_rice_SFp
|
42
|
+
"IPCC_2019_CH4_rice_SFp",
|
43
|
+
"IPCC_2019_CH4_rice_SFp-min",
|
44
|
+
"IPCC_2019_CH4_rice_SFp-max",
|
48
45
|
"IPCC_2019_CH4_rice_SFp-sd"
|
49
46
|
],
|
50
47
|
"waterRegime": [
|
51
|
-
"IPCC_2019_CH4_rice_SFw",
|
52
|
-
"IPCC_2019_CH4_rice_SFw-
|
53
|
-
"
|
54
|
-
"
|
48
|
+
"IPCC_2019_CH4_rice_SFw",
|
49
|
+
"IPCC_2019_CH4_rice_SFw-min",
|
50
|
+
"IPCC_2019_CH4_rice_SFw-max",
|
51
|
+
"IPCC_2019_CH4_rice_SFw-sd"
|
52
|
+
],
|
53
|
+
"organicFertiliser": [
|
54
|
+
"IPCC_2019_CH4_rice_CFOA_kg_fresh_weight",
|
55
|
+
"IPCC_2019_CH4_rice_CFOA_kg_fresh_weight_min",
|
56
|
+
"IPCC_2019_CH4_rice_CFOA_kg_fresh_weight_max",
|
57
|
+
"IPCC_2019_CH4_rice_CFOA_kg_fresh_weight_sd"
|
58
|
+
],
|
59
|
+
"cropResidueManagement": [
|
60
|
+
"IPCC_2019_CH4_rice_CFOA_kg_dry_weight",
|
61
|
+
"IPCC_2019_CH4_rice_CFOA_kg_dry_weight_min",
|
62
|
+
"IPCC_2019_CH4_rice_CFOA_kg_dry_weight_max",
|
63
|
+
"IPCC_2019_CH4_rice_CFOA_kg_dry_weight_sd"
|
55
64
|
],
|
56
|
-
"organicFertiliser": ["IPCC_2019_CH4_rice_CFOA_kg_fresh_weight", "IPCC_2019_CH4_rice_CFOA_kg_dry_weight"],
|
57
65
|
"region-ch4ef-IPCC2019": ["CH4_ef", "CH4_ef_min", "CH4_ef_max", "CH4_ef_sd"]
|
58
66
|
}
|
59
67
|
RETURNS = {
|
@@ -68,92 +76,140 @@ RETURNS = {
|
|
68
76
|
}
|
69
77
|
TERM_ID = 'ch4ToAirFloodedRice'
|
70
78
|
TIER = EmissionMethodTier.TIER_1.value
|
79
|
+
_STATS = ['value', 'min', 'max', 'sd']
|
71
80
|
|
72
81
|
|
73
82
|
def _emission(value: float, min: float, max: float, sd: float):
|
74
83
|
emission = _new_emission(TERM_ID, MODEL)
|
75
84
|
emission['value'] = [value]
|
76
|
-
|
77
|
-
|
78
|
-
|
85
|
+
if min is not None:
|
86
|
+
emission['min'] = [min]
|
87
|
+
if max is not None:
|
88
|
+
emission['max'] = [max]
|
89
|
+
if sd is not None:
|
90
|
+
emission['sd'] = [sd]
|
79
91
|
emission['methodTier'] = TIER
|
80
92
|
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
81
93
|
return emission
|
82
94
|
|
83
95
|
|
84
|
-
def _get_CH4_ef(country: str, suffix: str = ''):
|
96
|
+
def _get_CH4_ef(country: str, suffix: str = 'value'):
|
85
97
|
lookup_name = 'region-ch4ef-IPCC2019.csv'
|
98
|
+
lookup = 'CH4_ef'
|
99
|
+
lookup = '_'.join([lookup, suffix]) if suffix != 'value' else lookup
|
86
100
|
return safe_parse_float(
|
87
|
-
get_region_lookup_value(lookup_name, country,
|
101
|
+
get_region_lookup_value(lookup_name, country, lookup, model=MODEL, term=TERM_ID),
|
102
|
+
default=None
|
88
103
|
)
|
89
104
|
|
90
105
|
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
def _get_cropResidue_value(cycle: dict, suffix: str = ''):
|
106
|
+
def _get_cropResidue_value(cycle: dict, suffix: str = 'value'):
|
107
|
+
product_id = 'aboveGroundCropResidueIncorporated'
|
96
108
|
abgIncorporated = list_sum(
|
97
|
-
find_term_match(cycle.get('products', []),
|
109
|
+
find_term_match(cycle.get('products', []), product_id).get('value', []),
|
110
|
+
default=None
|
98
111
|
)
|
99
112
|
abgManagement = filter_list_term_type(cycle.get('practices', []), TermTermType.CROPRESIDUEMANAGEMENT)
|
100
113
|
term = abgManagement[0].get('term', {}) if len(abgManagement) > 0 else None
|
114
|
+
lookup = 'IPCC_2019_CH4_rice_CFOA_kg_dry_weight'
|
115
|
+
lookup = '_'.join([lookup, suffix]) if suffix != 'value' else lookup
|
101
116
|
factor = safe_parse_float(
|
102
|
-
get_lookup_value(term,
|
103
|
-
|
104
|
-
|
117
|
+
get_lookup_value(term, lookup, model=MODEL, term=TERM_ID),
|
118
|
+
default=None
|
119
|
+
) if term else None
|
105
120
|
|
121
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
122
|
+
**{'cropResidue_' + suffix: log_as_table({
|
123
|
+
'product-id': product_id,
|
124
|
+
'product-value': abgIncorporated,
|
125
|
+
'factor': factor
|
126
|
+
})})
|
106
127
|
|
107
|
-
|
128
|
+
return multiply_values([abgIncorporated, factor])
|
129
|
+
|
130
|
+
|
131
|
+
def _get_fertiliser_values(input: dict, suffix: str = 'value'):
|
108
132
|
term = input.get('term', {})
|
133
|
+
lookup = 'IPCC_2019_CH4_rice_CFOA_kg_fresh_weight'
|
134
|
+
lookup = '_'.join([lookup, suffix]) if suffix != 'value' else lookup
|
109
135
|
factor = safe_parse_float(
|
110
|
-
get_lookup_value(term,
|
136
|
+
get_lookup_value(term, lookup, model=MODEL, term=TERM_ID),
|
137
|
+
default=None
|
111
138
|
)
|
112
|
-
|
139
|
+
value = list_sum(input.get('value', []))
|
140
|
+
return {'input-id': term.get('@id'), 'input-value': value, 'factor': factor}
|
113
141
|
|
114
142
|
|
115
|
-
def
|
116
|
-
|
117
|
-
fertilisers = get_organicFertiliser_inputs(cycle)
|
118
|
-
fert_value = list_sum([_get_fertiliser_value(i, suffix) for i in fertilisers])
|
119
|
-
return (1 + (fert_value/1000) + (cropResidue/1000)) ** 0.59
|
143
|
+
def _get_fertiliser_value(cycle: dict, suffix: str = 'value'):
|
144
|
+
fertiliser_values = [_get_fertiliser_values(i, suffix) for i in get_organicFertiliser_inputs(cycle)]
|
120
145
|
|
146
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
147
|
+
**{'fertiliser_' + suffix: log_as_table(fertiliser_values)})
|
121
148
|
|
122
|
-
|
123
|
-
|
124
|
-
(
|
149
|
+
valid_fertiliser_values = [
|
150
|
+
value for value in fertiliser_values
|
151
|
+
if all([value.get('input-value') is not None, value.get('factor') is not None])
|
125
152
|
]
|
126
|
-
|
127
|
-
|
153
|
+
fert_value = list_sum([
|
154
|
+
value.get('input-value') * value.get('factor')
|
155
|
+
for value in valid_fertiliser_values
|
156
|
+
])
|
157
|
+
return fert_value
|
128
158
|
|
129
159
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
'SFw' + suffix: SFw,
|
138
|
-
'SFp' + suffix: SFp,
|
139
|
-
'SFo' + suffix: SFo
|
140
|
-
})
|
141
|
-
return CH4_ef * (SFw if SFw > 0 else 1) * (SFp if SFp > 0 else 1) * SFo
|
160
|
+
def _calculate_SFo(cycle: dict, suffix: str = 'value'):
|
161
|
+
cropResidue = _get_cropResidue_value(cycle, suffix)
|
162
|
+
fertiliser = _get_fertiliser_value(cycle, suffix)
|
163
|
+
return (1 + (fertiliser/1000) + (cropResidue/1000)) ** 0.59 if all([
|
164
|
+
fertiliser is not None,
|
165
|
+
cropResidue is not None
|
166
|
+
]) else None
|
142
167
|
|
143
168
|
|
144
|
-
def
|
145
|
-
|
169
|
+
def _get_practice_values(practice: dict, col: str, default=None):
|
170
|
+
term = practice.get('term', {})
|
171
|
+
factor = safe_parse_float(get_lookup_value(term, col, model=MODEL, term=TERM_ID), default)
|
172
|
+
return {
|
173
|
+
'practice-id': term.get('@id'),
|
174
|
+
'factor': factor,
|
175
|
+
'practice-value': list_sum(practice.get('value', []), default=default)
|
176
|
+
} if factor is not None else None
|
146
177
|
|
147
178
|
|
148
|
-
def
|
149
|
-
|
150
|
-
|
151
|
-
])
|
179
|
+
def _calculate_SF_total(cycle: dict, practices: list, lookup: str, suffix: str = 'value', default=None):
|
180
|
+
lookup_column = '-'.join([lookup, suffix]) if suffix != 'value' else lookup
|
181
|
+
values = non_empty_list([_get_practice_values(p, lookup_column) for p in practices])
|
152
182
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
183
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
184
|
+
**{lookup_column: log_as_table(values)})
|
185
|
+
|
186
|
+
used_values = [value for value in values if value.get('practice-value') is not None]
|
187
|
+
|
188
|
+
# sum only values that are numbers
|
189
|
+
return (
|
190
|
+
list_sum([
|
191
|
+
value.get('factor') * value.get('practice-value') for value in used_values
|
192
|
+
], default=None) / list_sum([
|
193
|
+
value.get('practice-value') for value in used_values
|
194
|
+
])
|
195
|
+
) if used_values else (
|
196
|
+
default if suffix == 'value' else None
|
197
|
+
)
|
198
|
+
|
199
|
+
|
200
|
+
def _value_from_factors(values: list, key: str = 'value'):
|
201
|
+
# get the value from all factors, and only run if all are provided
|
202
|
+
all_values = [value.get(key) for value in values]
|
203
|
+
return multiply_values(all_values) if all([v is not None for v in all_values]) else None
|
204
|
+
|
205
|
+
|
206
|
+
def _run(values: list):
|
207
|
+
value = _value_from_factors(values, 'value')
|
208
|
+
min = _value_from_factors(values, 'min')
|
209
|
+
max = _value_from_factors(values, 'max')
|
210
|
+
sd = _value_from_factors(values, 'sd')
|
211
|
+
|
212
|
+
sd = (max-min)/4 if all([max, min]) else None
|
157
213
|
|
158
214
|
return [_emission(value, min, max, sd)]
|
159
215
|
|
@@ -162,20 +218,51 @@ def _should_run(cycle: dict):
|
|
162
218
|
country = cycle.get('site', {}).get('country', {}).get('@id')
|
163
219
|
|
164
220
|
flooded_rice = has_flooded_rice(cycle.get('products', []))
|
221
|
+
practices = cycle.get('practices', [])
|
165
222
|
|
166
|
-
croppingDuration = find_term_match(
|
223
|
+
croppingDuration = find_term_match(practices, 'croppingDuration', None)
|
167
224
|
has_croppingDuration = croppingDuration is not None
|
225
|
+
croppingDuration = reduce(lambda p, key: p | {
|
226
|
+
key: list_sum(croppingDuration.get(key) or [], default=None)
|
227
|
+
}, _STATS, {}) if has_croppingDuration else {}
|
228
|
+
|
229
|
+
CH4_ef = reduce(lambda p, key: p | {key: _get_CH4_ef(country, key)}, _STATS, {})
|
230
|
+
SFo = reduce(lambda p, key: p | {key: _calculate_SFo(cycle, key)}, _STATS, {})
|
231
|
+
|
232
|
+
water_regime = filter_list_term_type(practices, TermTermType.WATERREGIME)
|
233
|
+
SFw = reduce(lambda p, key: p | {
|
234
|
+
key: _calculate_SF_total(cycle, water_regime, 'IPCC_2019_CH4_rice_SFw', key)
|
235
|
+
}, _STATS, {})
|
236
|
+
|
237
|
+
land_use_management = filter_list_term_type(practices, TermTermType.LANDUSEMANAGEMENT)
|
238
|
+
SFp = reduce(lambda p, key: p | {
|
239
|
+
key: _calculate_SF_total(cycle, land_use_management, 'IPCC_2019_CH4_rice_SFp', key, default=1)
|
240
|
+
}, _STATS, {})
|
168
241
|
|
169
242
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
170
243
|
has_flooded_rice=flooded_rice,
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
244
|
+
country=country,
|
245
|
+
values=log_as_table([
|
246
|
+
{'name': 'croppingDuration'} | croppingDuration,
|
247
|
+
{'name': 'CH4-ef'} | CH4_ef,
|
248
|
+
{'name': 'SFo'} | SFo,
|
249
|
+
{'name': 'SFw'} | SFw,
|
250
|
+
{'name': 'SFp'} | SFp,
|
251
|
+
]))
|
252
|
+
|
253
|
+
should_run = all([
|
254
|
+
flooded_rice,
|
255
|
+
has_croppingDuration,
|
256
|
+
country,
|
257
|
+
CH4_ef.get('value') is not None,
|
258
|
+
SFo.get('value') is not None,
|
259
|
+
SFw.get('value') is not None,
|
260
|
+
SFp.get('value') is not None,
|
261
|
+
])
|
175
262
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
176
|
-
return should_run, croppingDuration,
|
263
|
+
return should_run, [croppingDuration, CH4_ef, SFo, SFw, SFp]
|
177
264
|
|
178
265
|
|
179
266
|
def run(cycle: dict):
|
180
|
-
should_run,
|
181
|
-
return _run(
|
267
|
+
should_run, values = _should_run(cycle)
|
268
|
+
return _run(values) if should_run else []
|
@@ -0,0 +1,270 @@
|
|
1
|
+
import numpy as np
|
2
|
+
import numpy.typing as npt
|
3
|
+
from typing import Callable, Union
|
4
|
+
|
5
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition
|
6
|
+
|
7
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
8
|
+
from hestia_earth.models.utils.array_builders import (
|
9
|
+
discrete_uniform_1d, gen_seed, normal_1d, repeat_single, triangular_1d
|
10
|
+
)
|
11
|
+
from hestia_earth.models.utils.cycle import land_occupation_per_ha
|
12
|
+
from hestia_earth.models.utils.descriptive_stats import calc_descriptive_stats
|
13
|
+
from hestia_earth.models.utils.ecoClimateZone import EcoClimateZone, get_eco_climate_zone_value
|
14
|
+
from hestia_earth.models.utils.emission import _new_emission
|
15
|
+
from hestia_earth.models.utils.measurement import most_relevant_measurement_value
|
16
|
+
from hestia_earth.models.utils.site import valid_site_type
|
17
|
+
|
18
|
+
from .organicSoilCultivation_utils import (
|
19
|
+
assign_ditch_category, assign_organic_soil_category, calc_emission, DitchCategory, get_ditch_frac,
|
20
|
+
get_emission_factor, OrganicSoilCategory, remap_categories, valid_eco_climate_zone
|
21
|
+
)
|
22
|
+
from . import MODEL
|
23
|
+
|
24
|
+
REQUIREMENTS = {
|
25
|
+
"Cycle": {
|
26
|
+
"or": [
|
27
|
+
{
|
28
|
+
"cycleDuration": "",
|
29
|
+
"practices": [{"@type": "Practice", "value": "", "term.@id": "longFallowRatio"}]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
"@doc": "for plantations, additional properties are required",
|
33
|
+
"practices": [
|
34
|
+
{"@type": "Practice", "value": "", "term.@id": "nurseryDensity"},
|
35
|
+
{"@type": "Practice", "value": "", "term.@id": "nurseryDuration"},
|
36
|
+
{"@type": "Practice", "value": "", "term.@id": "plantationProductiveLifespan"},
|
37
|
+
{"@type": "Practice", "value": "", "term.@id": "plantationDensity"},
|
38
|
+
{"@type": "Practice", "value": "", "term.@id": "plantationLifespan"},
|
39
|
+
{"@type": "Practice", "value": "", "term.@id": "rotationDuration"}
|
40
|
+
]
|
41
|
+
}
|
42
|
+
],
|
43
|
+
"site": {
|
44
|
+
"@type": "Site",
|
45
|
+
"measurements": [
|
46
|
+
{"@type": "Measurement", "value": "", "term.@id": "histosol"},
|
47
|
+
{"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}
|
48
|
+
]
|
49
|
+
},
|
50
|
+
"optional": {
|
51
|
+
"cycleDuration": ""
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
LOOKUPS = {
|
56
|
+
"crop": [
|
57
|
+
"isPlantation",
|
58
|
+
"IPCC_2013_ORGANIC_SOIL_CULTIVATION_CATEGORY"
|
59
|
+
],
|
60
|
+
"forage": [
|
61
|
+
"isPlantation",
|
62
|
+
"IPCC_2013_ORGANIC_SOIL_CULTIVATION_CATEGORY"
|
63
|
+
],
|
64
|
+
"ecoClimateZone": [
|
65
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_ANNUAL_CROPS",
|
66
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_PERENNIAL_CROPS",
|
67
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_ACACIA",
|
68
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_OIL_PALM",
|
69
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_SAGO_PALM",
|
70
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_PADDY_RICE_CULTIVATION",
|
71
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_GRASSLAND",
|
72
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_DITCH",
|
73
|
+
"IPCC_2013_ORGANIC_SOILS_TONNES_CH4_HECTARE_OTHER",
|
74
|
+
"IPCC_2013_DRAINED_ORGANIC_SOILS_DITCH_FRAC_AGRICULTURAL_LAND",
|
75
|
+
"IPCC_2013_DRAINED_ORGANIC_SOILS_DITCH_FRAC_NETHERLANDS"
|
76
|
+
]
|
77
|
+
}
|
78
|
+
RETURNS = {
|
79
|
+
"Emission": [{
|
80
|
+
"value": "",
|
81
|
+
"sd": "",
|
82
|
+
"min": "",
|
83
|
+
"max": "",
|
84
|
+
"observations": "",
|
85
|
+
"statsDefinition": "simulated",
|
86
|
+
"methodTier": "tier 1"
|
87
|
+
}]
|
88
|
+
}
|
89
|
+
TERM_ID = 'ch4ToAirOrganicSoilCultivation'
|
90
|
+
TIER = EmissionMethodTier.TIER_1.value
|
91
|
+
|
92
|
+
_STATS_DEFINITION = EmissionStatsDefinition.SIMULATED.value
|
93
|
+
_ITERATIONS = 100000
|
94
|
+
|
95
|
+
_CATEGORY_REMAPPER = {
|
96
|
+
OrganicSoilCategory.ACACIA: OrganicSoilCategory.PERENNIAL_CROPS
|
97
|
+
}
|
98
|
+
|
99
|
+
|
100
|
+
def _emission(descriptive_stats: dict):
|
101
|
+
emission = _new_emission(TERM_ID, MODEL) | descriptive_stats
|
102
|
+
emission['methodTier'] = TIER
|
103
|
+
return emission
|
104
|
+
|
105
|
+
|
106
|
+
def sample_emission_factor(
|
107
|
+
eco_climate_zone: EcoClimateZone,
|
108
|
+
organic_soil_category: OrganicSoilCategory,
|
109
|
+
seed: Union[int, np.random.Generator, None] = None,
|
110
|
+
) -> npt.NDArray:
|
111
|
+
category = remap_categories(organic_soil_category, _CATEGORY_REMAPPER) # fewer categories than CO2 model
|
112
|
+
factor_data = get_emission_factor(TERM_ID, eco_climate_zone, category)
|
113
|
+
sample_func = _get_sample_func(factor_data)
|
114
|
+
return sample_func(iterations=_ITERATIONS, seed=seed, **factor_data)
|
115
|
+
|
116
|
+
|
117
|
+
def sample_ditch_frac(
|
118
|
+
eco_climate_zone: EcoClimateZone,
|
119
|
+
ditch_category: DitchCategory,
|
120
|
+
seed: Union[int, np.random.Generator, None] = None,
|
121
|
+
) -> npt.NDArray:
|
122
|
+
factor_data = get_ditch_frac(eco_climate_zone, ditch_category, term=TERM_ID)
|
123
|
+
sample_func = _get_sample_func(factor_data)
|
124
|
+
return sample_func(iterations=_ITERATIONS, seed=seed, **factor_data)
|
125
|
+
|
126
|
+
|
127
|
+
def _sample_normal(
|
128
|
+
*, iterations: int, value: float, sd: float, seed: Union[int, np.random.Generator, None] = None, **_
|
129
|
+
) -> npt.NDArray:
|
130
|
+
return normal_1d(shape=(1, iterations), mu=value, sigma=sd, seed=seed)
|
131
|
+
|
132
|
+
|
133
|
+
def _sample_uniform(
|
134
|
+
*, iterations: int, min: float, max: float, seed: Union[int, np.random.Generator, None] = None, **_
|
135
|
+
) -> npt.NDArray:
|
136
|
+
return discrete_uniform_1d(shape=(1, iterations), low=min, high=max, seed=seed)
|
137
|
+
|
138
|
+
|
139
|
+
def _sample_triangular(
|
140
|
+
*, iterations: int, value: float, min: float, max: float, seed: Union[int, np.random.Generator, None] = None, **_
|
141
|
+
) -> npt.NDArray:
|
142
|
+
return triangular_1d(shape=(1, iterations), mode=value, low=min, high=max, seed=seed)
|
143
|
+
|
144
|
+
|
145
|
+
def _sample_constant(*, value: float, **_) -> npt.NDArray:
|
146
|
+
"""Sample a constant model parameter."""
|
147
|
+
return repeat_single(shape=(1, 1), value=value)
|
148
|
+
|
149
|
+
|
150
|
+
_KWARGS_TO_SAMPLE_FUNC = {
|
151
|
+
("value", "sd"): _sample_normal,
|
152
|
+
("value", "min", "max"): _sample_triangular,
|
153
|
+
("min", "max"): _sample_uniform,
|
154
|
+
("value",): _sample_constant
|
155
|
+
}
|
156
|
+
"""
|
157
|
+
Mapping from available distribution data to sample function.
|
158
|
+
"""
|
159
|
+
|
160
|
+
|
161
|
+
def _get_sample_func(kwargs: dict) -> Callable:
|
162
|
+
"""
|
163
|
+
Select the correct sample function for a parameter based on the distribution data available. All possible
|
164
|
+
parameters for the model should have, at a minimum, a `value`, meaning that no default function needs to be
|
165
|
+
specified.
|
166
|
+
|
167
|
+
This function has been extracted into it's own method to allow for mocking of sample function.
|
168
|
+
|
169
|
+
Keyword Args
|
170
|
+
------------
|
171
|
+
value : float
|
172
|
+
The distribution mean.
|
173
|
+
sd : float
|
174
|
+
The standard deviation of the distribution.
|
175
|
+
se : float
|
176
|
+
The standard error of the distribution.
|
177
|
+
n : float
|
178
|
+
Sample size.
|
179
|
+
|
180
|
+
Returns
|
181
|
+
-------
|
182
|
+
Callable
|
183
|
+
The sample function for the distribution.
|
184
|
+
"""
|
185
|
+
return next(
|
186
|
+
sample_func for required_kwargs, sample_func in _KWARGS_TO_SAMPLE_FUNC.items()
|
187
|
+
if all(kwarg in kwargs.keys() for kwarg in required_kwargs)
|
188
|
+
)
|
189
|
+
|
190
|
+
|
191
|
+
def _should_run(cycle: dict):
|
192
|
+
end_date = cycle.get('endDate')
|
193
|
+
site = cycle.get('site', {})
|
194
|
+
measurements = site.get('measurements', [])
|
195
|
+
|
196
|
+
seed = gen_seed(cycle, MODEL, TERM_ID)
|
197
|
+
rng = np.random.default_rng(seed)
|
198
|
+
|
199
|
+
def _get_measurement_content(term_id: str):
|
200
|
+
return most_relevant_measurement_value(measurements, term_id, end_date)
|
201
|
+
|
202
|
+
histosol = _get_measurement_content('histosol')
|
203
|
+
eco_climate_zone = get_eco_climate_zone_value(cycle, as_enum=True)
|
204
|
+
organic_soil_category = assign_organic_soil_category(cycle, log_id=TERM_ID)
|
205
|
+
ditch_category = assign_ditch_category(cycle)
|
206
|
+
|
207
|
+
emission_factor = (
|
208
|
+
sample_emission_factor(eco_climate_zone, organic_soil_category, seed=rng) if eco_climate_zone
|
209
|
+
else None
|
210
|
+
)
|
211
|
+
ditch_factor = (
|
212
|
+
sample_emission_factor(eco_climate_zone, OrganicSoilCategory.DITCH, seed=rng) if eco_climate_zone
|
213
|
+
else None
|
214
|
+
)
|
215
|
+
ditch_frac = (
|
216
|
+
sample_ditch_frac(eco_climate_zone, ditch_category, seed=rng) if eco_climate_zone
|
217
|
+
else None
|
218
|
+
)
|
219
|
+
|
220
|
+
land_occupation = land_occupation_per_ha(MODEL, TERM_ID, cycle)
|
221
|
+
|
222
|
+
logRequirements(
|
223
|
+
cycle, model=MODEL, term=TERM_ID,
|
224
|
+
eco_climate_zone=eco_climate_zone,
|
225
|
+
organic_soil_category=organic_soil_category,
|
226
|
+
ditch_category=ditch_category,
|
227
|
+
emission_factor=f"{np.mean(emission_factor):.3f}",
|
228
|
+
ditch_factor=f"{np.mean(ditch_factor):.3f}",
|
229
|
+
ditch_frac=f"{np.mean(ditch_frac):.3f}",
|
230
|
+
land_occupation=land_occupation,
|
231
|
+
histosol=histosol
|
232
|
+
)
|
233
|
+
|
234
|
+
should_run = all([
|
235
|
+
valid_site_type(site),
|
236
|
+
valid_eco_climate_zone(eco_climate_zone),
|
237
|
+
all(
|
238
|
+
var is not None for var in [
|
239
|
+
emission_factor,
|
240
|
+
ditch_factor,
|
241
|
+
ditch_frac,
|
242
|
+
land_occupation,
|
243
|
+
histosol
|
244
|
+
]
|
245
|
+
)
|
246
|
+
])
|
247
|
+
|
248
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
249
|
+
|
250
|
+
return should_run, emission_factor, ditch_factor, ditch_frac, histosol, land_occupation
|
251
|
+
|
252
|
+
|
253
|
+
def _run(
|
254
|
+
emission_factor: npt.NDArray,
|
255
|
+
ditch_factor: npt.NDArray,
|
256
|
+
ditch_frac: npt.NDArray,
|
257
|
+
histosol: float,
|
258
|
+
land_occupation: float
|
259
|
+
):
|
260
|
+
land_emission = calc_emission(TERM_ID, emission_factor, histosol, land_occupation)
|
261
|
+
ditch_emission = calc_emission(TERM_ID, ditch_factor, histosol, land_occupation)
|
262
|
+
|
263
|
+
result = (ditch_emission * ditch_frac) + (land_emission * (1 - ditch_frac))
|
264
|
+
descriptive_stats = calc_descriptive_stats(result, _STATS_DEFINITION)
|
265
|
+
return [_emission(descriptive_stats)]
|
266
|
+
|
267
|
+
|
268
|
+
def run(cycle: dict):
|
269
|
+
should_run, *args = _should_run(cycle)
|
270
|
+
return _run(*args) if should_run else []
|
@@ -186,13 +186,11 @@ def _should_compile_inventory_func(
|
|
186
186
|
) for cycle in cycles
|
187
187
|
)
|
188
188
|
|
189
|
-
has_stock_measurements = len(carbon_stock_measurements) > 0
|
190
189
|
has_cycles = len(cycles) > 0
|
191
190
|
has_functional_unit_1_ha = all(cycle.get('functionalUnit') == CycleFunctionalUnit._1_HA.value for cycle in cycles)
|
192
191
|
|
193
192
|
should_run = all([
|
194
193
|
has_soil,
|
195
|
-
has_stock_measurements,
|
196
194
|
has_cycles,
|
197
195
|
has_functional_unit_1_ha
|
198
196
|
])
|
@@ -201,7 +199,6 @@ def _should_compile_inventory_func(
|
|
201
199
|
"site_type": site_type,
|
202
200
|
"has_soil": has_soil,
|
203
201
|
"carbon_stock_term": _CARBON_STOCK_TERM_ID,
|
204
|
-
"has_stock_measurements": has_stock_measurements,
|
205
202
|
"has_cycles": has_cycles,
|
206
203
|
"has_functional_unit_1_ha": has_functional_unit_1_ha,
|
207
204
|
}
|
@@ -199,13 +199,11 @@ def _should_compile_inventory_func(
|
|
199
199
|
) for cycle in cycles
|
200
200
|
)
|
201
201
|
|
202
|
-
has_stock_measurements = len(carbon_stock_measurements) > 0
|
203
202
|
has_cycles = len(cycles) > 0
|
204
203
|
has_functional_unit_1_ha = all(cycle.get('functionalUnit') == CycleFunctionalUnit._1_HA.value for cycle in cycles)
|
205
204
|
|
206
205
|
should_run = all([
|
207
206
|
has_soil,
|
208
|
-
has_stock_measurements,
|
209
207
|
has_cycles,
|
210
208
|
has_functional_unit_1_ha
|
211
209
|
])
|
@@ -214,7 +212,6 @@ def _should_compile_inventory_func(
|
|
214
212
|
"site_type": site_type,
|
215
213
|
"has_soil": has_soil,
|
216
214
|
"carbon_stock_term": _CARBON_STOCK_TERM_ID,
|
217
|
-
"has_stock_measurements": has_stock_measurements,
|
218
215
|
"has_cycles": has_cycles,
|
219
216
|
"has_functional_unit_1_ha": has_functional_unit_1_ha,
|
220
217
|
}
|