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
@@ -31,7 +31,7 @@ def _product(value: float):
|
|
31
31
|
|
32
32
|
def _get_lookup_value(product: dict):
|
33
33
|
term_id = product.get('term', {}).get('@id', '')
|
34
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
34
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
35
35
|
|
36
36
|
|
37
37
|
def _run(product: dict):
|
@@ -31,7 +31,7 @@ def _product(value: float):
|
|
31
31
|
|
32
32
|
def _get_lookup_value(product: dict):
|
33
33
|
term_id = product.get('term', {}).get('@id', '')
|
34
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
34
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
35
35
|
|
36
36
|
|
37
37
|
def _run(product: dict):
|
@@ -131,7 +131,7 @@ def _run(excreta_vs_products: list, excreta_n_products: list, mass_balance_items
|
|
131
131
|
def _get_carbonContent(cycle: dict):
|
132
132
|
primary_prod = find_primary_product(cycle) or {}
|
133
133
|
return safe_parse_float(
|
134
|
-
get_lookup_value(primary_prod.get('term', {}), 'carbonContent', model=MODEL, model_key=MODEL_KEY)
|
134
|
+
get_lookup_value(primary_prod.get('term', {}), 'carbonContent', model=MODEL, model_key=MODEL_KEY), default=0
|
135
135
|
) / 100
|
136
136
|
|
137
137
|
|
@@ -2,7 +2,7 @@ from hestia_earth.schema import TermTermType
|
|
2
2
|
from hestia_earth.utils.tools import list_sum, safe_parse_float
|
3
3
|
from hestia_earth.utils.model import filter_list_term_type
|
4
4
|
|
5
|
-
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
5
|
+
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun, log_as_table
|
6
6
|
from hestia_earth.models.utils.term import get_lookup_value
|
7
7
|
from hestia_earth.models.utils.indicator import _new_indicator
|
8
8
|
from hestia_earth.models.utils.impact_assessment import get_product, convert_value_from_cycle, get_site
|
@@ -25,6 +25,13 @@ REQUIREMENTS = {
|
|
25
25
|
"completeness.water": "True",
|
26
26
|
"inputs": [{"@type": "Input", "term.termType": "water", "value": "> 0"}]
|
27
27
|
}
|
28
|
+
},
|
29
|
+
"optional": {
|
30
|
+
"practices": [{
|
31
|
+
"@type": "Practice",
|
32
|
+
"value": "> 0",
|
33
|
+
"term.termType": "waterRegime"
|
34
|
+
}]
|
28
35
|
}
|
29
36
|
}
|
30
37
|
}
|
@@ -39,7 +46,8 @@ LOOKUPS = {
|
|
39
46
|
"Conveyancing_Efficiency_Annual_crops",
|
40
47
|
"Conveyancing_Efficiency_Permanent_crops",
|
41
48
|
"Conveyancing_Efficiency_Perennial_crops"
|
42
|
-
]
|
49
|
+
],
|
50
|
+
"waterRegime": "conveyancingEfficiency"
|
43
51
|
}
|
44
52
|
TERM_ID = 'freshwaterWithdrawalsDuringCycle'
|
45
53
|
|
@@ -50,19 +58,49 @@ def _indicator(term_id: str, value: float):
|
|
50
58
|
return indicator
|
51
59
|
|
52
60
|
|
53
|
-
def
|
61
|
+
def _get_conveyancing_efficiency_from_waterRegime(impact_assessment: dict):
|
62
|
+
practices = filter_list_term_type(impact_assessment.get('cycle', {}).get('practices', []), TermTermType.WATERREGIME)
|
63
|
+
practices_with_factors = [
|
64
|
+
{
|
65
|
+
'practice-id': p.get('term', {}).get('@id'),
|
66
|
+
'practice-value': list_sum(p.get('value'), default=None),
|
67
|
+
'conveyancing': safe_parse_float(
|
68
|
+
get_lookup_value(p.get('term', {}), 'conveyancingEfficiency'), default=None)
|
69
|
+
}
|
70
|
+
for p in practices
|
71
|
+
]
|
72
|
+
total_practice_value = list_sum([p.get('practice-value', 0) for p in practices_with_factors])
|
73
|
+
conveyancing_from_practices = list_sum([
|
74
|
+
(p.get('practice-value') or 0) * (p.get('conveyancing', 0) or 0) for p in practices_with_factors
|
75
|
+
]) / total_practice_value if total_practice_value > 0 else None
|
76
|
+
valid_waterRegime_practices = all([
|
77
|
+
p.get('conveyancing') is not None or p.get('practice-value', 0) == 0
|
78
|
+
for p in practices_with_factors
|
79
|
+
])
|
80
|
+
|
81
|
+
debugValues(impact_assessment, model=MODEL, term=TERM_ID,
|
82
|
+
waterRegime_conveyancing_efficiency_values=log_as_table(practices_with_factors),
|
83
|
+
waterRegime_conveyancing_efficiency=conveyancing_from_practices)
|
84
|
+
|
85
|
+
return conveyancing_from_practices if valid_waterRegime_practices else None
|
86
|
+
|
87
|
+
|
88
|
+
def _get_conveyancing_efficiency_from_country(impact_assessment: dict, product: dict):
|
54
89
|
site = get_site(impact_assessment)
|
55
90
|
country = impact_assessment.get('country', {}) or site.get('country', {})
|
56
91
|
grouping = get_crop_grouping_fao(MODEL, TERM_ID, product.get('term', {}))
|
57
92
|
value = get_lookup_value(country, f"Conveyancing_Efficiency_{grouping}", model=MODEL, term=TERM_ID)
|
58
93
|
debugValues(impact_assessment, model=MODEL, term=TERM_ID,
|
59
94
|
grouping=grouping,
|
60
|
-
|
61
|
-
return safe_parse_float(value, 1)
|
95
|
+
country_conveyancing_efficiency=value)
|
96
|
+
return safe_parse_float(value, default=1)
|
62
97
|
|
63
98
|
|
64
99
|
def _run(impact_assessment: dict, product: dict, irrigation: float):
|
65
|
-
conveyancing =
|
100
|
+
conveyancing = (
|
101
|
+
_get_conveyancing_efficiency_from_waterRegime(impact_assessment) or
|
102
|
+
_get_conveyancing_efficiency_from_country(impact_assessment, product)
|
103
|
+
)
|
66
104
|
# convert from m3 to litre
|
67
105
|
value = convert_value_from_cycle(
|
68
106
|
impact_assessment,
|
@@ -29,7 +29,7 @@ def _practice(value: float):
|
|
29
29
|
|
30
30
|
def _get_value(product: dict):
|
31
31
|
term_id = product.get('term', {}).get('@id', '')
|
32
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
32
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
33
33
|
|
34
34
|
|
35
35
|
def _run(product: dict):
|
@@ -23,7 +23,7 @@ TERM_ID = 'nurseryDensity'
|
|
23
23
|
|
24
24
|
def _get_value(product: dict):
|
25
25
|
term_id = product.get('term', {}).get('@id', '')
|
26
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
26
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
27
27
|
|
28
28
|
|
29
29
|
def _practice(value: float):
|
@@ -29,7 +29,7 @@ def _practice(value: float):
|
|
29
29
|
|
30
30
|
def _get_value(product: dict):
|
31
31
|
term_id = product.get('term', {}).get('@id', '')
|
32
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
32
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
33
33
|
|
34
34
|
|
35
35
|
def run(cycle: dict):
|
@@ -29,7 +29,7 @@ def _practice(value: float):
|
|
29
29
|
|
30
30
|
def _get_value(product: dict):
|
31
31
|
term_id = product.get('term', {}).get('@id', '')
|
32
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
32
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
33
33
|
|
34
34
|
|
35
35
|
def run(cycle: dict):
|
@@ -23,7 +23,7 @@ TERM_ID = 'plantationLifespan'
|
|
23
23
|
|
24
24
|
def _get_value(product: dict):
|
25
25
|
term_id = product.get('term', {}).get('@id', '')
|
26
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
26
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
27
27
|
|
28
28
|
|
29
29
|
def _practice(value: float):
|
@@ -33,7 +33,9 @@ def _get_value(cycle: dict):
|
|
33
33
|
def get(product: dict):
|
34
34
|
term_id = product.get('term', {}).get('@id', '')
|
35
35
|
plantationLifespan = get_plantationLifespan(product)
|
36
|
-
nonProductiveLifespan = safe_parse_float(
|
36
|
+
nonProductiveLifespan = safe_parse_float(
|
37
|
+
get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None
|
38
|
+
)
|
37
39
|
product_id = product.get('term').get('@id')
|
38
40
|
product_id_logs = log_as_table({
|
39
41
|
'plantationLifespan': plantationLifespan,
|
@@ -35,7 +35,7 @@ def _input(value: float):
|
|
35
35
|
|
36
36
|
def _get_value(product: dict):
|
37
37
|
term_id = product.get('term', {}).get('@id', '')
|
38
|
-
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), None)
|
38
|
+
return safe_parse_float(get_crop_lookup_value(MODEL, TERM_ID, term_id, LOOKUPS['crop']), default=None)
|
39
39
|
|
40
40
|
|
41
41
|
def _run(product: dict, plantationLifespan: float, cycleDuration: float):
|
@@ -0,0 +1,65 @@
|
|
1
|
+
from hestia_earth.schema import IndicatorMethodTier, TermTermType
|
2
|
+
from hestia_earth.utils.lookup import download_lookup, lookup_term_ids
|
3
|
+
from hestia_earth.utils.lookup_utils import is_in_system_boundary
|
4
|
+
|
5
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
6
|
+
from hestia_earth.models.utils.indicator import _new_indicator
|
7
|
+
from hestia_earth.models.utils.blank_node import _run_required
|
8
|
+
from hestia_earth.models.utils.impact_assessment import get_site
|
9
|
+
from hestia_earth.models.utils.site import get_land_cover_term_id
|
10
|
+
|
11
|
+
REQUIREMENTS = {
|
12
|
+
"ImpactAssessment": {
|
13
|
+
"emissionsResourceUse": [{"@type": "Indicator"}]
|
14
|
+
}
|
15
|
+
}
|
16
|
+
RETURNS = {
|
17
|
+
"Indicator": [{
|
18
|
+
"value": "0",
|
19
|
+
"methodTier": "not relevant"
|
20
|
+
}]
|
21
|
+
}
|
22
|
+
LOOKUPS = {
|
23
|
+
"resourceUse": [
|
24
|
+
"term.id",
|
25
|
+
"inHestiaDefaultSystemBoundary",
|
26
|
+
"siteTypesAllowed"
|
27
|
+
]
|
28
|
+
}
|
29
|
+
MODEL = 'resourceUseNotRelevant'
|
30
|
+
TIER = IndicatorMethodTier.NOT_RELEVANT.value
|
31
|
+
|
32
|
+
|
33
|
+
def _indicator(term_id: str, land_cover_id: str):
|
34
|
+
indicator = _new_indicator(term_id, MODEL, land_cover_id)
|
35
|
+
indicator['value'] = 0
|
36
|
+
indicator['methodTier'] = TIER
|
37
|
+
return indicator
|
38
|
+
|
39
|
+
|
40
|
+
def _resourceUse_ids():
|
41
|
+
return lookup_term_ids(download_lookup(f"{TermTermType.RESOURCEUSE.value}.csv"))
|
42
|
+
|
43
|
+
|
44
|
+
def _should_run_resourceUse(impact: dict):
|
45
|
+
def run(term_id: str):
|
46
|
+
is_not_relevant = not _run_required(MODEL, term_id, impact.get('cycle', {}))
|
47
|
+
in_system_boundary = is_in_system_boundary(term_id)
|
48
|
+
|
49
|
+
should_run = all([is_not_relevant, in_system_boundary])
|
50
|
+
if should_run:
|
51
|
+
# no need to show the model failed
|
52
|
+
logRequirements(impact, model=MODEL, term=term_id,
|
53
|
+
is_not_relevant=is_not_relevant,
|
54
|
+
in_system_boundary=in_system_boundary,
|
55
|
+
run_required=False)
|
56
|
+
logShouldRun(impact, MODEL, term_id, should_run)
|
57
|
+
return should_run
|
58
|
+
return run
|
59
|
+
|
60
|
+
|
61
|
+
def run(_, impact: dict):
|
62
|
+
term_ids = _resourceUse_ids()
|
63
|
+
term_ids = list(filter(_should_run_resourceUse(impact), term_ids))
|
64
|
+
land_cover_term_id = get_land_cover_term_id(get_site(impact).get('siteType'))
|
65
|
+
return [_indicator(term_id, land_cover_term_id) for term_id in term_ids]
|
@@ -80,7 +80,7 @@ def _should_run(cycle: dict):
|
|
80
80
|
measurements = site.get('measurements', [])
|
81
81
|
|
82
82
|
def _get_measurement_content(term_id: str):
|
83
|
-
return most_relevant_measurement_value(measurements, term_id, end_date)
|
83
|
+
return most_relevant_measurement_value(measurements, term_id, end_date, default=None)
|
84
84
|
|
85
85
|
nla_environment = _get_measurement_content('nutrientLossToAquaticEnvironment')
|
86
86
|
soil_nitrogen_content = _get_measurement_content('totalNitrogenPerKgSoil')
|
@@ -91,6 +91,7 @@ def _should_run(cycle: dict):
|
|
91
91
|
|
92
92
|
precipitation = _get_measurement_content('precipitationAnnual')
|
93
93
|
inputs_water = get_water_input(cycle)
|
94
|
+
total_water = list_sum([(inputs_water or 0)/10, precipitation or 0])
|
94
95
|
|
95
96
|
practice_factor = get_practice_factor(TERM_ID, site)
|
96
97
|
pcorr = get_pcorr(slope / 100) if slope is not None else None
|
@@ -100,7 +101,7 @@ def _should_run(cycle: dict):
|
|
100
101
|
list_of_contents_for_A = [
|
101
102
|
practice_factor, erodibility, slope_length,
|
102
103
|
pcorr, p_ef_c1, ef_p_c2]
|
103
|
-
list_of_contents_for_R = [heavy_winter_precipitation,
|
104
|
+
list_of_contents_for_R = [heavy_winter_precipitation, total_water]
|
104
105
|
list_of_contents_for_value = [nla_environment, soil_nitrogen_content]
|
105
106
|
|
106
107
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
@@ -118,8 +119,9 @@ def _should_run(cycle: dict):
|
|
118
119
|
soil_nitrogen_content=soil_nitrogen_content)
|
119
120
|
|
120
121
|
should_run = all([
|
122
|
+
heavy_winter_precipitation is not None,
|
123
|
+
total_water > 0,
|
121
124
|
all(list_of_contents_for_A),
|
122
|
-
all(list_of_contents_for_R),
|
123
125
|
all(list_of_contents_for_value)
|
124
126
|
])
|
125
127
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
@@ -80,7 +80,7 @@ def _should_run(cycle: dict):
|
|
80
80
|
measurements = site.get('measurements', [])
|
81
81
|
|
82
82
|
def _get_measurement_content(term_id: str):
|
83
|
-
return most_relevant_measurement_value(measurements, term_id, end_date)
|
83
|
+
return most_relevant_measurement_value(measurements, term_id, end_date, default=None)
|
84
84
|
|
85
85
|
nla_environment = _get_measurement_content('nutrientLossToAquaticEnvironment')
|
86
86
|
soil_phosphorus_content = _get_measurement_content('totalPhosphorusPerKgSoil')
|
@@ -91,6 +91,7 @@ def _should_run(cycle: dict):
|
|
91
91
|
|
92
92
|
precipitation = _get_measurement_content('precipitationAnnual')
|
93
93
|
inputs_water = get_water_input(cycle)
|
94
|
+
total_water = list_sum([(inputs_water or 0)/10, precipitation or 0])
|
94
95
|
|
95
96
|
practice_factor = get_practice_factor(TERM_ID, site)
|
96
97
|
pcorr = get_pcorr(slope / 100) if slope is not None else None
|
@@ -100,7 +101,7 @@ def _should_run(cycle: dict):
|
|
100
101
|
list_of_contents_for_A = [
|
101
102
|
practice_factor, erodibility, slope_length,
|
102
103
|
pcorr, p_ef_c1, ef_p_c2]
|
103
|
-
list_of_contents_for_R = [heavy_winter_precipitation,
|
104
|
+
list_of_contents_for_R = [heavy_winter_precipitation, total_water]
|
104
105
|
list_of_contents_for_value = [nla_environment, soil_phosphorus_content]
|
105
106
|
|
106
107
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
@@ -118,8 +119,9 @@ def _should_run(cycle: dict):
|
|
118
119
|
soil_phosphorus_content=soil_phosphorus_content)
|
119
120
|
|
120
121
|
should_run = all([
|
122
|
+
heavy_winter_precipitation is not None,
|
123
|
+
total_water > 0,
|
121
124
|
all(list_of_contents_for_A),
|
122
|
-
all(list_of_contents_for_R),
|
123
125
|
all(list_of_contents_for_value)
|
124
126
|
])
|
125
127
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
@@ -43,25 +43,26 @@ def get_pcorr(slope: float):
|
|
43
43
|
|
44
44
|
|
45
45
|
def _get_C2_factor(term_id: str, term: dict):
|
46
|
-
return safe_parse_float(get_lookup_value(term, 'C2_FACTORS', model=MODEL, term=term_id), None)
|
46
|
+
return safe_parse_float(get_lookup_value(term, 'C2_FACTORS', model=MODEL, term=term_id), default=None)
|
47
47
|
|
48
48
|
|
49
49
|
def get_practice_factor(term_id: str, site: dict):
|
50
50
|
return safe_parse_float(
|
51
|
-
get_lookup_value(site.get('country', {}), 'Practice_Factor', model=MODEL, term=term_id), None)
|
51
|
+
get_lookup_value(site.get('country', {}), 'Practice_Factor', model=MODEL, term=term_id), default=None)
|
52
52
|
|
53
53
|
|
54
54
|
def get_p_ef_c1(term_id: str, cycle: dict):
|
55
55
|
primary_product = find_primary_product(cycle) or {}
|
56
56
|
return safe_parse_float(
|
57
|
-
get_lookup_value(primary_product.get('term', {}), 'P_EF_C1', model=MODEL, term=term_id), None)
|
57
|
+
get_lookup_value(primary_product.get('term', {}), 'P_EF_C1', model=MODEL, term=term_id), default=None)
|
58
58
|
|
59
59
|
|
60
60
|
def get_ef_p_c2(term_id: str, cycle: dict):
|
61
61
|
tillage = _get_tillage(cycle)
|
62
62
|
country = cycle.get('site', {}).get('country', {})
|
63
63
|
return _get_C2_factor(term_id, tillage) if tillage else safe_parse_float(
|
64
|
-
get_lookup_value(country, 'EF_P_C2', model=MODEL, term=term_id), None
|
64
|
+
get_lookup_value(country, 'EF_P_C2', model=MODEL, term=term_id), default=None
|
65
|
+
)
|
65
66
|
|
66
67
|
|
67
68
|
def get_water_input(cycle: dict):
|
@@ -5,7 +5,7 @@ from hestia_earth.utils.tools import non_empty_list, flatten, is_number, list_su
|
|
5
5
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
6
6
|
from hestia_earth.models.utils import _include
|
7
7
|
from hestia_earth.models.utils.measurement import _new_measurement
|
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 = {
|
@@ -150,7 +150,7 @@ def _get_value(cycle: dict, content_list_of_items: list, N_total: float, term=TE
|
|
150
150
|
sand_factor = _sand_factor(sand, clay)
|
151
151
|
eco_factor = get_ecoClimateZone_lookup_value(ecoClimateZone, 'STEHFEST_BOUWMAN_2006_N2O-N_FACTOR')
|
152
152
|
crop_grouping_factor = N2O_FACTORS_BY_CROP[crop_grouping]
|
153
|
-
sum_factors = sum([carbon_factor, soil_factor, sand_factor, eco_factor, crop_grouping_factor])
|
153
|
+
sum_factors = sum([carbon_factor, soil_factor, sand_factor, eco_factor or 0, crop_grouping_factor])
|
154
154
|
conversion_unit = get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
155
155
|
|
156
156
|
try:
|
@@ -85,10 +85,10 @@ def _should_run(cycle: dict, term=TERM_ID, tier=TIER):
|
|
85
85
|
|
86
86
|
|
87
87
|
def _get_value(cycle: dict, country: dict, N_total: float, term=TERM_ID):
|
88
|
-
|
88
|
+
EF_NOX = safe_parse_float(get_lookup_value(country, LOOKUPS['region'], model=MODEL, term=TERM_ID), default=0)
|
89
89
|
debugValues(cycle, model=MODEL, term=term,
|
90
|
-
|
91
|
-
return
|
90
|
+
EF_NOX=EF_NOX)
|
91
|
+
return EF_NOX * N_total
|
92
92
|
|
93
93
|
|
94
94
|
def _run(cycle: dict, country: dict, N_total: float):
|
@@ -1,11 +1,11 @@
|
|
1
1
|
from hestia_earth.schema import TermTermType
|
2
|
-
from hestia_earth.utils.model import find_term_match
|
2
|
+
from hestia_earth.utils.model import find_term_match, filter_list_term_type
|
3
3
|
from hestia_earth.utils.tools import flatten
|
4
4
|
from hestia_earth.utils.emission import cycle_emissions_in_system_boundary
|
5
5
|
|
6
6
|
from hestia_earth.models.log import logShouldRun
|
7
7
|
from . import is_from_model
|
8
|
-
from .
|
8
|
+
from .term import get_lookup_value
|
9
9
|
|
10
10
|
|
11
11
|
def _animal_inputs(animal: dict):
|
@@ -35,8 +35,10 @@ def get_background_inputs(cycle: dict, extra_inputs: list = []):
|
|
35
35
|
return list(filter(_should_run_input(cycle.get('products', [])), inputs))
|
36
36
|
|
37
37
|
|
38
|
-
def no_gap_filled_background_emissions(
|
39
|
-
|
38
|
+
def no_gap_filled_background_emissions(
|
39
|
+
node: dict, list_key: str = 'emissions', term_type: TermTermType = TermTermType.EMISSION
|
40
|
+
):
|
41
|
+
blank_nodes = filter_list_term_type(node.get(list_key, []), term_type)
|
40
42
|
|
41
43
|
def check_input(input: dict):
|
42
44
|
input_term_id = input.get('term', {}).get('@id')
|
@@ -44,12 +46,12 @@ def no_gap_filled_background_emissions(cycle: dict):
|
|
44
46
|
animal_term_id = input.get('animal', {}).get('@id')
|
45
47
|
|
46
48
|
return not any([
|
47
|
-
is_from_model(
|
48
|
-
for
|
49
|
+
is_from_model(blank_node)
|
50
|
+
for blank_node in blank_nodes
|
49
51
|
if all([
|
50
|
-
any([i.get('@id') == input_term_id for i in
|
51
|
-
|
52
|
-
|
52
|
+
any([i.get('@id') == input_term_id for i in blank_node.get('inputs', [])]),
|
53
|
+
blank_node.get('operation', {}).get('@id') == operation_term_id,
|
54
|
+
blank_node.get('animal', {}).get('@id') == animal_term_id
|
53
55
|
])
|
54
56
|
])
|
55
57
|
|
@@ -67,10 +69,12 @@ def all_background_emission_term_ids(cycle: dict):
|
|
67
69
|
def log_missing_emissions(cycle: dict, **log_args):
|
68
70
|
all_emission_term_ids = all_background_emission_term_ids(cycle)
|
69
71
|
|
70
|
-
def log_input(input_term_id: str, included_emission_term_ids: list):
|
72
|
+
def log_input(input_term_id: str, included_emission_term_ids: list, **extra_log_args):
|
71
73
|
missing_emission_term_ids = [
|
72
74
|
term_id for term_id in all_emission_term_ids if term_id not in included_emission_term_ids
|
73
75
|
]
|
74
76
|
for emission_id in missing_emission_term_ids:
|
75
|
-
logShouldRun(cycle, term=input_term_id, should_run=False, emission_id=emission_id,
|
77
|
+
logShouldRun(cycle, term=input_term_id, should_run=False, emission_id=emission_id,
|
78
|
+
**log_args,
|
79
|
+
**extra_log_args)
|
76
80
|
return log_input
|
@@ -159,7 +159,7 @@ def _run_required(model: str, term_id: str, data: dict):
|
|
159
159
|
input_id_allowed=input_id_allowed,
|
160
160
|
input_termType_allowed=input_termType_allowed)
|
161
161
|
# logging this for the model would cause issues parsing statuses
|
162
|
-
if model
|
162
|
+
if not model.endswith('NotRelevant'):
|
163
163
|
debugValues(data, model=model, term=term_id, run_required=run_required)
|
164
164
|
return run_required
|
165
165
|
|
@@ -1326,16 +1326,18 @@ def get_inputs_from_properties(input: dict, term_types: Union[TermTermType, List
|
|
1326
1326
|
dict
|
1327
1327
|
A dictionary of nodes grouped by latest date, in the format `{date: list[node]}`.
|
1328
1328
|
"""
|
1329
|
+
term = input.get('term', {})
|
1329
1330
|
input_value = list_sum(input.get('value', []))
|
1330
1331
|
properties = (
|
1331
1332
|
input.get('properties') or
|
1332
|
-
|
1333
|
-
download_term(
|
1333
|
+
term.get('defaultProperties') or
|
1334
|
+
download_term(term).get('defaultProperties')
|
1334
1335
|
)
|
1335
1336
|
inputs = non_empty_list([
|
1336
1337
|
{
|
1337
1338
|
'term': p.get('key'),
|
1338
|
-
'value': [(p.get('value') / 100) * (p.get('share', 100) / 100) * input_value]
|
1339
|
+
'value': [(p.get('value') / 100) * (p.get('share', 100) / 100) * input_value],
|
1340
|
+
'parent': term
|
1339
1341
|
} for p in (properties or []) if all([p.get('key'), p.get('value')])
|
1340
1342
|
]) if input_value > 0 else []
|
1341
1343
|
return filter_list_term_type(inputs, term_types)
|
@@ -30,7 +30,7 @@ def get_N2ON_fertiliser_coeff_from_primary_product(model: str, log_id: str, cycl
|
|
30
30
|
product = find_primary_product(cycle)
|
31
31
|
term_id = product.get('term', {}).get('@id') if product else None
|
32
32
|
percent = get_crop_lookup_value(model, log_id, term_id, 'N2ON_FERT') if term_id else None
|
33
|
-
return safe_parse_float(percent, 0.01)
|
33
|
+
return safe_parse_float(percent, default=0.01)
|
34
34
|
|
35
35
|
|
36
36
|
def is_plantation(model: str, log_id: str, term_id: str):
|
@@ -1,3 +1,9 @@
|
|
1
|
+
from hestia_earth.schema import TermTermType
|
2
|
+
from hestia_earth.utils.model import find_term_match
|
3
|
+
from hestia_earth.utils.tools import flatten
|
4
|
+
|
5
|
+
from .completeness import _is_term_type_complete
|
6
|
+
|
1
7
|
PRODUCT_ID_TO_PRACTICES_ID = [
|
2
8
|
{'product': 'aboveGroundCropResidueRemoved', 'practices': ['residueRemoved']},
|
3
9
|
{'product': 'aboveGroundCropResidueIncorporated', 'practices': [
|
@@ -11,3 +17,13 @@ PRODUCT_ID_TO_PRACTICES_ID = [
|
|
11
17
|
|
12
18
|
|
13
19
|
def crop_residue_product_ids(): return [v.get('product') for v in PRODUCT_ID_TO_PRACTICES_ID]
|
20
|
+
|
21
|
+
|
22
|
+
def get_crop_residue_burnt_value(cycle: dict):
|
23
|
+
products = cycle.get('products', [])
|
24
|
+
value = flatten([
|
25
|
+
find_term_match(products, 'aboveGroundCropResidueBurnt').get('value', []),
|
26
|
+
find_term_match(products, 'discardedCropBurnt').get('value', [])
|
27
|
+
])
|
28
|
+
data_complete = _is_term_type_complete(cycle, TermTermType.CROPRESIDUE)
|
29
|
+
return [0] if len(value) == 0 and data_complete else value
|
@@ -204,7 +204,7 @@ def get_inorganic_fertiliser_P_total(cycle: dict) -> float:
|
|
204
204
|
|
205
205
|
def get_max_rooting_depth(cycle: dict) -> float:
|
206
206
|
properties = list(map(lambda p: get_node_property(p, 'rootingDepth'), cycle.get('products', [])))
|
207
|
-
values = [safe_parse_float(p.get('value')) for p in properties if p.get('value') is not None]
|
207
|
+
values = [safe_parse_float(p.get('value'), default=0) for p in properties if p.get('value') is not None]
|
208
208
|
return max(values) if len(values) > 0 else None
|
209
209
|
|
210
210
|
|
@@ -87,7 +87,7 @@ def get_ecoClimateZone_lookup_value(eco_climate_zone: str, col_name: str, group_
|
|
87
87
|
code = int(str(eco_climate_zone))
|
88
88
|
data = _get_single_table_value(lookup, column_name('ecoClimateZone'), code, column_name(col_name))
|
89
89
|
return safe_parse_float(
|
90
|
-
data if group_name is None else extract_grouped_data(data, group_name)
|
90
|
+
data if group_name is None else extract_grouped_data(data, group_name), default=None
|
91
91
|
)
|
92
92
|
except Exception:
|
93
93
|
return 0
|
@@ -118,7 +118,7 @@ def get_ecoClimateZone_lookup_grouped_value(
|
|
118
118
|
code = int(str(eco_climate_zone))
|
119
119
|
data = _get_single_table_value(lookup, column_name('ecoClimateZone'), code, column_name(col_name))
|
120
120
|
grouped_data = reduce(
|
121
|
-
lambda prev, curr: prev | {curr.split(':')[0]: safe_parse_float(curr.split(':')[1])},
|
121
|
+
lambda prev, curr: prev | {curr.split(':')[0]: safe_parse_float(curr.split(':')[1], default=None)},
|
122
122
|
data.split(';'),
|
123
123
|
{}
|
124
124
|
) if data is not None and isinstance(data, str) and len(data) > 1 else default
|
@@ -19,7 +19,7 @@ def _get_nh3_factor(lookup_name: str, term_id: str, input: dict, **log_args):
|
|
19
19
|
input_term_id = input.get('term', {}).get('@id')
|
20
20
|
value = get_table_value(download_lookup(lookup_name), 'termid', term_id, column_name(input_term_id))
|
21
21
|
debugMissingLookup(lookup_name, 'termid', term_id, input_term_id, value, **log_args)
|
22
|
-
return safe_parse_float(value, None)
|
22
|
+
return safe_parse_float(value, default=None)
|
23
23
|
|
24
24
|
|
25
25
|
def get_excreta_inputs_with_factor(cycle: dict, lookup_name: str, excreta_conversion_func, **log_args):
|
@@ -27,9 +27,9 @@ def _should_rescale_by_dm(property_id: str):
|
|
27
27
|
def _dm_property(term_id: str, property_values: dict, dm_property_values: dict, dry_matter_property: dict):
|
28
28
|
blank_node_data = {}
|
29
29
|
for property_key in property_values.keys():
|
30
|
-
new_dm_value = safe_parse_float(dry_matter_property.get(property_key))
|
31
|
-
old_dm_value = safe_parse_float(dm_property_values.get(property_key))
|
32
|
-
old_property_value = safe_parse_float(property_values.get(property_key))
|
30
|
+
new_dm_value = safe_parse_float(dry_matter_property.get(property_key), default=None)
|
31
|
+
old_dm_value = safe_parse_float(dm_property_values.get(property_key), default=None)
|
32
|
+
old_property_value = safe_parse_float(property_values.get(property_key), default=None)
|
33
33
|
if all([new_dm_value, old_dm_value, old_property_value]):
|
34
34
|
new_value = round(
|
35
35
|
old_property_value / old_dm_value * new_dm_value,
|
@@ -5,7 +5,13 @@ from hestia_earth.utils.tools import flatten
|
|
5
5
|
|
6
6
|
from .blank_node import get_inputs_from_properties
|
7
7
|
|
8
|
-
_TERM_TYPES = [
|
8
|
+
_TERM_TYPES = [
|
9
|
+
TermTermType.INORGANICFERTILISER,
|
10
|
+
TermTermType.ORGANICFERTILISER,
|
11
|
+
TermTermType.OTHERINORGANICCHEMICAL,
|
12
|
+
TermTermType.OTHERORGANICCHEMICAL,
|
13
|
+
TermTermType.PESTICIDEAI
|
14
|
+
]
|
9
15
|
|
10
16
|
|
11
17
|
def get_fertilisers_from_inputs(cycle: dict, term_types: Union[TermTermType, List[TermTermType]] = _TERM_TYPES):
|