hestia-earth-models 0.67.1__py3-none-any.whl → 0.68.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/aware/scarcityWeightedWaterUse.py +5 -6
- hestia_earth/models/blonkConsultants2016/ch4ToAirNaturalVegetationBurning.py +1 -1
- hestia_earth/models/blonkConsultants2016/co2ToAirAboveGroundBiomassStockChangeLandUseChange.py +1 -1
- hestia_earth/models/blonkConsultants2016/n2OToAirNaturalVegetationBurningDirect.py +1 -1
- hestia_earth/models/blonkConsultants2016/utils.py +9 -9
- hestia_earth/models/cache_sites.py +44 -23
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandOccupation.py +2 -2
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandTransformation.py +2 -2
- hestia_earth/models/chaudharyBrooks2018/utils.py +13 -8
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +2 -3
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +1 -1
- hestia_earth/models/config/Cycle.json +15 -0
- hestia_earth/models/config/ImpactAssessment.json +14 -1
- hestia_earth/models/config/Site.json +8 -0
- hestia_earth/models/cycle/excretaKgMass.py +2 -2
- hestia_earth/models/cycle/materialAndSubstrate.py +3 -2
- hestia_earth/models/cycle/pastureGrass.py +3 -3
- hestia_earth/models/dammgen2009/noxToAirExcreta.py +1 -1
- hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +1 -1
- hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +2 -6
- hestia_earth/models/emissionNotRelevant/__init__.py +4 -4
- hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +30 -21
- hestia_earth/models/environmentalFootprintV3_1/photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +36 -0
- hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +2 -2
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +9 -8
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +25 -22
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexTotalLandUseEffects.py +7 -6
- hestia_earth/models/faostat2018/coldCarcassWeightPerHead.py +2 -2
- hestia_earth/models/faostat2018/coldDressedCarcassWeightPerHead.py +2 -2
- hestia_earth/models/faostat2018/liveweightPerHead.py +7 -8
- hestia_earth/models/faostat2018/product/price.py +34 -28
- hestia_earth/models/faostat2018/readyToCookWeightPerHead.py +2 -2
- hestia_earth/models/faostat2018/utils.py +15 -27
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +16 -9
- hestia_earth/models/geospatialDatabase/altitude.py +60 -0
- hestia_earth/models/geospatialDatabase/croppingIntensity.py +1 -1
- hestia_earth/models/geospatialDatabase/ecoClimateZone.py +2 -2
- hestia_earth/models/geospatialDatabase/longFallowRatio.py +1 -1
- hestia_earth/models/geospatialDatabase/utils.py +4 -1
- hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +2 -3
- hestia_earth/models/haversineFormula/transport/distance.py +3 -3
- hestia_earth/models/hestia/landCover.py +72 -45
- hestia_earth/models/hestia/seed_emissions.py +11 -7
- hestia_earth/models/impact_assessment/__init__.py +3 -3
- hestia_earth/models/ipcc2019/animal/fatContent.py +1 -1
- hestia_earth/models/ipcc2019/animal/hoursWorkedPerDay.py +1 -1
- hestia_earth/models/ipcc2019/animal/liveweightGain.py +1 -1
- hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +1 -1
- hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +1 -1
- hestia_earth/models/ipcc2019/animal/pastureGrass.py +1 -1
- hestia_earth/models/ipcc2019/animal/pregnancyRateTotal.py +1 -1
- hestia_earth/models/ipcc2019/animal/trueProteinContent.py +1 -1
- hestia_earth/models/ipcc2019/animal/utils.py +5 -7
- hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +1 -1
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +2 -2
- hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +6 -7
- hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +5 -3
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +1 -1
- hestia_earth/models/ipcc2019/croppingDuration.py +3 -6
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +947 -0
- hestia_earth/models/ipcc2019/pastureGrass.py +1 -1
- hestia_earth/models/koble2014/residueBurnt.py +5 -7
- hestia_earth/models/koble2014/residueRemoved.py +5 -7
- hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/log.py +1 -1
- hestia_earth/models/mocking/search-results.json +3397 -1097
- hestia_earth/models/site/management.py +1 -1
- hestia_earth/models/site/post_checks/__init__.py +3 -2
- hestia_earth/models/site/post_checks/country.py +9 -0
- hestia_earth/models/site/pre_checks/__init__.py +3 -2
- hestia_earth/models/site/pre_checks/country.py +9 -0
- hestia_earth/models/site/soilMeasurement.py +2 -0
- hestia_earth/models/utils/__init__.py +1 -16
- hestia_earth/models/utils/blank_node.py +25 -25
- hestia_earth/models/utils/completeness.py +3 -2
- hestia_earth/models/utils/cycle.py +5 -4
- hestia_earth/models/utils/emission.py +5 -5
- hestia_earth/models/utils/feedipedia.py +6 -6
- hestia_earth/models/utils/impact_assessment.py +1 -2
- hestia_earth/models/utils/indicator.py +9 -7
- hestia_earth/models/utils/inorganicFertiliser.py +4 -6
- hestia_earth/models/utils/input.py +6 -5
- hestia_earth/models/utils/lookup.py +32 -100
- hestia_earth/models/utils/management.py +4 -4
- hestia_earth/models/utils/measurement.py +7 -8
- hestia_earth/models/utils/method.py +20 -0
- hestia_earth/models/utils/practice.py +4 -5
- hestia_earth/models/utils/product.py +4 -5
- hestia_earth/models/utils/property.py +12 -22
- hestia_earth/models/utils/site.py +14 -8
- hestia_earth/models/utils/term.py +27 -1
- hestia_earth/models/version.py +1 -1
- hestia_earth/orchestrator/log.py +0 -11
- hestia_earth/orchestrator/models/__init__.py +17 -4
- hestia_earth/orchestrator/strategies/run/add_blank_node_if_missing.py +2 -20
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/RECORD +146 -138
- tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +3 -3
- tests/models/cml2001Baseline/test_resourceUseEnergyDepletionDuringCycle.py +1 -1
- tests/models/cycle/test_coldCarcassWeightPerHead.py +1 -1
- tests/models/cycle/test_coldDressedCarcassWeightPerHead.py +1 -1
- tests/models/cycle/test_concentrateFeed.py +1 -1
- tests/models/cycle/test_energyContentLowerHeatingValue.py +1 -1
- tests/models/cycle/test_excretaKgMass.py +1 -1
- tests/models/cycle/test_feedConversionRatio.py +3 -3
- tests/models/cycle/test_pastureGrass.py +1 -1
- tests/models/cycle/test_readyToCookWeightPerHead.py +1 -1
- tests/models/environmentalFootprintV3_1/test_photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +30 -0
- tests/models/environmentalFootprintV3_1/test_soilQualityIndexTotalLandUseEffects.py +30 -7
- tests/models/faostat2018/product/test_price.py +27 -14
- tests/models/faostat2018/test_faostat_utils.py +4 -24
- tests/models/faostat2018/test_liveweightPerHead.py +9 -9
- tests/models/globalCropWaterModel2008/test_rootingDepth.py +7 -3
- tests/models/haversineFormula/transport/test_distance.py +1 -1
- tests/models/hestia/test_landCover.py +53 -5
- tests/models/ipcc2019/animal/test_pastureGrass.py +5 -3
- tests/models/ipcc2019/test_aboveGroundCropResidueTotal.py +4 -4
- tests/models/ipcc2019/test_belowGroundCropResidue.py +4 -4
- tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +10 -10
- tests/models/ipcc2019/test_croppingDuration.py +1 -1
- tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +83 -0
- tests/models/ipcc2019/test_organicCarbonPerHa.py +12 -12
- tests/models/ipcc2019/test_pastureGrass.py +5 -3
- tests/models/pooreNemecek2018/test_excretaKgN.py +5 -5
- tests/models/pooreNemecek2018/test_excretaKgVs.py +2 -2
- tests/models/site/post_checks/test_country.py +6 -0
- tests/models/site/pre_checks/test_cache_geospatialDatabase.py +1 -1
- tests/models/site/pre_checks/test_country.py +12 -0
- tests/models/test_ecoinventV3.py +7 -3
- tests/models/utils/test_blank_node.py +4 -12
- tests/models/utils/test_dataCompleteness.py +5 -5
- tests/models/utils/test_emission.py +2 -2
- tests/models/utils/test_indicator.py +2 -2
- tests/models/utils/test_input.py +2 -2
- tests/models/utils/test_measurement.py +2 -4
- tests/models/utils/test_practice.py +4 -2
- tests/models/utils/test_product.py +2 -2
- tests/models/utils/test_property.py +4 -2
- tests/models/utils/test_site.py +7 -0
- tests/orchestrator/strategies/run/test_add_blank_node_if_missing.py +4 -9
- hestia_earth/models/environmentalFootprintV3_1/utils.py +0 -17
- tests/models/utils/test_lookup.py +0 -10
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
2
|
+
from hestia_earth.models.utils.impact_assessment import impact_emission_lookup_value
|
3
|
+
from hestia_earth.models.utils.indicator import _new_indicator
|
4
|
+
from . import MODEL
|
5
|
+
|
6
|
+
REQUIREMENTS = {
|
7
|
+
"ImpactAssessment": {
|
8
|
+
"emissionsResourceUse": [
|
9
|
+
{"@type": "Indicator", "value": "", "term.termType": "emission"}
|
10
|
+
]
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
RETURNS = {
|
15
|
+
"Indicator": {
|
16
|
+
"value": ""
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
LOOKUPS = {
|
21
|
+
"emission": "nmvocEqPhotochemicalOzoneFormationEnvironmentalFootprintV3-1"
|
22
|
+
}
|
23
|
+
TERM_ID = 'photochemicalOzoneCreationPotentialHumanHealthNmvocEq'
|
24
|
+
|
25
|
+
|
26
|
+
def _indicator(value: float):
|
27
|
+
indicator = _new_indicator(TERM_ID, MODEL)
|
28
|
+
indicator["value"] = value
|
29
|
+
return indicator
|
30
|
+
|
31
|
+
|
32
|
+
def run(impact_assessment: dict):
|
33
|
+
value = impact_emission_lookup_value(MODEL, TERM_ID, impact_assessment, LOOKUPS["emission"])
|
34
|
+
logRequirements(impact_assessment, model=MODEL, term=TERM_ID, value=value)
|
35
|
+
logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
|
36
|
+
return _indicator(value) if value is not None else None
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
2
|
+
from hestia_earth.models.utils.impact_assessment import impact_country_value
|
3
|
+
from hestia_earth.models.utils.indicator import _new_indicator
|
2
4
|
from . import MODEL
|
3
|
-
from ..utils.impact_assessment import impact_country_value
|
4
|
-
from ..utils.indicator import _new_indicator
|
5
5
|
|
6
6
|
REQUIREMENTS = {
|
7
7
|
"ImpactAssessment": {
|
@@ -7,16 +7,14 @@ Factors version 2.5 (Horn and Meier, 2018).
|
|
7
7
|
from typing import Tuple
|
8
8
|
|
9
9
|
from hestia_earth.schema import TermTermType
|
10
|
-
from hestia_earth.utils.lookup import download_lookup
|
11
10
|
from hestia_earth.utils.model import filter_list_term_type
|
12
11
|
from hestia_earth.utils.tools import list_sum
|
13
12
|
|
14
13
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
15
14
|
from hestia_earth.models.utils.indicator import _new_indicator
|
16
15
|
from hestia_earth.models.utils.landCover import get_pef_grouping
|
17
|
-
from hestia_earth.models.utils.lookup import fallback_country, _node_value
|
16
|
+
from hestia_earth.models.utils.lookup import fallback_country, _node_value, get_region_lookup_value
|
18
17
|
from . import MODEL
|
19
|
-
from .utils import get_coefficient_factor
|
20
18
|
from ..utils.impact_assessment import get_country_id
|
21
19
|
|
22
20
|
REQUIREMENTS = {
|
@@ -75,16 +73,19 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
|
|
75
73
|
'area-by-year-is-valid': _node_value(land_occupation_indicator) is not None and _node_value(
|
76
74
|
land_occupation_indicator) > 0,
|
77
75
|
'area-unit-is-valid': land_occupation_indicator.get('term', {}).get("units") == "m2*year",
|
78
|
-
'used-country': fallback_country(get_country_id(impact_assessment), [
|
76
|
+
'used-country': fallback_country(get_country_id(impact_assessment), [LOOKUP]),
|
77
|
+
'pef-grouping': get_pef_grouping(land_occupation_indicator.get('landCover', {}).get("@id"))
|
79
78
|
|
80
79
|
} for land_occupation_indicator in land_occupation_indicators]
|
81
80
|
|
82
81
|
found_indicators_with_coefficient = [
|
83
82
|
indicator | {
|
84
|
-
'coefficient':
|
85
|
-
|
86
|
-
|
87
|
-
|
83
|
+
'coefficient': get_region_lookup_value(
|
84
|
+
model=MODEL,
|
85
|
+
term=TERM_ID,
|
86
|
+
lookup_name=LOOKUP,
|
87
|
+
term_id=indicator['used-country'],
|
88
|
+
column=indicator['pef-grouping']
|
88
89
|
),
|
89
90
|
"using-fallback-country-region-world-CFs": indicator['used-country'] != indicator['country-id']
|
90
91
|
} for indicator in found_land_occupation_indicators
|
@@ -7,17 +7,15 @@ Factors version 2.5 (Horn and Meier, 2018).
|
|
7
7
|
from typing import List, Tuple
|
8
8
|
|
9
9
|
from hestia_earth.schema import TermTermType
|
10
|
-
from hestia_earth.utils.lookup import download_lookup
|
11
10
|
from hestia_earth.utils.model import filter_list_term_type, find_term_match
|
12
11
|
from hestia_earth.utils.tools import list_sum
|
13
12
|
|
14
13
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
14
|
+
from hestia_earth.models.utils.impact_assessment import get_country_id
|
15
|
+
from hestia_earth.models.utils.indicator import _new_indicator
|
16
|
+
from hestia_earth.models.utils.landCover import get_pef_grouping
|
17
|
+
from hestia_earth.models.utils.lookup import fallback_country, _node_value, get_region_lookup_value
|
15
18
|
from . import MODEL
|
16
|
-
from .utils import get_coefficient_factor
|
17
|
-
from ..utils.impact_assessment import get_country_id
|
18
|
-
from ..utils.indicator import _new_indicator
|
19
|
-
from ..utils.landCover import get_pef_grouping
|
20
|
-
from ..utils.lookup import fallback_country, _node_value
|
21
19
|
|
22
20
|
REQUIREMENTS = {
|
23
21
|
"ImpactAssessment": {
|
@@ -50,8 +48,8 @@ REQUIREMENTS = {
|
|
50
48
|
# Note: CFs in `region-pefTermGrouping-landTransformation-from.csv` appear to be the opposite values as those in
|
51
49
|
# `region-pefTermGrouping-landTransformation-to.csv` but can be different in some cases.
|
52
50
|
LOOKUPS = {
|
53
|
-
"region-pefTermGrouping-landTransformation-from": "
|
54
|
-
"region-pefTermGrouping-landTransformation-to": "
|
51
|
+
"region-pefTermGrouping-landTransformation-from": "",
|
52
|
+
"region-pefTermGrouping-landTransformation-to": "",
|
55
53
|
"landCover": "pefTermGrouping"
|
56
54
|
}
|
57
55
|
|
@@ -104,30 +102,35 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
|
|
104
102
|
'land-cover-id-from': transformation_indicator.get('previousLandCover', {}).get("@id"),
|
105
103
|
'land-cover-id-to': transformation_indicator.get('landCover', {}).get("@id"),
|
106
104
|
'indicator-id': transformation_indicator.get('term', {}).get('@id', ''),
|
107
|
-
'good-land-cover-term': all([
|
108
|
-
|
105
|
+
'good-land-cover-term': all([
|
106
|
+
bool(transformation_indicator.get('landCover')),
|
107
|
+
bool(transformation_indicator.get('previousLandCover'))
|
108
|
+
]),
|
109
109
|
'country-id': get_country_id(impact_assessment),
|
110
|
-
'value-is-valid': (
|
111
|
-
|
112
|
-
|
113
|
-
|
110
|
+
'value-is-valid': (
|
111
|
+
_node_value(transformation_indicator) is not None and
|
112
|
+
_node_value(transformation_indicator) >= 0
|
113
|
+
),
|
114
|
+
'lookup-country': fallback_country(get_country_id(impact_assessment), [from_lookup_file, to_lookup_file]),
|
114
115
|
} for transformation_indicator in resource_uses
|
115
116
|
]
|
116
117
|
|
117
118
|
found_transformations_with_coefficient = [
|
118
119
|
transformation | {
|
119
120
|
'using-fallback-country-region-world-CFs': transformation['lookup-country'] != transformation['country-id'],
|
120
|
-
'factor-from':
|
121
|
+
'factor-from': get_region_lookup_value(
|
122
|
+
model=MODEL,
|
123
|
+
term=TERM_ID,
|
121
124
|
lookup_name=from_lookup_file,
|
122
|
-
|
123
|
-
|
124
|
-
occupation_type=get_pef_grouping(transformation['land-cover-id-from'])) if
|
125
|
+
term_id=transformation['lookup-country'],
|
126
|
+
column=get_pef_grouping(transformation['land-cover-id-from'])) if
|
125
127
|
transformation['land-cover-id-from'] else None,
|
126
|
-
'factor-to':
|
128
|
+
'factor-to': get_region_lookup_value(
|
129
|
+
model=MODEL,
|
130
|
+
term=TERM_ID,
|
127
131
|
lookup_name=to_lookup_file,
|
128
|
-
|
129
|
-
|
130
|
-
occupation_type=get_pef_grouping(transformation['land-cover-id-to'])) if
|
132
|
+
term_id=transformation['lookup-country'],
|
133
|
+
column=get_pef_grouping(transformation['land-cover-id-to'])) if
|
131
134
|
transformation['land-cover-id-to'] else None
|
132
135
|
} for transformation in found_transformations
|
133
136
|
]
|
@@ -4,7 +4,8 @@ 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 hestia_earth.
|
7
|
+
from hestia_earth.schema import TermTermType
|
8
|
+
from hestia_earth.utils.model import find_term_match, filter_list_term_type
|
8
9
|
from hestia_earth.utils.tools import list_sum
|
9
10
|
|
10
11
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
@@ -13,7 +14,7 @@ from ..utils.indicator import _new_indicator
|
|
13
14
|
|
14
15
|
REQUIREMENTS = {
|
15
16
|
"ImpactAssessment": {
|
16
|
-
"
|
17
|
+
"impacts": [
|
17
18
|
{"@type": "Indicator", "value": "", "term.@id": "soilQualityIndexLandOccupation"},
|
18
19
|
{"@type": "Indicator", "value": "", "term.@id": "soilQualityIndexLandTransformation"}
|
19
20
|
]
|
@@ -32,19 +33,19 @@ TERM_ID = 'soilQualityIndexTotalLandUseEffects'
|
|
32
33
|
|
33
34
|
def _indicator(value: float):
|
34
35
|
indicator = _new_indicator(TERM_ID, MODEL)
|
35
|
-
indicator[
|
36
|
+
indicator["value"] = value
|
36
37
|
return indicator
|
37
38
|
|
38
39
|
|
39
40
|
def _run(indicators: list):
|
40
|
-
values = [indicator[
|
41
|
+
values = [indicator["value"] for indicator in indicators]
|
41
42
|
return _indicator(list_sum(values))
|
42
43
|
|
43
44
|
|
44
45
|
def _should_run(impactassessment: dict) -> tuple[bool, list]:
|
45
46
|
soil_quality_indicators = [
|
46
|
-
i for i in impactassessment.get(
|
47
|
-
i.get(
|
47
|
+
i for i in filter_list_term_type(impactassessment.get("impacts", []), TermTermType.CHARACTERISEDINDICATOR) if
|
48
|
+
i.get("term", {}).get("@id", "") in ["soilQualityIndexLandOccupation", "soilQualityIndexLandTransformation"]
|
48
49
|
]
|
49
50
|
has_soil_quality_indicators = bool(soil_quality_indicators)
|
50
51
|
|
@@ -22,8 +22,8 @@ REQUIREMENTS = {
|
|
22
22
|
}
|
23
23
|
}
|
24
24
|
LOOKUPS = {
|
25
|
-
"region-animalProduct-animalProductGroupingFAO-productionQuantity": "
|
26
|
-
"region-animalProduct-animalProductGroupingFAO-head": "
|
25
|
+
"region-animalProduct-animalProductGroupingFAO-productionQuantity": "",
|
26
|
+
"region-animalProduct-animalProductGroupingFAO-head": ""
|
27
27
|
}
|
28
28
|
RETURNS = {
|
29
29
|
"Product": [{
|
@@ -25,8 +25,8 @@ REQUIREMENTS = {
|
|
25
25
|
}
|
26
26
|
}
|
27
27
|
LOOKUPS = {
|
28
|
-
"region-animalProduct-animalProductGroupingFAO-productionQuantity": "
|
29
|
-
"region-animalProduct-animalProductGroupingFAO-head": "
|
28
|
+
"region-animalProduct-animalProductGroupingFAO-productionQuantity": "",
|
29
|
+
"region-animalProduct-animalProductGroupingFAO-head": ""
|
30
30
|
}
|
31
31
|
RETURNS = {
|
32
32
|
"Product": [{
|
@@ -1,14 +1,15 @@
|
|
1
1
|
from hestia_earth.schema import TermTermType
|
2
|
-
from hestia_earth.utils.
|
3
|
-
from hestia_earth.utils.lookup import get_table_value, column_name, download_lookup, extract_grouped_data_closest_date
|
2
|
+
from hestia_earth.utils.lookup import extract_grouped_data_closest_date
|
4
3
|
from hestia_earth.utils.model import filter_list_term_type
|
5
4
|
from hestia_earth.utils.tools import non_empty_list, safe_parse_date, safe_parse_float
|
6
5
|
|
7
|
-
from hestia_earth.models.log import logRequirements, logShouldRun
|
6
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
8
7
|
from hestia_earth.models.utils.constant import Units
|
8
|
+
from hestia_earth.models.utils.term import download_term
|
9
9
|
from hestia_earth.models.utils.property import _new_property, node_has_no_property
|
10
10
|
from hestia_earth.models.utils.product import convert_product_to_unit
|
11
11
|
from hestia_earth.models.utils.animalProduct import FAO_LOOKUP_COLUMN, get_animalProduct_lookup_value
|
12
|
+
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
12
13
|
from .utils import get_liveAnimal_to_animalProduct_id
|
13
14
|
from . import MODEL
|
14
15
|
|
@@ -29,7 +30,7 @@ REQUIREMENTS = {
|
|
29
30
|
LOOKUPS = {
|
30
31
|
"liveAnimal": ["primaryMeatProductFaoProductionTermId"],
|
31
32
|
"animalProduct": ["animalProductGroupingFAOEquivalent", "animalProductGroupingFAO"],
|
32
|
-
"region-animalProduct-animalProductGroupingFAO-averageColdCarcassWeight": "
|
33
|
+
"region-animalProduct-animalProductGroupingFAO-averageColdCarcassWeight": ""
|
33
34
|
}
|
34
35
|
RETURNS = {
|
35
36
|
"Product": [{
|
@@ -53,9 +54,7 @@ def _product_value(product: dict, year: int, country_id: str):
|
|
53
54
|
product_id = product.get('term', {}).get('@id')
|
54
55
|
groupingFAO = get_animalProduct_lookup_value(MODEL, product_id, FAO_LOOKUP_COLUMN)
|
55
56
|
|
56
|
-
|
57
|
-
data = get_table_value(lookup, 'termid', country_id, column_name(groupingFAO))
|
58
|
-
debugMissingLookup(LOOKUP_WEIGHT, 'termid', country_id, groupingFAO, data, model=MODEL, term=TERM_ID)
|
57
|
+
data = get_region_lookup_value(LOOKUP_WEIGHT, country_id, groupingFAO, model=MODEL, term=TERM_ID)
|
59
58
|
average_carcass_weight = safe_parse_float(extract_grouped_data_closest_date(data, year), None)
|
60
59
|
# average_carcass_weight is in hg, divide by 10 to go back to kg
|
61
60
|
kg_carcass_weight = average_carcass_weight / 10 if average_carcass_weight else None
|
@@ -77,7 +76,7 @@ def _run_liveAnimal(cycle: dict, product: dict, year: int, country_id: str):
|
|
77
76
|
product_id = product.get('term', {}).get('@id')
|
78
77
|
animal_product_id = get_liveAnimal_to_animalProduct_id(product_id, LOOKUPS['liveAnimal'][0], term=TERM_ID)
|
79
78
|
|
80
|
-
animal_product_term =
|
79
|
+
animal_product_term = download_term(animal_product_id, TermTermType.ANIMALPRODUCT) if animal_product_id else {}
|
81
80
|
kg_liveweight, groupingFAO = _product_value({**product, 'term': animal_product_term}, year, country_id)
|
82
81
|
|
83
82
|
logRequirements(cycle, model=MODEL, term=product_id, property=TERM_ID,
|
@@ -4,16 +4,17 @@ Product Price
|
|
4
4
|
Calculates the price of `crop` and `liveAnimal` using FAOSTAT data.
|
5
5
|
"""
|
6
6
|
from hestia_earth.schema import TermTermType
|
7
|
-
from hestia_earth.utils.
|
8
|
-
from hestia_earth.utils.lookup import get_table_value, column_name, download_lookup, extract_grouped_data
|
7
|
+
from hestia_earth.utils.lookup import extract_grouped_data
|
9
8
|
from hestia_earth.utils.tools import non_empty_list, safe_parse_float, safe_parse_date
|
10
9
|
|
11
|
-
from hestia_earth.models.log import
|
10
|
+
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
12
11
|
from hestia_earth.models.utils.constant import Units
|
12
|
+
from hestia_earth.models.utils.term import download_term
|
13
13
|
from hestia_earth.models.utils.currency import DEFAULT_CURRENCY
|
14
14
|
from hestia_earth.models.utils.crop import FAOSTAT_PRODUCTION_LOOKUP_COLUMN, get_crop_grouping_faostat_production
|
15
15
|
from hestia_earth.models.utils.animalProduct import FAO_LOOKUP_COLUMN, get_animalProduct_grouping_fao
|
16
16
|
from hestia_earth.models.utils.product import convert_product_to_unit
|
17
|
+
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
17
18
|
from ..utils import get_liveAnimal_to_animalProduct_id
|
18
19
|
from .. import MODEL
|
19
20
|
|
@@ -37,12 +38,12 @@ RETURNS = {
|
|
37
38
|
LOOKUPS = {
|
38
39
|
"@doc": "Depending on the primary product [termType](https://hestia.earth/schema/Product#term)",
|
39
40
|
"crop": "cropGroupingFaostatProduction",
|
40
|
-
"region-crop-cropGroupingFaostatProduction-price": "
|
41
|
+
"region-crop-cropGroupingFaostatProduction-price": "",
|
41
42
|
"liveAnimal": ["primaryMeatProductFaoPriceTermId"],
|
42
43
|
"animalProduct": ["animalProductGroupingFAOEquivalent", "animalProductGroupingFAO"],
|
43
|
-
"region-animalProduct-animalProductGroupingFAO-price": "
|
44
|
-
"region-animalProduct-animalProductGroupingFAO-averageColdCarcassWeight": "
|
45
|
-
"region-animalProduct-animalProductGroupingFAO-weightPerItem": "
|
44
|
+
"region-animalProduct-animalProductGroupingFAO-price": "",
|
45
|
+
"region-animalProduct-animalProductGroupingFAO-averageColdCarcassWeight": "",
|
46
|
+
"region-animalProduct-animalProductGroupingFAO-weightPerItem": ""
|
46
47
|
}
|
47
48
|
MODEL_KEY = 'price'
|
48
49
|
LOOKUP_NAME = {
|
@@ -62,14 +63,19 @@ def _term_grouping(term: dict): return LOOKUP_GROUPING.get(term.get('termType'),
|
|
62
63
|
|
63
64
|
|
64
65
|
def _lookup_data(
|
65
|
-
term_id: str, grouping: str,
|
66
|
+
term_id: str, grouping: str, country: dict, year: int, term_type: str = None, lookup_name: str = None
|
66
67
|
):
|
67
|
-
lookup_name = lookup_name or LOOKUP_NAME.get(term_type)
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
lookup_name = lookup_name or LOOKUP_NAME.get(term_type, '')
|
69
|
+
|
70
|
+
def get_data(country_id):
|
71
|
+
data = get_region_lookup_value(lookup_name, country_id, grouping, model=MODEL, term=term_id, key=MODEL_KEY)
|
72
|
+
price = extract_grouped_data(data, str(year)) or extract_grouped_data(data, 'Average_price_per_tonne')
|
73
|
+
return safe_parse_float(price, None)
|
74
|
+
|
75
|
+
# try get country data first, falls back to region data
|
76
|
+
country_id = country.get('@id')
|
77
|
+
region_id = (country.get('subClassOf') or [{}])[0].get('@id')
|
78
|
+
return get_data(country_id) or (get_data(region_id) if region_id else None)
|
73
79
|
|
74
80
|
|
75
81
|
def _product(product: dict, value: float):
|
@@ -77,7 +83,7 @@ def _product(product: dict, value: float):
|
|
77
83
|
return product | {'currency': DEFAULT_CURRENCY, MODEL_KEY: round(value, 4)}
|
78
84
|
|
79
85
|
|
80
|
-
def _get_liveAnimal_lookup_values(cycle: dict, product: dict,
|
86
|
+
def _get_liveAnimal_lookup_values(cycle: dict, product: dict, country: dict, year: int = None):
|
81
87
|
term_id = product.get('term', {}).get('@id')
|
82
88
|
animal_product = get_liveAnimal_to_animalProduct_id(term_id, LOOKUPS['liveAnimal'][0], key=MODEL_KEY)
|
83
89
|
groupingFAO = _term_grouping({'termType': TermTermType.ANIMALPRODUCT.value, '@id': animal_product})
|
@@ -85,7 +91,7 @@ def _get_liveAnimal_lookup_values(cycle: dict, product: dict, country_id: str, y
|
|
85
91
|
# one live animal can be linked to many animal product, hence go one by one until we have a match
|
86
92
|
if groupingFAO:
|
87
93
|
price_per_ton_liveweight = _lookup_data(
|
88
|
-
term_id, groupingFAO,
|
94
|
+
term_id, groupingFAO, country, year, term_type=TermTermType.ANIMALPRODUCT.value
|
89
95
|
)
|
90
96
|
debugValues(cycle, model=MODEL, term=term_id, key=MODEL_KEY, by='liveAnimal',
|
91
97
|
animal_product=animal_product,
|
@@ -97,11 +103,11 @@ def _get_liveAnimal_lookup_values(cycle: dict, product: dict, country_id: str, y
|
|
97
103
|
return (None, None)
|
98
104
|
|
99
105
|
|
100
|
-
def _run_by_liveAnimal(cycle: dict, product: dict,
|
106
|
+
def _run_by_liveAnimal(cycle: dict, product: dict, country: dict, year: int = None):
|
101
107
|
term_id = product.get('term', {}).get('@id')
|
102
|
-
animal_product_id, price_per_kg_liveweight = _get_liveAnimal_lookup_values(cycle, product,
|
108
|
+
animal_product_id, price_per_kg_liveweight = _get_liveAnimal_lookup_values(cycle, product, country, year)
|
103
109
|
|
104
|
-
animal_product =
|
110
|
+
animal_product = download_term(animal_product_id, TermTermType.ANIMALPRODUCT)
|
105
111
|
price_per_head = convert_product_to_unit({
|
106
112
|
**product,
|
107
113
|
'term': animal_product,
|
@@ -123,7 +129,7 @@ def _should_run_liveAnimal(product: dict):
|
|
123
129
|
return product.get('term', {}).get('termType') == TermTermType.LIVEANIMAL.value
|
124
130
|
|
125
131
|
|
126
|
-
def _run_by_country(cycle: dict, product: dict,
|
132
|
+
def _run_by_country(cycle: dict, product: dict, country: dict, year: int = None):
|
127
133
|
product_term = product.get('term', {})
|
128
134
|
term_id = product_term.get('@id')
|
129
135
|
term_type = product_term.get('termType')
|
@@ -136,12 +142,12 @@ def _run_by_country(cycle: dict, product: dict, country_id: str, year: int = Non
|
|
136
142
|
grouping = _term_grouping(product_term) or None
|
137
143
|
|
138
144
|
should_run = all([not_already_set, has_yield, grouping])
|
139
|
-
value = _lookup_data(term_id, grouping,
|
145
|
+
value = _lookup_data(term_id, grouping, country, year, term_type=term_type) if should_run else None
|
140
146
|
|
141
147
|
# if units is number instead of kg, need to convert to number first
|
142
|
-
conversion_to_number = safe_parse_float(
|
143
|
-
|
144
|
-
)
|
148
|
+
conversion_to_number = safe_parse_float(
|
149
|
+
get_region_lookup_value(LOOKUP_UNITS_NUMBER.get(term_type), country.get('@id'), grouping), 1
|
150
|
+
) if term_units == Units.NUMBER.value else 1
|
145
151
|
|
146
152
|
logRequirements(cycle, model=MODEL, term=term_id, key=MODEL_KEY, by='country',
|
147
153
|
has_yield=has_yield,
|
@@ -161,7 +167,7 @@ def _should_run_product(product: dict): return product.get(MODEL_KEY) is None
|
|
161
167
|
|
162
168
|
|
163
169
|
def run(cycle: dict):
|
164
|
-
|
170
|
+
country = cycle.get('site', {}).get('country', {})
|
165
171
|
end_date = safe_parse_date(cycle.get('endDate'))
|
166
172
|
year = end_date.year if end_date else None
|
167
173
|
|
@@ -169,8 +175,8 @@ def run(cycle: dict):
|
|
169
175
|
return non_empty_list([
|
170
176
|
(
|
171
177
|
(
|
172
|
-
(_run_by_liveAnimal(cycle, p,
|
173
|
-
or _run_by_country(cycle, p,
|
174
|
-
) if
|
178
|
+
(_run_by_liveAnimal(cycle, p, country, year) if _should_run_liveAnimal(p) else None)
|
179
|
+
or _run_by_country(cycle, p, country, year)
|
180
|
+
) if country else None
|
175
181
|
) for p in products
|
176
182
|
])
|
@@ -22,8 +22,8 @@ REQUIREMENTS = {
|
|
22
22
|
}
|
23
23
|
}
|
24
24
|
LOOKUPS = {
|
25
|
-
"region-animalProduct-animalProductGroupingFAO-productionQuantity": "
|
26
|
-
"region-animalProduct-animalProductGroupingFAO-head": "
|
25
|
+
"region-animalProduct-animalProductGroupingFAO-productionQuantity": "",
|
26
|
+
"region-animalProduct-animalProductGroupingFAO-head": ""
|
27
27
|
}
|
28
28
|
RETURNS = {
|
29
29
|
"Product": [{
|
@@ -1,4 +1,3 @@
|
|
1
|
-
from numpy import recarray
|
2
1
|
from hestia_earth.schema import TermTermType
|
3
2
|
from hestia_earth.utils.api import download_hestia
|
4
3
|
from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name, extract_grouped_data_closest_date
|
@@ -11,9 +10,11 @@ from hestia_earth.models.utils.animalProduct import (
|
|
11
10
|
from hestia_earth.models.utils.product import convert_product_to_unit
|
12
11
|
from hestia_earth.models.utils.impact_assessment import get_country_id, impact_end_year
|
13
12
|
from hestia_earth.models.utils.indicator import _new_indicator
|
13
|
+
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
14
14
|
from . import MODEL
|
15
15
|
|
16
16
|
LOOKUP_PREFIX = f"{TermTermType.REGION.value}-{TermTermType.ANIMALPRODUCT.value}-{FAO_LOOKUP_COLUMN}"
|
17
|
+
FAOSTAT_AREA_LOOKUP = 'region-faostatArea.csv'
|
17
18
|
|
18
19
|
|
19
20
|
def get_liveAnimal_to_animalProduct_id(product_term_id: str, column: str, **log_args):
|
@@ -32,12 +33,10 @@ def product_equivalent_value(product: dict, year: int, country: str):
|
|
32
33
|
if not grouping or not fao_product_id:
|
33
34
|
return None
|
34
35
|
|
35
|
-
|
36
|
-
quantity_values = get_table_value(lookup, 'termid', country, column_name(grouping))
|
36
|
+
quantity_values = get_region_lookup_value(f"{LOOKUP_PREFIX}-productionQuantity.csv", country, grouping)
|
37
37
|
quantity = safe_parse_float(extract_grouped_data_closest_date(quantity_values, year))
|
38
38
|
|
39
|
-
|
40
|
-
head_values = get_table_value(lookup, 'termid', country, column_name(grouping))
|
39
|
+
head_values = get_region_lookup_value(f"{LOOKUP_PREFIX}-head.csv", country, grouping)
|
41
40
|
head = safe_parse_float(extract_grouped_data_closest_date(head_values, year))
|
42
41
|
|
43
42
|
# quantity is in Tonnes
|
@@ -64,11 +63,11 @@ def _split_delta(table_value: str, start_year: int, end_year: int):
|
|
64
63
|
]) else None
|
65
64
|
|
66
65
|
|
67
|
-
def get_sum_of_columns(
|
66
|
+
def get_sum_of_columns(country: str, year: int, columns_list: list) -> float:
|
68
67
|
return sum(
|
69
68
|
[safe_parse_float(
|
70
69
|
extract_grouped_data_closest_date(
|
71
|
-
data=
|
70
|
+
data=get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, col, model=MODEL),
|
72
71
|
year=year
|
73
72
|
)
|
74
73
|
) for col in columns_list]
|
@@ -76,9 +75,8 @@ def get_sum_of_columns(lookup: recarray, country: str, year: int, columns_list:
|
|
76
75
|
|
77
76
|
|
78
77
|
def get_single_delta(country: str, start_year: int, end_year: int, column: str):
|
79
|
-
lookup = download_lookup('region-faostatArea.csv')
|
80
78
|
return _split_delta(
|
81
|
-
|
79
|
+
get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, column, model=MODEL), start_year, end_year
|
82
80
|
)
|
83
81
|
|
84
82
|
|
@@ -88,27 +86,24 @@ def get_land_ratio(
|
|
88
86
|
"""
|
89
87
|
total_column is optional. Assumes that, if missing, total is the sum of values from first and second.
|
90
88
|
"""
|
91
|
-
lookup = download_lookup('region-faostatArea.csv')
|
92
89
|
first_delta = _split_delta(
|
93
|
-
|
90
|
+
get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, first_column, model=MODEL), start_year, end_year
|
94
91
|
)
|
95
92
|
second_delta = _split_delta(
|
96
|
-
|
93
|
+
get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, second_column, model=MODEL), start_year, end_year
|
97
94
|
)
|
98
95
|
total_delta = (
|
99
96
|
get_sum_of_columns(
|
100
|
-
lookup=lookup,
|
101
97
|
country=country,
|
102
98
|
year=end_year,
|
103
99
|
columns_list=[first_column, second_column]
|
104
100
|
) - get_sum_of_columns(
|
105
|
-
lookup=lookup,
|
106
101
|
country=country,
|
107
102
|
year=start_year,
|
108
103
|
columns_list=[first_column, second_column]
|
109
104
|
)
|
110
105
|
) if total_column is None else _split_delta(
|
111
|
-
|
106
|
+
get_region_lookup_value(FAOSTAT_AREA_LOOKUP, country, total_column, model=MODEL), start_year, end_year
|
112
107
|
)
|
113
108
|
|
114
109
|
return (None, None, None) if any([
|
@@ -130,18 +125,11 @@ def get_cropland_ratio(country: str, start_year: int, end_year: int):
|
|
130
125
|
|
131
126
|
|
132
127
|
def get_change_in_harvested_area_for_crop(country_id: str, crop_name: str, start_year: int, end_year: int = 0):
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
year=start_year
|
139
|
-
)
|
140
|
-
)
|
141
|
-
else:
|
142
|
-
return _split_delta(
|
143
|
-
get_table_value(lookup, 'termid', country_id, column_name(crop_name)), start_year, end_year
|
144
|
-
)
|
128
|
+
lookup_name = 'region-crop-cropGroupingFaostatProduction-areaHarvested.csv'
|
129
|
+
value = get_region_lookup_value(lookup_name, country_id, crop_name)
|
130
|
+
return safe_parse_float(
|
131
|
+
extract_grouped_data_closest_date(value, start_year)
|
132
|
+
) if end_year == 0 or end_year == start_year else _split_delta(value, start_year, end_year)
|
145
133
|
|
146
134
|
|
147
135
|
def should_run_landTransformationFromCropland(term_id: str, impact: dict):
|
@@ -63,9 +63,11 @@ def _run(emissions: list):
|
|
63
63
|
|
64
64
|
|
65
65
|
def _should_run(impact_assessment: dict):
|
66
|
-
emissions = [
|
67
|
-
|
68
|
-
|
66
|
+
emissions = [
|
67
|
+
emission
|
68
|
+
for emission in filter_list_term_type(impact_assessment.get('emissionsResourceUse', []), TermTermType.EMISSION)
|
69
|
+
if emission.get('term', {}).get('@id', '') in LOOKUPS[TermTermType.WASTE.value]
|
70
|
+
]
|
69
71
|
|
70
72
|
has_emissions = bool(emissions)
|
71
73
|
|
@@ -80,7 +82,7 @@ def _should_run(impact_assessment: dict):
|
|
80
82
|
"input": input,
|
81
83
|
"indicator-input-is-valid": _valid_waste(input),
|
82
84
|
"value": _node_value(emission),
|
83
|
-
"coefficient": get_table_value(
|
85
|
+
"coefficient": get_table_value(lookup=download_lookup(filename="waste.csv"),
|
84
86
|
col_match='termid',
|
85
87
|
col_match_with=input.get('@id'),
|
86
88
|
col_val=column_name(emission['term']['@id'])) if input else None
|
@@ -89,9 +91,13 @@ def _should_run(impact_assessment: dict):
|
|
89
91
|
]
|
90
92
|
)
|
91
93
|
|
92
|
-
valid_emission_with_cf = [
|
93
|
-
|
94
|
-
|
94
|
+
valid_emission_with_cf = [
|
95
|
+
em for em in emissions_unpacked if all([
|
96
|
+
em['coefficient'] is not None,
|
97
|
+
em['indicator-is-valid'] is True,
|
98
|
+
em['indicator-input-is-valid'] is True
|
99
|
+
])
|
100
|
+
]
|
95
101
|
|
96
102
|
valid_input_requirements = all([
|
97
103
|
all([
|
@@ -101,8 +107,9 @@ def _should_run(impact_assessment: dict):
|
|
101
107
|
for em in emissions_unpacked
|
102
108
|
])
|
103
109
|
|
104
|
-
all_emissions_have_known_cf = all([
|
105
|
-
emissions_unpacked
|
110
|
+
all_emissions_have_known_cf = all([
|
111
|
+
em['coefficient'] is not None for em in emissions_unpacked
|
112
|
+
]) and bool(emissions_unpacked)
|
106
113
|
|
107
114
|
logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
|
108
115
|
has_emissions=has_emissions,
|