hestia-earth-models 0.72.2__py3-none-any.whl → 0.73.1__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/{akagiEtAl2011AndIpcc2006 → akagiEtAl2011}/__init__.py +1 -1
- hestia_earth/models/akagiEtAl2011/ch4ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/nh3ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/noxToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/pm25ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/so2ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/utils.py +45 -0
- hestia_earth/models/aware/scarcityWeightedWaterUse.py +10 -9
- hestia_earth/models/cache_sites.py +8 -4
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandTransformation.py +14 -11
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsTotalLandUseEffects.py +1 -1
- hestia_earth/models/chaudharyBrooks2018/utils.py +5 -3
- hestia_earth/models/config/Cycle.json +48 -7
- hestia_earth/models/config/ImpactAssessment.json +22 -0
- hestia_earth/models/cycle/completeness/electricityFuel.py +1 -1
- hestia_earth/models/cycle/completeness/freshForage.py +1 -1
- hestia_earth/models/cycle/completeness/soilAmendment.py +1 -1
- hestia_earth/models/cycle/input/hestiaAggregatedData.py +1 -2
- hestia_earth/models/cycle/product/economicValueShare.py +4 -2
- hestia_earth/models/cycle/product/price.py +35 -10
- hestia_earth/models/cycle/product/revenue.py +5 -2
- hestia_earth/models/dammgen2009/noxToAirExcreta.py +14 -18
- hestia_earth/models/ecoinventV3/__init__.py +11 -6
- hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +1 -1
- hestia_earth/models/emepEea2019/utils.py +2 -1
- hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +1 -1
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +11 -11
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +14 -11
- hestia_earth/models/faostat2018/liveweightPerHead.py +1 -1
- hestia_earth/models/faostat2018/product/price.py +2 -2
- hestia_earth/models/faostat2018/seed.py +3 -2
- hestia_earth/models/faostat2018/utils.py +32 -18
- hestia_earth/models/geospatialDatabase/altitude.py +2 -1
- hestia_earth/models/geospatialDatabase/drainageClass.py +2 -1
- hestia_earth/models/geospatialDatabase/organicCarbonPerKgSoil.py +2 -1
- hestia_earth/models/geospatialDatabase/totalNitrogenPerKgSoil.py +2 -1
- hestia_earth/models/geospatialDatabase/totalPhosphorusPerKgSoil.py +2 -1
- hestia_earth/models/geospatialDatabase/utils.py +7 -5
- hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +1 -1
- hestia_earth/models/hestia/brackishWater.py +1 -1
- hestia_earth/models/hestia/default_emissions.py +105 -0
- hestia_earth/models/hestia/default_resourceUse.py +110 -0
- hestia_earth/models/hestia/excretaKgMass.py +7 -9
- hestia_earth/models/hestia/freshWater.py +1 -1
- hestia_earth/models/hestia/inorganicFertiliser.py +12 -12
- hestia_earth/models/hestia/landCover.py +7 -5
- hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +3 -0
- hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +3 -0
- hestia_earth/models/hestia/liveAnimal.py +1 -1
- hestia_earth/models/hestia/management.py +1 -1
- hestia_earth/models/hestia/netPrimaryProduction.py +1 -1
- hestia_earth/models/hestia/organicCarbonPerHa.py +2 -2
- hestia_earth/models/hestia/salineWater.py +1 -1
- hestia_earth/models/hestia/seed_emissions.py +35 -21
- hestia_earth/models/hestia/stockingDensityAnimalHousingAverage.py +1 -1
- hestia_earth/models/hestia/totalNitrogenPerKgSoil.py +1 -1
- hestia_earth/models/hestia/waterSalinity.py +3 -2
- hestia_earth/models/ipcc2006/aboveGroundCropResidueRemoved.py +2 -2
- hestia_earth/models/ipcc2006/aboveGroundCropResidueTotal.py +10 -6
- hestia_earth/models/ipcc2006/belowGroundCropResidue.py +12 -8
- hestia_earth/models/ipcc2019/animal/utils.py +1 -1
- hestia_earth/models/ipcc2019/belowGroundCropResidue.py +1 -1
- hestia_earth/models/ipcc2019/carbonContent.py +1 -1
- hestia_earth/models/ipcc2019/ch4ToAirAquacultureSystems.py +18 -10
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +6 -6
- hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +4 -2
- hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +1 -1
- hestia_earth/models/ipcc2019/croppingDuration.py +4 -2
- hestia_earth/models/ipcc2019/ligninContent.py +1 -1
- hestia_earth/models/{akagiEtAl2011AndIpcc2006 → ipcc2019}/n2OToAirCropResidueBurningDirect.py +8 -4
- hestia_earth/models/ipcc2019/nitrogenContent.py +1 -1
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +6 -2
- hestia_earth/models/ipcc2019/pastureGrass_utils.py +13 -12
- hestia_earth/models/ipcc2019/utils.py +6 -2
- hestia_earth/models/koble2014/residueBurnt.py +6 -3
- hestia_earth/models/koble2014/residueRemoved.py +1 -1
- hestia_earth/models/mocking/search-results.json +1614 -1610
- hestia_earth/models/pooreNemecek2018/aboveGroundCropResidueTotal.py +1 -1
- hestia_earth/models/pooreNemecek2018/belowGroundCropResidue.py +1 -1
- hestia_earth/models/pooreNemecek2018/excretaKgVs.py +1 -1
- hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py +44 -6
- hestia_earth/models/pooreNemecek2018/longFallowDuration.py +1 -1
- hestia_earth/models/pooreNemecek2018/nurseryDensity.py +1 -1
- hestia_earth/models/pooreNemecek2018/nurseryDuration.py +1 -1
- hestia_earth/models/pooreNemecek2018/plantationDensity.py +1 -1
- hestia_earth/models/pooreNemecek2018/plantationLifespan.py +1 -1
- hestia_earth/models/pooreNemecek2018/plantationProductiveLifespan.py +3 -1
- hestia_earth/models/pooreNemecek2018/saplingsDepreciatedAmountPerCycle.py +1 -1
- hestia_earth/models/resourceUseNotRelevant/__init__.py +65 -0
- hestia_earth/models/schererPfister2015/nErosionSoilFlux.py +5 -3
- hestia_earth/models/schererPfister2015/pErosionSoilFlux.py +5 -3
- hestia_earth/models/schererPfister2015/utils.py +5 -4
- hestia_earth/models/site/grouped_measurement.py +1 -1
- hestia_earth/models/stehfestBouwman2006/n2OToAirSoilFlux_utils.py +1 -1
- hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirSoilFlux_utils.py +3 -3
- hestia_earth/models/utils/background_emissions.py +15 -11
- hestia_earth/models/utils/blank_node.py +6 -4
- hestia_earth/models/utils/crop.py +1 -1
- hestia_earth/models/utils/cropResidue.py +16 -0
- hestia_earth/models/utils/cycle.py +1 -1
- hestia_earth/models/utils/ecoClimateZone.py +2 -2
- hestia_earth/models/utils/excretaManagement.py +1 -1
- hestia_earth/models/utils/feedipedia.py +3 -3
- hestia_earth/models/utils/fertiliser.py +7 -1
- hestia_earth/models/utils/impact_assessment.py +29 -14
- hestia_earth/models/utils/inorganicFertiliser.py +2 -2
- hestia_earth/models/utils/input.py +34 -1
- hestia_earth/models/utils/liveAnimal.py +2 -2
- hestia_earth/models/utils/lookup.py +6 -2
- hestia_earth/models/utils/measurement.py +4 -4
- hestia_earth/models/utils/productivity.py +1 -1
- hestia_earth/models/utils/property.py +4 -2
- hestia_earth/models/utils/site.py +2 -1
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.1.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.1.dist-info}/RECORD +138 -127
- tests/models/akagiEtAl2011/test_ch4ToAirCropResidueBurning.py +33 -0
- tests/models/akagiEtAl2011/test_nh3ToAirCropResidueBurning.py +33 -0
- tests/models/{akagiEtAl2011AndIpcc2006 → akagiEtAl2011}/test_noxToAirCropResidueBurning.py +5 -17
- tests/models/akagiEtAl2011/test_pm25ToAirCropResidueBurning.py +33 -0
- tests/models/akagiEtAl2011/test_so2ToAirCropResidueBurning.py +33 -0
- tests/models/akagiEtAl2011/test_utils.py +18 -0
- tests/models/cycle/product/test_price.py +1 -11
- tests/models/dammgen2009/test_noxToAirExcreta.py +30 -10
- tests/models/geospatialDatabase/test_utils.py +2 -1
- tests/models/hestia/test_default_emissions.py +25 -0
- tests/models/hestia/test_default_resourceUse.py +26 -0
- tests/models/hestia/test_landCover.py +2 -2
- tests/models/ipcc2019/test_ch4ToAirAquacultureSystems.py +2 -2
- tests/models/{akagiEtAl2011AndIpcc2006/test_nh3ToAirCropResidueBurning.py → ipcc2019/test_n2OToAirCropResidueBurningDirect.py} +2 -2
- tests/models/pooreNemecek2018/test_freshwaterWithdrawalsDuringCycle.py +12 -0
- tests/models/test_resourceUseNotRelevant.py +27 -0
- tests/models/{akagiEtAl2011AndIpcc2006/test_utils.py → utils/test_cropResidue.py} +6 -6
- tests/models/utils/test_impact_assessment.py +29 -13
- hestia_earth/models/akagiEtAl2011AndIpcc2006/ch4ToAirCropResidueBurning.py +0 -57
- hestia_earth/models/akagiEtAl2011AndIpcc2006/nh3ToAirCropResidueBurning.py +0 -57
- hestia_earth/models/akagiEtAl2011AndIpcc2006/noxToAirCropResidueBurning.py +0 -57
- hestia_earth/models/akagiEtAl2011AndIpcc2006/utils.py +0 -15
- tests/models/akagiEtAl2011AndIpcc2006/test_ch4ToAirCropResidueBurning.py +0 -45
- tests/models/akagiEtAl2011AndIpcc2006/test_n2OToAirCropResidueBurningDirect.py +0 -46
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.1.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.1.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.1.dist-info}/top_level.txt +0 -0
- /tests/models/{akagiEtAl2011AndIpcc2006 → akagiEtAl2011}/__init__.py +0 -0
@@ -0,0 +1,110 @@
|
|
1
|
+
from hestia_earth.schema import IndicatorMethodTier, TermTermType
|
2
|
+
from hestia_earth.utils.tools import flatten, safe_parse_float
|
3
|
+
from hestia_earth.utils.lookup import download_lookup, lookup_term_ids
|
4
|
+
|
5
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
6
|
+
from hestia_earth.models.utils import _omit
|
7
|
+
from hestia_earth.models.utils.indicator import _new_indicator
|
8
|
+
from hestia_earth.models.utils.background_emissions import no_gap_filled_background_emissions
|
9
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
10
|
+
from hestia_earth.models.utils.input import unique_background_inputs
|
11
|
+
from . import MODEL
|
12
|
+
|
13
|
+
REQUIREMENTS = {
|
14
|
+
"ImpactAssessment": {
|
15
|
+
"cycle": {
|
16
|
+
"@type": "Cycle",
|
17
|
+
"inputs": [{
|
18
|
+
"@type": "Input",
|
19
|
+
"value": "> 0",
|
20
|
+
"none": {
|
21
|
+
"impactAssessment": {"@type": "ImpactAssessment"},
|
22
|
+
"fromCycle": "True",
|
23
|
+
"producedInCycle": "True"
|
24
|
+
}
|
25
|
+
}]
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
RETURNS = {
|
30
|
+
"Indicator": [{
|
31
|
+
"value": "",
|
32
|
+
"inputs": "",
|
33
|
+
"methodTier": "background"
|
34
|
+
}]
|
35
|
+
}
|
36
|
+
LOOKUPS = {
|
37
|
+
"organicFertiliser": "backgroundEmissionsResourceUseDefaultValue"
|
38
|
+
}
|
39
|
+
MODEL_KEY = 'default_resourceUse'
|
40
|
+
TIER = IndicatorMethodTier.BACKGROUND.value
|
41
|
+
|
42
|
+
|
43
|
+
def _indicator(term_id: str, value: float, input: dict):
|
44
|
+
indicator = _new_indicator(term_id, MODEL)
|
45
|
+
indicator['value'] = value
|
46
|
+
indicator['inputs'] = [input]
|
47
|
+
indicator['methodTier'] = TIER
|
48
|
+
return indicator
|
49
|
+
|
50
|
+
|
51
|
+
def _default_value(input: dict):
|
52
|
+
return safe_parse_float(get_lookup_value(input.get('term', {}), LOOKUPS['organicFertiliser']), default=None)
|
53
|
+
|
54
|
+
|
55
|
+
def _run_input(impact: dict):
|
56
|
+
required_resourceUse_term_ids = [
|
57
|
+
id for id in lookup_term_ids(download_lookup(f"{TermTermType.RESOURCEUSE.value}.csv"))
|
58
|
+
if id.endswith('InputsProduction')
|
59
|
+
]
|
60
|
+
|
61
|
+
def run(input: dict):
|
62
|
+
input_term = input.get('input').get('term')
|
63
|
+
term_id = input_term.get('@id')
|
64
|
+
value = input.get('default-value-from-lookup')
|
65
|
+
|
66
|
+
for emission_id in required_resourceUse_term_ids:
|
67
|
+
logShouldRun(impact, MODEL, term_id, True, methodTier=TIER, model_key=MODEL_KEY, emission_id=emission_id)
|
68
|
+
|
69
|
+
return [
|
70
|
+
_indicator(term_id, value, input_term) for term_id in required_resourceUse_term_ids
|
71
|
+
]
|
72
|
+
|
73
|
+
return run
|
74
|
+
|
75
|
+
|
76
|
+
def _should_run(impact: dict):
|
77
|
+
no_gap_filled_background_emissions_func = no_gap_filled_background_emissions(
|
78
|
+
node=impact, list_key='emissionsResourceUse', term_type=TermTermType.RESOURCEUSE
|
79
|
+
)
|
80
|
+
|
81
|
+
inputs = [
|
82
|
+
input | {
|
83
|
+
'default-value-from-lookup': _default_value(input['input']),
|
84
|
+
'no-gap-filled-background-emissions': no_gap_filled_background_emissions_func(input['input'])
|
85
|
+
}
|
86
|
+
for input in unique_background_inputs(impact.get('cycle', {}))
|
87
|
+
]
|
88
|
+
valid_inputs = [
|
89
|
+
input for input in inputs
|
90
|
+
if all([
|
91
|
+
input.get('default-value-from-lookup') is not None,
|
92
|
+
input.get('no-gap-filled-background-emissions')
|
93
|
+
])
|
94
|
+
]
|
95
|
+
|
96
|
+
should_run = all([bool(valid_inputs)])
|
97
|
+
|
98
|
+
for input in inputs:
|
99
|
+
term_id = input.get('input').get('term', {}).get('@id')
|
100
|
+
|
101
|
+
logRequirements(impact, model=MODEL, term=term_id, model_key=MODEL_KEY,
|
102
|
+
**_omit(input, ['input', 'input-value']))
|
103
|
+
logShouldRun(impact, MODEL, term_id, should_run, methodTier=TIER, model_key=MODEL_KEY)
|
104
|
+
|
105
|
+
return should_run, valid_inputs
|
106
|
+
|
107
|
+
|
108
|
+
def run(impact: dict):
|
109
|
+
should_run, grouped_inputs = _should_run(impact)
|
110
|
+
return flatten(map(_run_input(impact), grouped_inputs)) if should_run else []
|
@@ -3,7 +3,7 @@ from hestia_earth.utils.model import filter_list_term_type, find_term_match
|
|
3
3
|
from hestia_earth.utils.tools import non_empty_list, list_sum
|
4
4
|
|
5
5
|
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
6
|
-
from hestia_earth.models.utils import get_kg_term_id, get_kg_N_term_id, get_kg_VS_term_id
|
6
|
+
from hestia_earth.models.utils import get_kg_term_id, get_kg_N_term_id, get_kg_VS_term_id, _filter_list_term_unit
|
7
7
|
from hestia_earth.models.utils.term import download_term
|
8
8
|
from hestia_earth.models.utils.constant import Units
|
9
9
|
from hestia_earth.models.utils.product import _new_product, convert_product_to_unit
|
@@ -31,12 +31,12 @@ RETURNS = {
|
|
31
31
|
MODEL_KEY = 'excretaKgMass'
|
32
32
|
|
33
33
|
UNITS = [
|
34
|
-
Units.KG_N
|
35
|
-
Units.KG_VS
|
34
|
+
Units.KG_N,
|
35
|
+
Units.KG_VS
|
36
36
|
]
|
37
37
|
|
38
38
|
|
39
|
-
def _product(
|
39
|
+
def _product(term_id: str, value: float = None):
|
40
40
|
product = _new_product(term_id, value, MODEL)
|
41
41
|
return product
|
42
42
|
|
@@ -80,17 +80,15 @@ def _run_product(cycle: dict, product_term_id: str):
|
|
80
80
|
# use existing product if exist, else create new one
|
81
81
|
existing_product = find_term_match(cycle.get('products', []), product_term_id)
|
82
82
|
|
83
|
-
return (existing_product | _product(
|
83
|
+
return (existing_product | _product(product_term_id, value)) if value else _product(product_term_id)
|
84
84
|
|
85
85
|
|
86
86
|
def _should_run(cycle: dict):
|
87
87
|
node_type = cycle.get('type', cycle.get('@type'))
|
88
88
|
excreta_products = filter_list_term_type(cycle.get('products', []), TermTermType.EXCRETA)
|
89
89
|
kg_term_ids = list(set([
|
90
|
-
get_kg_term_id(p.get('term', {}).get('@id'))
|
91
|
-
|
92
|
-
p.get('value', [])
|
93
|
-
])
|
90
|
+
get_kg_term_id(p.get('term', {}).get('@id'))
|
91
|
+
for p in _filter_list_term_unit(excreta_products, UNITS)
|
94
92
|
]))
|
95
93
|
gap_fill_term_ids = [
|
96
94
|
term_id for term_id in kg_term_ids if not find_term_match(excreta_products, term_id).get('value', [])
|
@@ -34,7 +34,7 @@ def _should_run(site: dict):
|
|
34
34
|
logRequirements(site, model=MODEL, term=TERM_ID,
|
35
35
|
waterSalinity=waterSalinity)
|
36
36
|
|
37
|
-
should_run = all([0 < waterSalinity < 500])
|
37
|
+
should_run = all([0 < (waterSalinity or 0) < 500])
|
38
38
|
logShouldRun(site, MODEL, TERM_ID, should_run)
|
39
39
|
return should_run
|
40
40
|
|
@@ -88,15 +88,15 @@ def _include_term_ids(term_id: str):
|
|
88
88
|
def _run_input(cycle: dict, input: dict):
|
89
89
|
term_id = input.get('term', {}).get('@id')
|
90
90
|
input_term_ids = _include_term_ids(term_id)
|
91
|
-
nitrogenContent = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent'), 0)
|
92
|
-
nitrogenContent_min = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent-min'), None)
|
93
|
-
nitrogenContent_max = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent-max'), None)
|
94
|
-
phosphateContentAsP2O5 = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5'), 0)
|
95
|
-
phosphateContentAsP2O5_min = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5-min'), None)
|
96
|
-
phosphateContentAsP2O5_max = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5-max'), None)
|
97
|
-
potassiumContentAsK2O = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O'), 0)
|
98
|
-
potassiumContentAsK2O_min = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O-min'), None)
|
99
|
-
potassiumContentAsK2O_max = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O-max'), None)
|
91
|
+
nitrogenContent = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent'), default=0)
|
92
|
+
nitrogenContent_min = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent-min'), default=None)
|
93
|
+
nitrogenContent_max = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent-max'), default=None)
|
94
|
+
phosphateContentAsP2O5 = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5'), default=0)
|
95
|
+
phosphateContentAsP2O5_min = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5-min'), default=None)
|
96
|
+
phosphateContentAsP2O5_max = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5-max'), default=None)
|
97
|
+
potassiumContentAsK2O = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O'), default=0)
|
98
|
+
potassiumContentAsK2O_min = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O-min'), default=None)
|
99
|
+
potassiumContentAsK2O_max = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O-max'), default=None)
|
100
100
|
|
101
101
|
from_units = input.get('term', {}).get('units')
|
102
102
|
input_value = list_sum(input.get('value'))
|
@@ -166,9 +166,9 @@ def _run_input(cycle: dict, input: dict):
|
|
166
166
|
def _should_run_input(cycle: dict, input: dict):
|
167
167
|
term_id = input.get('term', {}).get('@id')
|
168
168
|
has_value = list_sum(input.get('value', [])) > 0
|
169
|
-
nitrogenContent = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent'), None)
|
170
|
-
phosphateContentAsP2O5 = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5'), None)
|
171
|
-
potassiumContentAsK2O = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O'), None)
|
169
|
+
nitrogenContent = safe_parse_float(get_term_lookup(term_id, 'nitrogenContent'), default=None)
|
170
|
+
phosphateContentAsP2O5 = safe_parse_float(get_term_lookup(term_id, 'phosphateContentAsP2O5'), default=None)
|
171
|
+
potassiumContentAsK2O = safe_parse_float(get_term_lookup(term_id, 'potassiumContentAsK2O'), default=None)
|
172
172
|
|
173
173
|
# skip inputs that already have all the inlcuded term with a value
|
174
174
|
inputs = cycle.get('inputs', [])
|
@@ -163,7 +163,7 @@ def _should_group_landCover(management_node: dict):
|
|
163
163
|
)
|
164
164
|
|
165
165
|
|
166
|
-
def
|
166
|
+
def _get_changes(country_id: str, end_year: int) -> tuple[dict, bool]:
|
167
167
|
"""
|
168
168
|
For each entry in ALL_LAND_USE_TERMS, creates a key: value in output dictionary, also TOTAL
|
169
169
|
"""
|
@@ -178,7 +178,7 @@ def get_changes(country_id: str, end_year: int) -> tuple[dict, bool]:
|
|
178
178
|
)
|
179
179
|
for land_use_term in ALL_LAND_USE_TERMS + [LAND_AREA]
|
180
180
|
}
|
181
|
-
missing_changes =
|
181
|
+
missing_changes = [k for k, v in changes_dict.items() if v is None]
|
182
182
|
changes_dict = {k: v if v is not None else 0 for k, v in changes_dict.items()}
|
183
183
|
changes_dict[TOTAL_AGRICULTURAL_CHANGE] = (
|
184
184
|
float(changes_dict.get(TOTAL_CROPLAND, 0)) + float(changes_dict.get(PERMANENT_PASTURE, 0))
|
@@ -609,7 +609,7 @@ def _should_run_historical_land_use_change_single_crop(
|
|
609
609
|
) -> tuple[bool, dict]:
|
610
610
|
"""Calculate land use change percentages for a single management node/crop."""
|
611
611
|
# (C-H).
|
612
|
-
changes, missing_changes =
|
612
|
+
changes, missing_changes = _get_changes(country_id=country_id, end_year=end_year)
|
613
613
|
|
614
614
|
# (L). Estimate maximum forest loss
|
615
615
|
forest_loss = _estimate_maximum_forest_change(
|
@@ -749,12 +749,13 @@ def _should_run_historical_land_use_change_single_crop(
|
|
749
749
|
land_use_type=land_use_type,
|
750
750
|
country_id=country_id,
|
751
751
|
changes=log_as_table(changes),
|
752
|
+
missing_changes=log_as_table(missing_changes),
|
752
753
|
site_area=log_as_table(capped_site_area),
|
753
754
|
sum_of_site_areas_is_100=sum_of_site_areas_is_100,
|
754
755
|
site_type_allowed=site_type_allowed
|
755
756
|
)
|
756
757
|
|
757
|
-
should_run = all([
|
758
|
+
should_run = all([len(missing_changes) == 0, country_id, site_type_allowed, sum_of_site_areas_is_100])
|
758
759
|
logShouldRun(site, MODEL, term.get("@id"), should_run, model_key=MODEL_KEY)
|
759
760
|
|
760
761
|
return should_run, capped_site_area
|
@@ -831,7 +832,8 @@ def _should_run(site: dict) -> tuple[bool, list, dict]:
|
|
831
832
|
land_use_type=land_use_type,
|
832
833
|
allowed_land_use_types=';'.join(ALLOWED_LAND_USE_TYPES),
|
833
834
|
has_no_prior_land_cover_data=has_no_prior_land_cover_data,
|
834
|
-
management_nodes=log_as_table([_omit(n, ['term']) for n in relevant_nodes])
|
835
|
+
management_nodes=log_as_table([_omit(n, ['term']) for n in relevant_nodes]),
|
836
|
+
should_run_nodes=should_run_nodes)
|
835
837
|
|
836
838
|
should_run = all([land_use_type, has_no_prior_land_cover_data, should_run_nodes])
|
837
839
|
logShouldRun(site, MODEL, None, should_run, model_key=MODEL_KEY)
|
@@ -66,7 +66,7 @@ def _should_run(cycle: dict):
|
|
66
66
|
) or next(
|
67
67
|
(p for p in product.get('properties', []) if p.get('term', {}).get('@id').endswith('PerHead')), {}
|
68
68
|
)
|
69
|
-
propertyPerHead_value = safe_parse_float(propertyPerHead.get('value'), None)
|
69
|
+
propertyPerHead_value = safe_parse_float(propertyPerHead.get('value'), default=None)
|
70
70
|
|
71
71
|
# make sure the `liveAnimal` Term is not already present as a Product or Input
|
72
72
|
term_id = get_liveAnimal_term_id(product, model_key=MODEL_KEY)
|
@@ -95,7 +95,7 @@ _INPUT_RULES = {
|
|
95
95
|
TermTermType.INORGANICFERTILISER.value: (
|
96
96
|
(
|
97
97
|
TermTermType.INORGANICFERTILISER.value, # Lookup column
|
98
|
-
lambda x: safe_parse_float(x) > 0, # Condition
|
98
|
+
lambda x: safe_parse_float(x, default=0) > 0, # Condition
|
99
99
|
_INORGANIC_NITROGEN_FERTILISER_USED_TERM_ID # New term.
|
100
100
|
),
|
101
101
|
),
|
@@ -45,7 +45,7 @@ def _should_run(site: dict):
|
|
45
45
|
logRequirements(site, model=MODEL, term=TERM_ID,
|
46
46
|
temperature=temperature)
|
47
47
|
|
48
|
-
should_run = temperature > 0
|
48
|
+
should_run = all([(temperature or 0) > 0])
|
49
49
|
logShouldRun(site, MODEL, TERM_ID, should_run)
|
50
50
|
return should_run, temperature
|
51
51
|
|
@@ -189,8 +189,8 @@ def _run_calculation(site: dict, depth_key: str, measurement_nodes: list[dict])
|
|
189
189
|
A list of `organicCarbonPerHa` [Measurement nodes](https://www.hestia.earth/schema/Measurement).
|
190
190
|
"""
|
191
191
|
split = depth_key.split('_') # "a_to_b"
|
192
|
-
depth_upper = safe_parse_float(split[0])
|
193
|
-
depth_lower = safe_parse_float(split[2])
|
192
|
+
depth_upper = safe_parse_float(split[0], default=0)
|
193
|
+
depth_lower = safe_parse_float(split[2], default=0)
|
194
194
|
|
195
195
|
soil_bulk_density_nodes = [
|
196
196
|
node for node in measurement_nodes if node.get('term', {}).get('@id') == SOIL_BULK_DENSITY_TERM_ID
|
@@ -34,7 +34,7 @@ def _should_run(site: dict):
|
|
34
34
|
logRequirements(site, model=MODEL, term=TERM_ID,
|
35
35
|
waterSalinity=waterSalinity)
|
36
36
|
|
37
|
-
should_run = all([waterSalinity > 18000])
|
37
|
+
should_run = all([(waterSalinity or 0) > 18000])
|
38
38
|
logShouldRun(site, MODEL, TERM_ID, should_run)
|
39
39
|
return should_run
|
40
40
|
|
@@ -14,7 +14,7 @@ from hestia_earth.models.utils.site import valid_site_type
|
|
14
14
|
from hestia_earth.models.utils.cycle import cycle_end_year
|
15
15
|
from hestia_earth.models.utils.crop import get_crop_grouping_faostat_production, get_landCover_term_id
|
16
16
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
17
|
-
from hestia_earth.models.utils.
|
17
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
18
18
|
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
19
19
|
from . import MODEL
|
20
20
|
|
@@ -83,6 +83,7 @@ def _run_emission(
|
|
83
83
|
input_term_id = input_term.get('@id')
|
84
84
|
seed_value = list_sum(seed_input.get('value'))
|
85
85
|
value = emission_value * economicValueShare / 100 / total_yield * seed_value
|
86
|
+
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, model_key=MODEL_KEY, emission_id=term_id)
|
86
87
|
debugValues(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
|
87
88
|
value=value,
|
88
89
|
coefficient=1,
|
@@ -107,7 +108,7 @@ def _map_group_emissions(group_id: str, required_emission_term_ids: list, emissi
|
|
107
108
|
included_emissions = list(filter(lambda v: v in emission_ids, emissions))
|
108
109
|
missing_emissions = list(filter(lambda v: v not in emission_ids, emissions))
|
109
110
|
return {
|
110
|
-
'id': group_id,
|
111
|
+
'group-id': group_id,
|
111
112
|
'total-emissions': len(emissions),
|
112
113
|
'included-emissions': len(included_emissions),
|
113
114
|
'missing-emissions': '-'.join(missing_emissions),
|
@@ -120,7 +121,7 @@ def _filter_emissions(cycle: dict):
|
|
120
121
|
|
121
122
|
emissions = [
|
122
123
|
{
|
123
|
-
'id': i.get('term', {}).get('@id'),
|
124
|
+
'emission-id': i.get('term', {}).get('@id'),
|
124
125
|
'group-id': get_lookup_value(i.get('term', {}), LOOKUPS['emission'], model=MODEL, model_key=MODEL_KEY),
|
125
126
|
'value': list_sum(i.get('value'))
|
126
127
|
}
|
@@ -130,7 +131,7 @@ def _filter_emissions(cycle: dict):
|
|
130
131
|
len(i.get('value', [])) > 0
|
131
132
|
])
|
132
133
|
]
|
133
|
-
emission_ids = set([v.get('id') for v in emissions])
|
134
|
+
emission_ids = set([v.get('emission-id') for v in emissions])
|
134
135
|
group_ids = set([v.get('group-id') for v in emissions if v.get('group-id')])
|
135
136
|
|
136
137
|
# for each group, get the list of all required emissions
|
@@ -140,7 +141,7 @@ def _filter_emissions(cycle: dict):
|
|
140
141
|
]
|
141
142
|
# only keep groups that have all emissions present in the Cycle
|
142
143
|
valid_groups = list(filter(lambda group: group.get('is-valid'), emissions_per_group))
|
143
|
-
valid_group_ids = set([v.get('id') for v in valid_groups])
|
144
|
+
valid_group_ids = set([v.get('group-id') for v in valid_groups])
|
144
145
|
|
145
146
|
# finally, only return emissions which groups are valid
|
146
147
|
return list(filter(
|
@@ -151,19 +152,21 @@ def _filter_emissions(cycle: dict):
|
|
151
152
|
|
152
153
|
def _evs(product: dict):
|
153
154
|
return safe_parse_float(
|
154
|
-
get_lookup_value(product.get('term', {}), 'global_economic_value_share', model=MODEL, model_key=MODEL_KEY)
|
155
|
+
get_lookup_value(product.get('term', {}), 'global_economic_value_share', model=MODEL, model_key=MODEL_KEY),
|
156
|
+
default=None
|
155
157
|
) or product.get('economicValueShare')
|
156
158
|
|
157
159
|
|
158
160
|
def _faostat_yield(country_id: str, end_year: int, product: dict):
|
159
161
|
grouping = get_crop_grouping_faostat_production(MODEL, product.get('term', {}))
|
160
|
-
|
162
|
+
value = extract_grouped_data_closest_date(get_region_lookup_value(
|
161
163
|
'region-crop-cropGroupingFaostatProduction-yield.csv',
|
162
164
|
country_id,
|
163
165
|
grouping,
|
164
166
|
model=MODEL,
|
165
167
|
model_key=MODEL_KEY
|
166
|
-
), end_year)
|
168
|
+
), end_year)
|
169
|
+
return safe_parse_float(value, default=None)
|
167
170
|
|
168
171
|
|
169
172
|
def _group_seed_inputs(inputs: list):
|
@@ -242,10 +245,11 @@ def _should_run(cycle: dict):
|
|
242
245
|
emissions,
|
243
246
|
{}
|
244
247
|
)
|
248
|
+
has_single_land_cover = len(crop_land_cover_ids) <= 1
|
245
249
|
|
246
250
|
should_run = all([
|
247
251
|
site_type_valid,
|
248
|
-
|
252
|
+
has_single_land_cover,
|
249
253
|
is_product_complete,
|
250
254
|
total_economicValueShare,
|
251
255
|
total_yield,
|
@@ -253,29 +257,39 @@ def _should_run(cycle: dict):
|
|
253
257
|
bool(emissions)
|
254
258
|
])
|
255
259
|
|
260
|
+
logs = {
|
261
|
+
'site_type_valid': site_type_valid,
|
262
|
+
'crop_products': log_as_table(crop_products),
|
263
|
+
'crop_land_cover_ids': ';'.join(crop_land_cover_ids),
|
264
|
+
'has_single_land_cover': has_single_land_cover,
|
265
|
+
'is_term_type_product_complete': is_product_complete,
|
266
|
+
'total_economicValueShare': total_economicValueShare,
|
267
|
+
'total_yield': total_yield,
|
268
|
+
'end_year': end_year,
|
269
|
+
'country_id': country_id
|
270
|
+
}
|
271
|
+
|
256
272
|
for seed_input in seed_inputs:
|
257
273
|
term_id = seed_input.get('input').get('term', {}).get('@id')
|
258
274
|
|
259
275
|
logRequirements(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
|
260
|
-
site_type_valid=site_type_valid,
|
261
|
-
crop_products=log_as_table(crop_products),
|
262
|
-
crop_land_cover_ids=';'.join(crop_land_cover_ids),
|
263
|
-
is_term_type_product_complete=is_product_complete,
|
264
|
-
total_economicValueShare=total_economicValueShare,
|
265
|
-
total_yield=total_yield,
|
266
|
-
end_year=end_year,
|
267
|
-
country_id=country_id,
|
268
276
|
emissions=log_as_table(emissions),
|
269
277
|
emissions_per_group=log_as_table(emissions_per_group),
|
270
|
-
**_omit(seed_input, 'input')
|
278
|
+
**_omit(seed_input, 'input'),
|
279
|
+
**logs)
|
271
280
|
|
272
281
|
logShouldRun(cycle, MODEL, term_id, should_run, methodTier=TIER, model_key=MODEL_KEY)
|
273
282
|
|
274
|
-
# log
|
283
|
+
# log failed emissions to show in the logs
|
275
284
|
for group in emissions_per_group:
|
276
|
-
|
285
|
+
emission_id = group.get('group-id')
|
286
|
+
if not group.get('is-valid') or not should_run:
|
287
|
+
logRequirements(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY, emission_id=emission_id,
|
288
|
+
**group,
|
289
|
+
**_omit(seed_input, 'input'),
|
290
|
+
**logs)
|
277
291
|
logShouldRun(cycle, MODEL, term_id, False,
|
278
|
-
methodTier=TIER, model_key=MODEL_KEY, emission_id=
|
292
|
+
methodTier=TIER, model_key=MODEL_KEY, emission_id=emission_id)
|
279
293
|
|
280
294
|
return should_run, total_economicValueShare, total_yield, grouped_seed_inputs, grouped_emissions
|
281
295
|
|
@@ -3,7 +3,7 @@ from hestia_earth.utils.model import filter_list_term_type
|
|
3
3
|
|
4
4
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
5
5
|
from hestia_earth.models.utils import weighted_average
|
6
|
-
from hestia_earth.models.utils.
|
6
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
7
7
|
from hestia_earth.models.utils.practice import _new_practice
|
8
8
|
from . import MODEL
|
9
9
|
|
@@ -45,7 +45,7 @@ def _should_run(site: dict):
|
|
45
45
|
logRequirements(site, model=MODEL, term=TERM_ID,
|
46
46
|
carbon_content_value=carbon_content_value)
|
47
47
|
|
48
|
-
should_run = not is_from_model(carbon_content)
|
48
|
+
should_run = all([not is_from_model(carbon_content), (carbon_content_value or 0) > 0])
|
49
49
|
logShouldRun(site, MODEL, TERM_ID, should_run)
|
50
50
|
return should_run, carbon_content_value
|
51
51
|
|
@@ -5,7 +5,7 @@ from hestia_earth.utils.tools import safe_parse_float
|
|
5
5
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
6
6
|
from hestia_earth.models.utils.measurement import _new_measurement
|
7
7
|
from hestia_earth.models.utils.site import related_cycles
|
8
|
-
from hestia_earth.models.utils.
|
8
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
9
9
|
from . import MODEL
|
10
10
|
|
11
11
|
REQUIREMENTS = {
|
@@ -52,7 +52,8 @@ def _should_run(site: dict):
|
|
52
52
|
{
|
53
53
|
'product-id': product.get('term', {}).get('@id'),
|
54
54
|
'lookup-value': safe_parse_float(
|
55
|
-
get_lookup_value(product.get('term', {}), LOOKUPS['liveAquaticSpecies']),
|
55
|
+
get_lookup_value(product.get('term', {}), LOOKUPS['liveAquaticSpecies']),
|
56
|
+
default=None
|
56
57
|
),
|
57
58
|
'start-date': product.get('startDate') or cycle.get('startDate'),
|
58
59
|
'end-date': product.get('endDate') or cycle.get('endDate')
|
@@ -38,11 +38,11 @@ def _product(value: float):
|
|
38
38
|
|
39
39
|
def _get_value(product: dict, product_dm_property: dict):
|
40
40
|
value = product.get('value', [0])[0]
|
41
|
-
dm_percent = safe_parse_float(product_dm_property.get('value'))
|
41
|
+
dm_percent = safe_parse_float(product_dm_property.get('value'), default=None)
|
42
42
|
debugValues(product, model=MODEL, term=product.get('term', {}).get('@id'),
|
43
43
|
value=value,
|
44
44
|
dm_percent=dm_percent)
|
45
|
-
return value * dm_percent / 100
|
45
|
+
return value * dm_percent / 100 if dm_percent is not None else 0
|
46
46
|
|
47
47
|
|
48
48
|
def _run(products: list):
|
@@ -41,21 +41,25 @@ def _product(value: float):
|
|
41
41
|
def _get_value_dm(product: dict, dm_percent: float):
|
42
42
|
term_id = product.get('term', {}).get('@id', '')
|
43
43
|
product_yield = list_sum(product.get('value', [0]))
|
44
|
-
yield_dm = product_yield * (dm_percent / 100)
|
44
|
+
yield_dm = product_yield * (dm_percent / 100) if dm_percent is not None else None
|
45
45
|
|
46
46
|
# estimate the AG DM calculation
|
47
|
-
slope = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][1]), None)
|
48
|
-
intercept = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]), None)
|
47
|
+
slope = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][1]), default=None)
|
48
|
+
intercept = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]), default=None)
|
49
49
|
debugValues(product, model=MODEL, term=TERM_ID,
|
50
50
|
yield_dm=yield_dm,
|
51
51
|
dryMatter_percent=dm_percent,
|
52
52
|
slope=slope,
|
53
53
|
intercept=intercept)
|
54
|
-
return None if
|
54
|
+
return None if any([
|
55
|
+
slope is None,
|
56
|
+
intercept is None,
|
57
|
+
yield_dm is None
|
58
|
+
]) else (yield_dm * slope + intercept * 1000)
|
55
59
|
|
56
60
|
|
57
61
|
def _run(product: dict, dm_property: dict):
|
58
|
-
value = _get_value_dm(product, safe_parse_float(dm_property.get('value')))
|
62
|
+
value = _get_value_dm(product, safe_parse_float(dm_property.get('value'), default=None))
|
59
63
|
return [_product(value)] if value is not None else []
|
60
64
|
|
61
65
|
|
@@ -63,7 +67,7 @@ def _should_run_product(product: dict):
|
|
63
67
|
term_id = product.get('term', {}).get('@id')
|
64
68
|
value = list_sum(product.get('value', [0]))
|
65
69
|
return value > 0 and (
|
66
|
-
safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]), None) is not None
|
70
|
+
safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]), default=None) is not None
|
67
71
|
)
|
68
72
|
|
69
73
|
|
@@ -41,17 +41,17 @@ def _product(value: float):
|
|
41
41
|
def _get_value_dm(product: dict, dm_percent: float):
|
42
42
|
term_id = product.get('term', {}).get('@id', '')
|
43
43
|
product_yield = list_sum(product.get('value', [0]))
|
44
|
-
yield_dm = product_yield * (dm_percent / 100)
|
44
|
+
yield_dm = product_yield * (dm_percent / 100) if dm_percent is not None else None
|
45
45
|
|
46
46
|
# TODO with the spreadsheet there are a number of ways this value is calculated.
|
47
47
|
# Currently, the result of this model when applied to Sah et al does not match
|
48
48
|
# the example due to hardcoded calc in the spreadsheet
|
49
49
|
|
50
50
|
# estimate the BG DM calculation
|
51
|
-
intercept = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]))
|
52
|
-
slope = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][1]))
|
51
|
+
intercept = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]), default=None)
|
52
|
+
slope = safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][1]), default=None)
|
53
53
|
ab_bg_ratio = safe_parse_float(
|
54
|
-
get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][2])
|
54
|
+
get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][2]), default=None
|
55
55
|
)
|
56
56
|
debugValues(product, model=MODEL, term=TERM_ID,
|
57
57
|
yield_dm=yield_dm,
|
@@ -64,12 +64,16 @@ def _get_value_dm(product: dict, dm_percent: float):
|
|
64
64
|
# https://www.ipcc-nggip.iges.or.jp/public/2019rf/pdf/4_Volume4/19R_V4_Ch11_Soils_N2O_CO2.pdf
|
65
65
|
# only if site.type = pasture
|
66
66
|
# multiply by the ratio of above to below matter
|
67
|
-
return None if
|
68
|
-
|
67
|
+
return None if any([
|
68
|
+
yield_dm is None,
|
69
|
+
slope is None,
|
70
|
+
intercept is None,
|
71
|
+
ab_bg_ratio is None
|
72
|
+
]) else ((yield_dm * slope + intercept * 1000) + yield_dm) * ab_bg_ratio
|
69
73
|
|
70
74
|
|
71
75
|
def _run(product: dict, dm_property: dict):
|
72
|
-
value = _get_value_dm(product, safe_parse_float(dm_property.get('value')))
|
76
|
+
value = _get_value_dm(product, safe_parse_float(dm_property.get('value'), default=None))
|
73
77
|
return [_product(value)] if value is not None else []
|
74
78
|
|
75
79
|
|
@@ -77,7 +81,7 @@ def _should_run_product(product: dict):
|
|
77
81
|
term_id = product.get('term', {}).get('@id')
|
78
82
|
value = list_sum(product.get('value', [0]))
|
79
83
|
return value > 0 and (
|
80
|
-
safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]), None) is not None
|
84
|
+
safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop'][0]), default=None) is not None
|
81
85
|
)
|
82
86
|
|
83
87
|
|
@@ -30,7 +30,7 @@ def productivity_lookup_value(term_id: str, lookup: str, country: dict, animal:
|
|
30
30
|
return safe_parse_float(
|
31
31
|
extract_grouped_data(value, productivity_key.value) or
|
32
32
|
extract_grouped_data(value, PRODUCTIVITY.HIGH.value), # defaults to high if low is not found
|
33
|
-
None
|
33
|
+
default=None
|
34
34
|
)
|
35
35
|
|
36
36
|
|
@@ -42,7 +42,7 @@ def _product(value: float):
|
|
42
42
|
|
43
43
|
|
44
44
|
def _get_lookup_value(term: dict, column: str):
|
45
|
-
return safe_parse_float(get_lookup_value(term, column, model=MODEL, term=TERM_ID), None)
|
45
|
+
return safe_parse_float(get_lookup_value(term, column, model=MODEL, term=TERM_ID), default=None)
|
46
46
|
|
47
47
|
|
48
48
|
def _product_value(product: dict):
|
@@ -67,7 +67,7 @@ def _crop_residue_lookup_col(term):
|
|
67
67
|
|
68
68
|
|
69
69
|
def _get_lookup_value(term: dict, column: str):
|
70
|
-
return safe_parse_float(get_lookup_value(term, column, model=MODEL, term=TERM_ID), None)
|
70
|
+
return safe_parse_float(get_lookup_value(term, column, model=MODEL, term=TERM_ID), default=None)
|
71
71
|
|
72
72
|
|
73
73
|
# Single crop
|