hestia-earth-models 0.64.8__py3-none-any.whl → 0.64.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hestia-earth-models might be problematic. Click here for more details.
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +175 -0
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +136 -0
- hestia_earth/models/cycle/siteArea.py +2 -1
- hestia_earth/models/environmentalFootprintV3/soilQualityIndexLandOccupation.py +73 -82
- hestia_earth/models/environmentalFootprintV3/soilQualityIndexLandTransformation.py +102 -116
- hestia_earth/models/environmentalFootprintV3/soilQualityIndexTotalLandUseEffects.py +27 -16
- hestia_earth/models/faostat2018/landTransformationFromCropland100YearAverage.py +3 -2
- hestia_earth/models/faostat2018/landTransformationFromCropland20YearAverage.py +3 -2
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +69 -37
- hestia_earth/models/ipcc2019/aboveGroundBiomass.py +31 -243
- hestia_earth/models/ipcc2019/animal/fatContent.py +38 -0
- hestia_earth/models/ipcc2019/animal/liveweightGain.py +3 -54
- hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +3 -54
- hestia_earth/models/ipcc2019/animal/pregnancyRateTotal.py +38 -0
- hestia_earth/models/ipcc2019/animal/trueProteinContent.py +38 -0
- hestia_earth/models/ipcc2019/animal/utils.py +87 -3
- hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +4 -10
- hestia_earth/models/ipcc2019/belowGroundBiomass.py +529 -0
- hestia_earth/models/ipcc2019/biomass_utils.py +406 -0
- hestia_earth/models/ipcc2019/{co2ToAirAboveGroundBiomassStockChangeLandUseChange.py → co2ToAirAboveGroundBiomassStockChange.py} +19 -7
- hestia_earth/models/ipcc2019/{co2ToAirBelowGroundBiomassStockChangeLandUseChange.py → co2ToAirBelowGroundBiomassStockChange.py} +19 -7
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +402 -73
- hestia_earth/models/ipcc2019/{co2ToAirSoilOrganicCarbonStockChangeManagementChange.py → co2ToAirSoilOrganicCarbonStockChange.py} +20 -8
- hestia_earth/models/ipcc2019/organicCarbonPerHa.py +3 -1
- hestia_earth/models/ipcc2019/pastureGrass_utils.py +6 -7
- hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
- hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsWaterStress.py +2 -2
- hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthParticulateMatterFormation.py +2 -2
- hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactAllEffects100Years/damageToMarineEcosystemsMarineEutrophication.py +2 -2
- hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsWaterStress.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthParticulateMatterFormation.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToMarineEcosystemsMarineEutrophication.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthParticulateMatterFormation.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToMarineEcosystemsMarineEutrophication.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthParticulateMatterFormation.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToMarineEcosystemsMarineEutrophication.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
- hestia_earth/models/mocking/build_mock_search.py +44 -0
- hestia_earth/models/mocking/mock_search.py +8 -49
- hestia_earth/models/mocking/search-results.json +3078 -575
- hestia_earth/models/poschEtAl2008/terrestrialAcidificationPotentialAccumulatedExceedance.py +6 -3
- hestia_earth/models/poschEtAl2008/terrestrialEutrophicationPotentialAccumulatedExceedance.py +6 -3
- hestia_earth/models/preload_requests.py +1 -1
- hestia_earth/models/schmidt2007/utils.py +13 -4
- hestia_earth/models/utils/__init__.py +5 -4
- hestia_earth/models/utils/blank_node.py +73 -3
- hestia_earth/models/utils/constant.py +8 -1
- hestia_earth/models/utils/cycle.py +10 -13
- hestia_earth/models/utils/fuel.py +1 -1
- hestia_earth/models/utils/impact_assessment.py +39 -15
- hestia_earth/models/utils/lookup.py +36 -7
- hestia_earth/models/utils/pesticideAI.py +1 -1
- hestia_earth/models/utils/property.py +11 -4
- hestia_earth/models/utils/term.py +15 -8
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.64.8.dist-info → hestia_earth_models-0.64.10.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.64.8.dist-info → hestia_earth_models-0.64.10.dist-info}/RECORD +103 -90
- {hestia_earth_models-0.64.8.dist-info → hestia_earth_models-0.64.10.dist-info}/WHEEL +1 -1
- tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +196 -0
- tests/models/cml2001Baseline/test_abioticResourceDepletionMineralsAndMetals.py +124 -0
- tests/models/edip2003/test_ozoneDepletionPotential.py +1 -13
- tests/models/environmentalFootprintV3/test_soilQualityIndexLandOccupation.py +97 -66
- tests/models/environmentalFootprintV3/test_soilQualityIndexLandTransformation.py +136 -74
- tests/models/environmentalFootprintV3/test_soilQualityIndexTotalLandUseEffects.py +15 -10
- tests/models/frischknechtEtAl2000/test_ionisingRadiationKbqU235Eq.py +67 -44
- tests/models/impact_assessment/test_emissions.py +1 -0
- tests/models/ipcc2019/animal/test_fatContent.py +22 -0
- tests/models/ipcc2019/animal/test_liveweightGain.py +4 -2
- tests/models/ipcc2019/animal/test_liveweightPerHead.py +4 -2
- tests/models/ipcc2019/animal/test_pregnancyRateTotal.py +22 -0
- tests/models/ipcc2019/animal/test_trueProteinContent.py +22 -0
- tests/models/ipcc2019/animal/test_weightAtMaturity.py +2 -1
- tests/models/ipcc2019/test_aboveGroundBiomass.py +27 -63
- tests/models/ipcc2019/test_belowGroundBiomass.py +146 -0
- tests/models/ipcc2019/test_biomass_utils.py +115 -0
- tests/models/ipcc2019/{test_co2ToAirAboveGroundBiomassStockChangeLandUseChange.py → test_co2ToAirAboveGroundBiomassStockChange.py} +5 -5
- tests/models/ipcc2019/{test_co2ToAirBelowGroundBiomassStockChangeLandUseChange.py → test_co2ToAirBelowGroundBiomassStockChange.py} +5 -5
- tests/models/ipcc2019/{test_co2ToAirSoilOrganicCarbonStockChangeManagementChange.py → test_co2ToAirSoilOrganicCarbonStockChange.py} +5 -5
- tests/models/ipcc2021/test_gwp100.py +2 -2
- tests/models/poschEtAl2008/test_terrestrialAcidificationPotentialAccumulatedExceedance.py +30 -17
- tests/models/poschEtAl2008/test_terrestrialEutrophicationPotentialAccumulatedExceedance.py +28 -14
- hestia_earth/models/ipcc2019/aboveGroundBiomass_utils.py +0 -180
- tests/models/ipcc2019/test_aboveGroundBiomass_utils.py +0 -92
- {hestia_earth_models-0.64.8.dist-info → hestia_earth_models-0.64.10.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.64.8.dist-info → hestia_earth_models-0.64.10.dist-info}/top_level.txt +0 -0
|
@@ -4,53 +4,53 @@ based on an updated [LANCA model (De Laurentiis et al. 2019)](
|
|
|
4
4
|
http://publications.jrc.ec.europa.eu/repository/handle/JRC113865) and on the LANCA (Regionalised) Characterisation
|
|
5
5
|
Factors version 2.5 (Horn and Meier, 2018).
|
|
6
6
|
"""
|
|
7
|
-
from typing import List
|
|
7
|
+
from typing import List, Tuple, Optional
|
|
8
8
|
|
|
9
9
|
from hestia_earth.schema import TermTermType
|
|
10
10
|
from hestia_earth.utils.lookup import download_lookup
|
|
11
11
|
from hestia_earth.utils.model import filter_list_term_type
|
|
12
|
-
from hestia_earth.utils.tools import list_sum
|
|
12
|
+
from hestia_earth.utils.tools import list_sum
|
|
13
13
|
|
|
14
14
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
|
15
|
-
from hestia_earth.models.utils import hectar_to_square_meter
|
|
16
|
-
from hestia_earth.models.utils import pairwise
|
|
17
15
|
from . import MODEL
|
|
18
16
|
from .utils import get_coefficient_factor
|
|
17
|
+
from ..utils.impact_assessment import get_country_id
|
|
19
18
|
from ..utils.indicator import _new_indicator
|
|
20
19
|
from ..utils.landCover import get_pef_grouping
|
|
21
|
-
from ..utils.lookup import fallback_country
|
|
20
|
+
from ..utils.lookup import fallback_country, _node_value
|
|
21
|
+
from ..utils.term import get_land_cover_terms
|
|
22
22
|
|
|
23
23
|
REQUIREMENTS = {
|
|
24
24
|
"ImpactAssessment": {
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
"optional": {
|
|
34
|
-
"otherSitesArea": "> 0",
|
|
35
|
-
"otherSites": [{
|
|
36
|
-
"@type": "Site",
|
|
37
|
-
"management": [{"@type": "Management", "term.termType": "landCover"}],
|
|
38
|
-
"optional": {"country": {"@type": "Term", "termType": "region"}}
|
|
39
|
-
}]
|
|
25
|
+
"emissionsResourceUse": [
|
|
26
|
+
{
|
|
27
|
+
"@type": "Indicator",
|
|
28
|
+
"term.units": "m2 / year",
|
|
29
|
+
"term.termType": "resourceUse",
|
|
30
|
+
"term.name": "Land transformation from",
|
|
31
|
+
"value": "> 0",
|
|
32
|
+
"landCover": {"@type": "Term", "term.termType": "landCover"}
|
|
40
33
|
}
|
|
41
|
-
|
|
34
|
+
],
|
|
35
|
+
"optional": {"country": {"@type": "Term", "termType": "region"}}
|
|
42
36
|
}
|
|
43
37
|
}
|
|
44
38
|
|
|
39
|
+
# Note: CFs in `region-pefTermGrouping-landTransformation-from.csv` appear to be the opposite values as those in
|
|
40
|
+
# `region-pefTermGrouping-landTransformation-to.csv` but can be different in some cases.
|
|
45
41
|
LOOKUPS = {
|
|
46
|
-
"
|
|
47
|
-
"region-pefTermGrouping-landTransformation-
|
|
48
|
-
"region-pefTermGrouping-landTransformation-to": "",
|
|
42
|
+
"region-pefTermGrouping-landTransformation-from": "using country and `pefTermGrouping` from `landCover`",
|
|
43
|
+
"region-pefTermGrouping-landTransformation-to": "using country and `pefTermGrouping` from `landCover`",
|
|
49
44
|
"landCover": "pefTermGrouping"
|
|
50
45
|
}
|
|
51
46
|
|
|
52
|
-
from_lookup_file = f"{list(LOOKUPS.keys())[
|
|
53
|
-
to_lookup_file = f"{list(LOOKUPS.keys())[
|
|
47
|
+
from_lookup_file = f"{list(LOOKUPS.keys())[0]}.csv"
|
|
48
|
+
to_lookup_file = f"{list(LOOKUPS.keys())[1]}.csv"
|
|
49
|
+
|
|
50
|
+
LOOKUP = {
|
|
51
|
+
"from": from_lookup_file,
|
|
52
|
+
"to": to_lookup_file
|
|
53
|
+
}
|
|
54
54
|
|
|
55
55
|
RETURNS = {
|
|
56
56
|
"Indicator": {
|
|
@@ -67,116 +67,102 @@ def _indicator(value: float):
|
|
|
67
67
|
return indicator
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
def _run(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
for transformation_from_factor, transformation_to_factor in site['transformation_factors']]
|
|
75
|
-
result.append(list_sum(values))
|
|
76
|
-
return _indicator(list_sum(result)) if result else None
|
|
70
|
+
def _run(transformations: List[dict]):
|
|
71
|
+
values = [(transformation['factor-from'] + transformation['factor-to']) * transformation['area'] for transformation
|
|
72
|
+
in transformations]
|
|
73
|
+
return _indicator(list_sum(values))
|
|
77
74
|
|
|
78
75
|
|
|
79
|
-
def
|
|
80
|
-
|
|
76
|
+
def _extract_land_cover_from_indicator_id(indicator: dict) -> Optional[str]:
|
|
77
|
+
"""
|
|
78
|
+
Given a indicator with term type `resourceUse` return the equivalent `landCover` term
|
|
79
|
+
"""
|
|
80
|
+
term_in_id = indicator.get('term', {}).get('@id', '') \
|
|
81
|
+
.removeprefix("landTransformationFrom") \
|
|
82
|
+
.removesuffix("20YearAverageInputsProduction") \
|
|
83
|
+
.removesuffix("20YearAverageDuringCycle")
|
|
84
|
+
term_in_id = term_in_id[0].lower() + term_in_id[1:] if term_in_id else None
|
|
85
|
+
return term_in_id
|
|
81
86
|
|
|
82
|
-
has_site = bool(cycle.get('site', {}))
|
|
83
|
-
site_area = cycle.get('site', {}).get("area", False)
|
|
84
|
-
has_area = site_area > 0
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
def _is_valid_indicator(indicator: dict, land_cover_term_ids: list[str]) -> bool:
|
|
89
|
+
term_id = _extract_land_cover_from_indicator_id(indicator)
|
|
90
|
+
return term_id in land_cover_term_ids
|
|
87
91
|
|
|
88
|
-
all_sites = non_empty_list([cycle.get('site')] + cycle.get('otherSites', []))
|
|
89
|
-
site_areas = [cycle.get('site', {}).get('area')] + cycle.get('otherSitesArea', [])
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
'transformation_pairs': list(pairwise(
|
|
95
|
-
sorted(filter_list_term_type(site.get("management", []), TermTermType.LANDCOVER.value),
|
|
96
|
-
key=lambda d: safe_parse_date(d['endDate'])))),
|
|
97
|
-
'country_id_str': site.get('country', {}).get('@id', ''),
|
|
98
|
-
'area': site_areas[index] if len(site_areas) >= index + 1 else None,
|
|
99
|
-
}
|
|
100
|
-
for index, site in enumerate(all_sites)
|
|
101
|
-
]
|
|
93
|
+
def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
|
|
94
|
+
resource_uses = filter_list_term_type(impact_assessment.get('emissionsResourceUse', []), TermTermType.RESOURCEUSE)
|
|
95
|
+
land_cover_term_ids = get_land_cover_terms() if resource_uses else []
|
|
102
96
|
|
|
103
|
-
|
|
104
|
-
site for site in sites
|
|
105
|
-
if all([
|
|
106
|
-
(site.get('area') or 0) > 0,
|
|
107
|
-
site.get('transformation_pairs', [])
|
|
108
|
-
])
|
|
109
|
-
]
|
|
97
|
+
land_transformation_indicators = [i for i in resource_uses if _is_valid_indicator(i, land_cover_term_ids)]
|
|
110
98
|
|
|
111
|
-
|
|
112
|
-
site |
|
|
99
|
+
found_transformations = [
|
|
113
100
|
{
|
|
114
|
-
'
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
101
|
+
'area': _node_value(transformation_indicator) * 20,
|
|
102
|
+
'area-unit': transformation_indicator.get('term', {}).get("units"),
|
|
103
|
+
'land-cover-id-from': _extract_land_cover_from_indicator_id(transformation_indicator),
|
|
104
|
+
'land-cover-id-to': transformation_indicator.get('landCover', {}).get("@id"),
|
|
105
|
+
'indicator-id': transformation_indicator.get('term', {}).get('@id', ''),
|
|
106
|
+
'good-land-cover-term': transformation_indicator.get('landCover', {}).get('termType') == 'landCover',
|
|
107
|
+
'country-id': get_country_id(impact_assessment),
|
|
108
|
+
'area-is-valid': _node_value(transformation_indicator) is not None and _node_value(
|
|
109
|
+
transformation_indicator) > 0,
|
|
110
|
+
'area-unit-is-valid': transformation_indicator.get('term', {}).get("units") == "m2 / year",
|
|
111
|
+
'lookup-country': fallback_country(get_country_id(impact_assessment),
|
|
112
|
+
[download_lookup(from_lookup_file), download_lookup(to_lookup_file)]),
|
|
113
|
+
} for transformation_indicator in land_transformation_indicators
|
|
118
114
|
]
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
116
|
+
found_transformations_with_coefficient = [
|
|
117
|
+
transformation | {
|
|
118
|
+
"using-fallback-country-region-world-CFs": transformation['lookup-country'] != transformation['country-id'],
|
|
119
|
+
'factor-from': get_coefficient_factor(
|
|
120
|
+
lookup_name=from_lookup_file,
|
|
121
|
+
country_id=transformation['lookup-country'],
|
|
122
|
+
term_id=TERM_ID,
|
|
123
|
+
occupation_type=get_pef_grouping(transformation['land-cover-id-from'])) if
|
|
124
|
+
transformation['land-cover-id-from'] else None,
|
|
125
|
+
'factor-to': get_coefficient_factor(
|
|
126
|
+
lookup_name=to_lookup_file,
|
|
127
|
+
country_id=transformation['lookup-country'],
|
|
128
|
+
term_id=TERM_ID,
|
|
129
|
+
occupation_type=get_pef_grouping(transformation['land-cover-id-to'])) if
|
|
130
|
+
transformation['land-cover-id-to'] else None
|
|
131
|
+
} for transformation in found_transformations
|
|
132
132
|
]
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
'
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
country_id=site['country_id'], term_id=TERM_ID,
|
|
142
|
-
occupation_type=to_transformation_header))
|
|
143
|
-
for from_transformation_header, to_transformation_header in site['column_names']]
|
|
144
|
-
} for site in valid_sites
|
|
134
|
+
valid_transformations_with_coef = [
|
|
135
|
+
t for t in found_transformations_with_coefficient if all([
|
|
136
|
+
t['area-is-valid'],
|
|
137
|
+
t['area-unit-is-valid'],
|
|
138
|
+
t['factor-from'] is not None,
|
|
139
|
+
t['factor-to'] is not None
|
|
140
|
+
])
|
|
145
141
|
]
|
|
146
142
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
'
|
|
152
|
-
|
|
153
|
-
]
|
|
154
|
-
|
|
155
|
-
log_transformation_factors = [
|
|
156
|
-
[{
|
|
157
|
-
'site-id': site['site_id'],
|
|
158
|
-
'country-id-used-for-factors': site['country_id'],
|
|
159
|
-
'country-id-in-input': site['country_id_str'],
|
|
160
|
-
'factor-from': from_transformation_header,
|
|
161
|
-
'factor-to': to_transformation_header,
|
|
162
|
-
} for from_transformation_header, to_transformation_header in site['transformation_factors']
|
|
163
|
-
] for site in valid_sites]
|
|
143
|
+
has_land_transformation_indicators = bool(land_transformation_indicators)
|
|
144
|
+
|
|
145
|
+
all_transformations_are_valid = all(
|
|
146
|
+
[
|
|
147
|
+
all([t['area-is-valid'], t['area-unit-is-valid'], t['good-land-cover-term']])
|
|
148
|
+
for t in found_transformations_with_coefficient
|
|
149
|
+
]
|
|
150
|
+
) if found_transformations_with_coefficient else False
|
|
164
151
|
|
|
165
152
|
logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
equivalent_EU_PEF_landUse_names=log_as_table(log_equivalent_eu_pef_land_use_names),
|
|
171
|
-
transformation_factors=log_as_table(log_transformation_factors)
|
|
153
|
+
has_land_occupation_indicators=has_land_transformation_indicators,
|
|
154
|
+
all_transformations_are_valid=all_transformations_are_valid,
|
|
155
|
+
has_valid_transformations_with_coef=bool(valid_transformations_with_coef),
|
|
156
|
+
found_transformations=log_as_table(found_transformations_with_coefficient)
|
|
172
157
|
)
|
|
173
|
-
should_run = has_valid_sites
|
|
174
158
|
|
|
175
|
-
|
|
159
|
+
should_run = has_land_transformation_indicators is False or all([has_land_transformation_indicators,
|
|
160
|
+
all_transformations_are_valid])
|
|
176
161
|
|
|
177
|
-
|
|
162
|
+
logShouldRun(impact_assessment, MODEL, TERM_ID, should_run)
|
|
163
|
+
return should_run, valid_transformations_with_coef
|
|
178
164
|
|
|
179
165
|
|
|
180
166
|
def run(impact_assessment: dict):
|
|
181
|
-
should_run,
|
|
182
|
-
return _run(
|
|
167
|
+
should_run, transformations = _should_run(impact_assessment)
|
|
168
|
+
return _run(transformations) if should_run else None
|
|
@@ -5,6 +5,7 @@ http://publications.jrc.ec.europa.eu/repository/handle/JRC113865) and on the LAN
|
|
|
5
5
|
Factors version 2.5 (Horn and Meier, 2018).
|
|
6
6
|
"""
|
|
7
7
|
from hestia_earth.utils.model import find_term_match
|
|
8
|
+
from hestia_earth.utils.tools import list_sum
|
|
8
9
|
|
|
9
10
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
10
11
|
from . import MODEL
|
|
@@ -35,32 +36,42 @@ def _indicator(value: float):
|
|
|
35
36
|
return indicator
|
|
36
37
|
|
|
37
38
|
|
|
38
|
-
def _run(
|
|
39
|
-
|
|
40
|
-
return _indicator(
|
|
39
|
+
def _run(indicators: list):
|
|
40
|
+
values = [indicator['value'] for indicator in indicators]
|
|
41
|
+
return _indicator(list_sum(values))
|
|
41
42
|
|
|
42
43
|
|
|
43
|
-
def _should_run(impactassessment: dict):
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
def _should_run(impactassessment: dict) -> tuple[bool, list]:
|
|
45
|
+
land_indicators = [
|
|
46
|
+
i for i in impactassessment.get('emissionsResourceUse', []) if
|
|
47
|
+
i.get('term', {}).get('@id', '') in ['soilQualityIndexLandOccupation', 'soilQualityIndexLandTransformation']
|
|
48
|
+
]
|
|
49
|
+
has_indicators = bool(land_indicators)
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
land_occupation_indicator = find_term_match(land_indicators, "soilQualityIndexLandOccupation",
|
|
52
|
+
default_val=None)
|
|
53
|
+
has_land_occupation_indicator = bool(land_occupation_indicator)
|
|
54
|
+
|
|
55
|
+
land_transformation_indicator = find_term_match(land_indicators, "soilQualityIndexLandTransformation",
|
|
56
|
+
default_val=None)
|
|
57
|
+
has_land_transformation_indicator = bool(land_transformation_indicator)
|
|
58
|
+
|
|
59
|
+
has_valid_values = all([isinstance(indicator.get('value', None), (int, float)) for indicator in land_indicators])
|
|
51
60
|
|
|
52
61
|
logRequirements(impactassessment, model=MODEL, term=TERM_ID,
|
|
53
|
-
|
|
54
|
-
|
|
62
|
+
has_indicators=has_indicators,
|
|
63
|
+
has_land_occupation_indicator=has_land_occupation_indicator,
|
|
64
|
+
has_land_transformation_indicator=has_land_transformation_indicator,
|
|
55
65
|
has_valid_values=has_valid_values
|
|
56
66
|
)
|
|
57
67
|
|
|
58
|
-
should_run = all([
|
|
68
|
+
should_run = all([has_indicators, has_valid_values,
|
|
69
|
+
has_land_occupation_indicator, has_land_transformation_indicator])
|
|
59
70
|
|
|
60
71
|
logShouldRun(impactassessment, MODEL, TERM_ID, should_run)
|
|
61
|
-
return should_run,
|
|
72
|
+
return should_run, land_indicators
|
|
62
73
|
|
|
63
74
|
|
|
64
75
|
def run(impactassessment: dict):
|
|
65
|
-
should_run,
|
|
66
|
-
return _run(
|
|
76
|
+
should_run, indicators = _should_run(impactassessment)
|
|
77
|
+
return _run(indicators) if should_run else None
|
|
@@ -20,7 +20,8 @@ LOOKUPS = {
|
|
|
20
20
|
}
|
|
21
21
|
RETURNS = {
|
|
22
22
|
"Indicator": [{
|
|
23
|
-
"value": ""
|
|
23
|
+
"value": "",
|
|
24
|
+
"landCover": ""
|
|
24
25
|
}]
|
|
25
26
|
}
|
|
26
27
|
TERM_ID = 'landTransformationFromTemporaryCropland100YearAverageDuringCycle,landTransformationFromPermanentCropland100YearAverageDuringCycle' # noqa: E501
|
|
@@ -30,7 +31,7 @@ PERMANENT_TERM_ID = 'landTransformationFromPermanentCropland100YearAverageDuring
|
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def _indicator(term_id: str, value: float):
|
|
33
|
-
indicator = _new_indicator(term_id, MODEL)
|
|
34
|
+
indicator = _new_indicator(term_id, MODEL, 'cropland')
|
|
34
35
|
indicator['value'] = value
|
|
35
36
|
return indicator
|
|
36
37
|
|
|
@@ -20,7 +20,8 @@ LOOKUPS = {
|
|
|
20
20
|
}
|
|
21
21
|
RETURNS = {
|
|
22
22
|
"Indicator": [{
|
|
23
|
-
"value": ""
|
|
23
|
+
"value": "",
|
|
24
|
+
"landCover": ""
|
|
24
25
|
}]
|
|
25
26
|
}
|
|
26
27
|
TERM_ID = 'landTransformationFromTemporaryCropland20YearAverageDuringCycle,landTransformationFromPermanentCropland20YearAverageDuringCycle' # noqa: E501
|
|
@@ -30,7 +31,7 @@ PERMANENT_TERM_ID = 'landTransformationFromPermanentCropland20YearAverageDuringC
|
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
def _indicator(term_id: str, value: float):
|
|
33
|
-
indicator = _new_indicator(term_id, MODEL)
|
|
34
|
+
indicator = _new_indicator(term_id, MODEL, 'cropland')
|
|
34
35
|
indicator['value'] = value
|
|
35
36
|
return indicator
|
|
36
37
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
from functools import reduce
|
|
2
1
|
from hestia_earth.schema import TermTermType
|
|
3
|
-
from hestia_earth.utils.
|
|
2
|
+
from hestia_earth.utils.lookup import get_table_value, download_lookup, column_name
|
|
3
|
+
from hestia_earth.utils.model import filter_list_term_type
|
|
4
|
+
from hestia_earth.utils.tools import flatten
|
|
4
5
|
|
|
5
|
-
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
6
|
-
from hestia_earth.models.utils.emission import filter_emission_inputs
|
|
6
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
|
7
7
|
from hestia_earth.models.utils.indicator import _new_indicator
|
|
8
|
-
from hestia_earth.models.utils.lookup import
|
|
8
|
+
from hestia_earth.models.utils.lookup import _node_value
|
|
9
9
|
from . import MODEL
|
|
10
10
|
|
|
11
11
|
REQUIREMENTS = {
|
|
@@ -18,7 +18,7 @@ REQUIREMENTS = {
|
|
|
18
18
|
"ionisingCompoundsToWaterInputsProduction",
|
|
19
19
|
"ionisingCompoundsToSaltwaterInputsProduction"
|
|
20
20
|
],
|
|
21
|
-
"inputs":
|
|
21
|
+
"inputs": {"@type": "Term", "term.termType": "waste", "term.units": "kg"}
|
|
22
22
|
}]
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -30,15 +30,23 @@ LOOKUPS = {
|
|
|
30
30
|
]
|
|
31
31
|
}
|
|
32
32
|
RETURNS = {
|
|
33
|
-
"Indicator": {
|
|
33
|
+
"Indicator": [{
|
|
34
34
|
"value": "",
|
|
35
35
|
"inputs": ""
|
|
36
|
-
}
|
|
36
|
+
}]
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
TERM_ID = 'ionisingRadiationKbqU235Eq'
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
def _valid_waste(input: dict) -> bool:
|
|
43
|
+
return input.get('units', '').startswith("kg") and input.get('termType', '') == TermTermType.WASTE.value
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _valid_emission(emission: dict) -> bool:
|
|
47
|
+
return len(emission.get('inputs', [])) == 1 and isinstance(_node_value(emission), (int, float))
|
|
48
|
+
|
|
49
|
+
|
|
42
50
|
def _indicator(value: float, input: dict):
|
|
43
51
|
indicator = _new_indicator(TERM_ID, MODEL)
|
|
44
52
|
indicator['value'] = value
|
|
@@ -46,45 +54,69 @@ def _indicator(value: float, input: dict):
|
|
|
46
54
|
return indicator
|
|
47
55
|
|
|
48
56
|
|
|
49
|
-
def _run(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
model=MODEL,
|
|
54
|
-
term_id=TERM_ID,
|
|
55
|
-
lookup_name=f"{TermTermType.WASTE.value}.csv",
|
|
56
|
-
lookup_col=i.get('emission').get('term', {}).get('@id')
|
|
57
|
-
)(data=i.get('emission') | {'term': i.get('input')})
|
|
58
|
-
for i in grouped_emissions_inputs
|
|
57
|
+
def _run(emissions: list):
|
|
58
|
+
indicators = [
|
|
59
|
+
_indicator(value=emission['value'] * emission['coefficient'], input=emission['input'])
|
|
60
|
+
for emission in emissions
|
|
59
61
|
]
|
|
60
|
-
|
|
61
|
-
return _indicator(value, input) if value else None
|
|
62
|
+
return indicators
|
|
62
63
|
|
|
63
64
|
|
|
64
65
|
def _should_run(impact_assessment: dict):
|
|
65
|
-
emissions =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
emissions = [emission for emission in filter_list_term_type(impact_assessment.get('emissionsResourceUse', []),
|
|
67
|
+
TermTermType.EMISSION)
|
|
68
|
+
if emission.get('term', {}).get('@id', '') in LOOKUPS[TermTermType.WASTE.value]]
|
|
69
|
+
|
|
70
|
+
has_emissions = bool(emissions)
|
|
71
|
+
|
|
72
|
+
emissions_unpacked = flatten(
|
|
73
|
+
[
|
|
74
|
+
[
|
|
75
|
+
{
|
|
76
|
+
"input-term-id": input.get('@id'),
|
|
77
|
+
"input-term-type": input.get('termType'),
|
|
78
|
+
"indicator-term-id": emission['term']['@id'],
|
|
79
|
+
"indicator-is-valid": _valid_emission(emission),
|
|
80
|
+
"input": input,
|
|
81
|
+
"indicator-input-is-valid": _valid_waste(input),
|
|
82
|
+
"value": _node_value(emission),
|
|
83
|
+
"coefficient": get_table_value(array=download_lookup(filename="waste.csv"),
|
|
84
|
+
col_match='termid',
|
|
85
|
+
col_match_with=input.get('@id'),
|
|
86
|
+
col_val=column_name(emission['term']['@id'])) if input else None
|
|
87
|
+
} for input in emission['inputs'] or [{}]]
|
|
88
|
+
for emission in emissions
|
|
89
|
+
]
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
valid_emission_with_cf = [em for em in emissions_unpacked if em['coefficient'] is not None
|
|
93
|
+
and em['indicator-is-valid'] is True
|
|
94
|
+
and em['indicator-input-is-valid'] is True]
|
|
95
|
+
|
|
96
|
+
valid_input_requirements = all([
|
|
97
|
+
all([
|
|
98
|
+
em['indicator-is-valid'],
|
|
99
|
+
em['indicator-input-is-valid']
|
|
69
100
|
])
|
|
70
|
-
for
|
|
71
|
-
if emission.get('term', {}).get('@id') in LOOKUPS[TermTermType.WASTE.value]
|
|
101
|
+
for em in emissions_unpacked
|
|
72
102
|
])
|
|
73
|
-
emissions_per_input = reduce(
|
|
74
|
-
lambda p, c: p | {c.get('input').get('@id'): p.get(c.get('input').get('@id'), []) + [c]},
|
|
75
|
-
emissions,
|
|
76
|
-
{}
|
|
77
|
-
)
|
|
78
103
|
|
|
79
|
-
|
|
80
|
-
|
|
104
|
+
all_emissions_have_known_cf = all([em['coefficient'] is not None for em in emissions_unpacked]) and bool(
|
|
105
|
+
emissions_unpacked)
|
|
106
|
+
|
|
107
|
+
logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
|
|
108
|
+
has_emissions=has_emissions,
|
|
109
|
+
valid_input_requirements=valid_input_requirements,
|
|
110
|
+
all_emissions_have_known_CF=all_emissions_have_known_cf,
|
|
111
|
+
emissions=log_as_table(emissions_unpacked)
|
|
112
|
+
)
|
|
81
113
|
|
|
82
|
-
should_run =
|
|
114
|
+
should_run = valid_input_requirements
|
|
83
115
|
|
|
84
116
|
logShouldRun(impact_assessment, MODEL, TERM_ID, should_run)
|
|
85
|
-
return should_run,
|
|
117
|
+
return should_run, valid_emission_with_cf
|
|
86
118
|
|
|
87
119
|
|
|
88
120
|
def run(impact_assessment: dict):
|
|
89
|
-
should_run,
|
|
90
|
-
return
|
|
121
|
+
should_run, emissions = _should_run(impact_assessment)
|
|
122
|
+
return _run(emissions) if should_run else []
|