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,60 @@
|
|
1
|
+
from hestia_earth.schema import MeasurementMethodClassification
|
2
|
+
from hestia_earth.utils.tools import safe_parse_float
|
3
|
+
|
4
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
5
|
+
from hestia_earth.models.utils.measurement import _new_measurement
|
6
|
+
from hestia_earth.models.utils.source import get_source
|
7
|
+
from .utils import download, has_geospatial_data, should_download
|
8
|
+
from . import MODEL
|
9
|
+
|
10
|
+
REQUIREMENTS = {
|
11
|
+
"Site": {
|
12
|
+
"or": [
|
13
|
+
{"latitude": "", "longitude": ""},
|
14
|
+
{"boundary": {}},
|
15
|
+
{"region": {"@type": "Term", "termType": "region"}}
|
16
|
+
]
|
17
|
+
}
|
18
|
+
}
|
19
|
+
RETURNS = {
|
20
|
+
"Measurement": [{
|
21
|
+
"value": "",
|
22
|
+
"methodClassification": "geospatial dataset"
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
TERM_ID = 'altitude'
|
26
|
+
EE_PARAMS = {
|
27
|
+
'collection': 'USGS/GMTED2010_FULL',
|
28
|
+
'ee_type': 'raster',
|
29
|
+
'band_name': 'med',
|
30
|
+
'is_image': True
|
31
|
+
}
|
32
|
+
BIBLIO_TITLE = 'An Enhanced Global Elevation Model Generalized From Multiple Higher Resolution Source Datasets'
|
33
|
+
|
34
|
+
|
35
|
+
def _measurement(site: dict, value: float):
|
36
|
+
measurement = _new_measurement(TERM_ID)
|
37
|
+
measurement['value'] = [value]
|
38
|
+
measurement['methodClassification'] = MeasurementMethodClassification.GEOSPATIAL_DATASET.value
|
39
|
+
return measurement | get_source(site, BIBLIO_TITLE)
|
40
|
+
|
41
|
+
|
42
|
+
def _run(site: dict):
|
43
|
+
value = download(TERM_ID, site, EE_PARAMS)
|
44
|
+
return [_measurement(site, safe_parse_float(value))] if value is not None else []
|
45
|
+
|
46
|
+
|
47
|
+
def _should_run(site: dict):
|
48
|
+
contains_geospatial_data = has_geospatial_data(site)
|
49
|
+
below_max_area_size = should_download(TERM_ID, site)
|
50
|
+
|
51
|
+
logRequirements(site, model=MODEL, term=TERM_ID,
|
52
|
+
contains_geospatial_data=contains_geospatial_data,
|
53
|
+
below_max_area_size=below_max_area_size)
|
54
|
+
|
55
|
+
should_run = all([contains_geospatial_data, below_max_area_size])
|
56
|
+
logShouldRun(site, MODEL, TERM_ID, should_run)
|
57
|
+
return should_run
|
58
|
+
|
59
|
+
|
60
|
+
def run(site: dict): return _run(site) if _should_run(site) else []
|
@@ -65,7 +65,7 @@ def _should_run(cycle: dict):
|
|
65
65
|
|
66
66
|
|
67
67
|
def run(cycle: dict):
|
68
|
-
sites = get_allowed_sites(MODEL, TERM_ID,
|
68
|
+
sites = get_allowed_sites(MODEL, TERM_ID, cycle) if _should_run(cycle) else []
|
69
69
|
sites = [
|
70
70
|
(site, get_region_factor(TERM_ID, site, TermTermType.LANDUSEMANAGEMENT)) for site in sites
|
71
71
|
]
|
@@ -79,7 +79,7 @@ def _run_default(site: dict):
|
|
79
79
|
region_factor=region_factor)
|
80
80
|
|
81
81
|
should_run = all([region_factor])
|
82
|
-
logShouldRun(site, MODEL, TERM_ID, should_run)
|
82
|
+
logShouldRun(site, MODEL, TERM_ID, should_run, run_by='Lookup')
|
83
83
|
return [_measurement(site, round(region_factor))] if should_run else []
|
84
84
|
|
85
85
|
|
@@ -92,7 +92,7 @@ def _should_run(site: dict):
|
|
92
92
|
below_max_area_size=below_max_area_size)
|
93
93
|
|
94
94
|
should_run = all([contains_geospatial_data, below_max_area_size])
|
95
|
-
logShouldRun(site, MODEL, TERM_ID, should_run)
|
95
|
+
logShouldRun(site, MODEL, TERM_ID, should_run, run_by='Earth Engine')
|
96
96
|
return should_run
|
97
97
|
|
98
98
|
|
@@ -65,7 +65,7 @@ def _should_run(cycle: dict):
|
|
65
65
|
|
66
66
|
|
67
67
|
def run(cycle: dict):
|
68
|
-
sites = get_allowed_sites(MODEL, TERM_ID,
|
68
|
+
sites = get_allowed_sites(MODEL, TERM_ID, cycle) if _should_run(cycle) else []
|
69
69
|
sites = [
|
70
70
|
(site, get_region_factor(TERM_ID, site, TermTermType.LANDUSEMANAGEMENT)) for site in sites
|
71
71
|
]
|
@@ -196,4 +196,7 @@ def download(term: str, site: dict, data: dict, only_coordinates=False) -> dict:
|
|
196
196
|
def get_region_factor(term_id: str, site: dict, termType: TermTermType = TermTermType.MEASUREMENT):
|
197
197
|
region_id = region_level_1_id(site.get('region', {}).get('@id'))
|
198
198
|
country_id = site.get('country', {}).get('@id')
|
199
|
-
return
|
199
|
+
return (
|
200
|
+
# `region-measurement` only exists for countries
|
201
|
+
region_factor(MODEL, region_id, term_id, termType) if termType != TermTermType.MEASUREMENT else None
|
202
|
+
) or region_factor(MODEL, country_id, term_id, termType)
|
@@ -1,11 +1,10 @@
|
|
1
1
|
from hestia_earth.schema import CycleFunctionalUnit, TermTermType
|
2
|
-
from hestia_earth.utils.api import download_hestia
|
3
2
|
from hestia_earth.utils.model import find_term_match, filter_list_term_type
|
4
3
|
from hestia_earth.utils.tools import list_sum, non_empty_list, safe_parse_float
|
5
4
|
|
6
5
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
7
6
|
from hestia_earth.models.utils.property import _new_property, node_has_no_property
|
8
|
-
from hestia_earth.models.utils.term import get_irrigation_terms
|
7
|
+
from hestia_earth.models.utils.term import get_irrigation_terms, download_term
|
9
8
|
from hestia_earth.models.utils.crop import get_crop_lookup_value
|
10
9
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
11
10
|
from . import MODEL
|
@@ -81,7 +80,7 @@ def _should_run_product(cycle: dict):
|
|
81
80
|
|
82
81
|
|
83
82
|
def _run_cycle(products: list):
|
84
|
-
term =
|
83
|
+
term = download_term(TERM_ID, TermTermType.PROPERTY)
|
85
84
|
|
86
85
|
def run_product(values: tuple):
|
87
86
|
product, value = values
|
@@ -10,7 +10,7 @@ from hestia_earth.utils.api import download_hestia
|
|
10
10
|
from hestia_earth.utils.tools import non_empty_list
|
11
11
|
|
12
12
|
from hestia_earth.models.log import logRequirements, logShouldRun, debugValues
|
13
|
-
from hestia_earth.models.utils import
|
13
|
+
from hestia_earth.models.utils.method import include_methodModel
|
14
14
|
from .. import MODEL
|
15
15
|
|
16
16
|
REQUIREMENTS = {
|
@@ -39,8 +39,8 @@ MODEL_KEY = 'distance'
|
|
39
39
|
|
40
40
|
def _run_transport(cycle: dict, distance_kms: float):
|
41
41
|
def exec(transport: dict):
|
42
|
-
return
|
43
|
-
|
42
|
+
return include_methodModel(transport | {
|
43
|
+
MODEL_KEY: distance_kms
|
44
44
|
}, MODEL) if _should_run_transport(cycle, transport) else transport
|
45
45
|
return exec
|
46
46
|
|
@@ -10,7 +10,7 @@ from datetime import datetime, timedelta
|
|
10
10
|
|
11
11
|
from hestia_earth.schema import SiteSiteType, TermTermType
|
12
12
|
from hestia_earth.utils.lookup import (
|
13
|
-
download_lookup, get_table_value, column_name, _is_missing_value, extract_grouped_data
|
13
|
+
download_lookup, get_table_value, column_name, _is_missing_value, extract_grouped_data, lookup_columns
|
14
14
|
)
|
15
15
|
from hestia_earth.utils.model import filter_list_term_type
|
16
16
|
from hestia_earth.utils.tools import safe_parse_float, to_precision
|
@@ -19,6 +19,7 @@ from hestia_earth.models.log import logRequirements, log_as_table, logShouldRun
|
|
19
19
|
from hestia_earth.models.utils.constant import DAYS_IN_YEAR
|
20
20
|
from hestia_earth.models.utils.management import _new_management
|
21
21
|
from hestia_earth.models.utils.term import get_lookup_value
|
22
|
+
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
22
23
|
from hestia_earth.models.utils.blank_node import _node_date, DatestrFormat, _gapfill_datestr, DatestrGapfillMode
|
23
24
|
from .utils import (
|
24
25
|
IPCC_LAND_USE_CATEGORY_ANNUAL,
|
@@ -71,9 +72,9 @@ RETURNS = {
|
|
71
72
|
}]
|
72
73
|
}
|
73
74
|
LOOKUPS = {
|
74
|
-
"region-crop-cropGroupingFaostatProduction-areaHarvestedUpTo20YearExpansion": "
|
75
|
-
"region-crop-cropGroupingFaostatProduction-areaHarvested": "
|
76
|
-
"region-faostatArea-UpTo20YearExpansion": "
|
75
|
+
"region-crop-cropGroupingFaostatProduction-areaHarvestedUpTo20YearExpansion": "",
|
76
|
+
"region-crop-cropGroupingFaostatProduction-areaHarvested": "",
|
77
|
+
"region-faostatArea-UpTo20YearExpansion": "",
|
77
78
|
"region-faostatArea": [
|
78
79
|
"Arable land",
|
79
80
|
"Cropland",
|
@@ -99,6 +100,7 @@ SITE_TYPES = {
|
|
99
100
|
DEFAULT_WINDOW_IN_YEARS = 20
|
100
101
|
DATE_TOLERANCE_IN_YEARS = 2
|
101
102
|
OUTPUT_SIGNIFICANT_DIGITS = 3
|
103
|
+
_LOOKUP_EXPANSION = "region-crop-cropGroupingFaostatProduction-areaHarvestedUpTo20YearExpansion.csv"
|
102
104
|
|
103
105
|
|
104
106
|
def _management(term_id: str, value: float, start_date: str, end_date: str):
|
@@ -117,10 +119,25 @@ def _safe_divide(numerator, denominator, default=0) -> float:
|
|
117
119
|
return default if not denominator else numerator / denominator
|
118
120
|
|
119
121
|
|
122
|
+
def scale_values_to_one(dictionary: dict) -> dict:
|
123
|
+
"""
|
124
|
+
Takes a dictionary with numeric values.
|
125
|
+
Scales each value so that the sum of them all is one.
|
126
|
+
"""
|
127
|
+
# Does not handle negative values.
|
128
|
+
sum_of_values = sum(dictionary.values())
|
129
|
+
return {key: value / sum_of_values for key, value in dictionary.items()} if sum_of_values != 0 else dictionary
|
130
|
+
|
131
|
+
|
132
|
+
def cap_values(dictionary: dict, lower_limit: float = 0, upper_limit: float = 1) -> dict:
|
133
|
+
return {key: min([upper_limit, max([lower_limit, value])]) for key, value in dictionary.items()}
|
134
|
+
|
135
|
+
|
120
136
|
def site_area_sum_to_100(dict_of_percentages: dict):
|
121
|
-
return False if dict_of_percentages == {} else
|
122
|
-
|
123
|
-
|
137
|
+
return False if dict_of_percentages == {} else (
|
138
|
+
math.isclose(sum(dict_of_percentages.values()), 1.0, rel_tol=0.01) or
|
139
|
+
math.isclose(sum(dict_of_percentages.values()), 0.0, rel_tol=0.01)
|
140
|
+
)
|
124
141
|
|
125
142
|
|
126
143
|
def _should_group_landCover(term: dict):
|
@@ -134,12 +151,13 @@ def get_changes(country_id: str, end_year: int) -> tuple[dict, bool]:
|
|
134
151
|
"""
|
135
152
|
For each entry in ALL_LAND_USE_TERMS, creates a key: value in output dictionary, also TOTAL
|
136
153
|
"""
|
137
|
-
|
154
|
+
lookup_name = "region-faostatArea-UpTo20YearExpansion.csv"
|
138
155
|
changes_dict = {
|
139
156
|
land_use_term: safe_parse_float(
|
140
157
|
extract_grouped_data(
|
141
|
-
|
142
|
-
str(end_year)
|
158
|
+
get_region_lookup_value(lookup_name, country_id, land_use_term, model=MODEL, key=MODEL_KEY),
|
159
|
+
str(end_year)
|
160
|
+
),
|
143
161
|
default=None
|
144
162
|
)
|
145
163
|
for land_use_term in ALL_LAND_USE_TERMS + [LAND_AREA]
|
@@ -160,8 +178,7 @@ def _get_ratio_start_and_end_values(
|
|
160
178
|
end_year: int
|
161
179
|
) -> float:
|
162
180
|
# expansion over twenty years / current area
|
163
|
-
|
164
|
-
table_value = get_table_value(lookup, 'termid', country_id, column_name(fao_name))
|
181
|
+
table_value = get_region_lookup_value('region-faostatArea.csv', country_id, fao_name, model=MODEL, key=MODEL_KEY)
|
165
182
|
end_value = safe_parse_float(value=extract_grouped_data(table_value, str(end_year)), default=None)
|
166
183
|
return max(0.0, _safe_divide(numerator=expansion, denominator=end_value))
|
167
184
|
|
@@ -186,11 +203,13 @@ def _estimate_maximum_forest_change(
|
|
186
203
|
|
187
204
|
|
188
205
|
def _negative_agricultural_land_change(forest_change, pasture_change, total_cropland_change):
|
189
|
-
return
|
190
|
-
|
191
|
-
else
|
192
|
-
else
|
206
|
+
return (
|
207
|
+
-pasture_change if 0 < pasture_change < -min(forest_change, 0)
|
208
|
+
else min(forest_change, 0) if pasture_change > 0
|
209
|
+
else -total_cropland_change if 0 < total_cropland_change < -min(forest_change, 0)
|
210
|
+
else min(forest_change, 0) if 0 < total_cropland_change
|
193
211
|
else 0
|
212
|
+
)
|
194
213
|
|
195
214
|
|
196
215
|
def _allocate_forest_loss(forest_loss: float, changes: dict):
|
@@ -271,12 +290,14 @@ def _estimate_conversions_to_annual_cropland(
|
|
271
290
|
permanent_to_annual_cropland: float
|
272
291
|
) -> dict:
|
273
292
|
"""(AC-AG): Estimate percentage of land sources when converted to: Annual cropland"""
|
293
|
+
|
274
294
|
# -> percent_annual_cropland_was[]
|
275
295
|
def conversion_to_annual_cropland(factor: float):
|
276
296
|
return factor * _safe_divide(
|
277
297
|
numerator=_safe_divide(
|
278
298
|
numerator=max(changes[ANNUAL_CROPLAND], 0),
|
279
|
-
denominator=max(changes[ANNUAL_CROPLAND], 0) + max(changes[PERMANENT_CROPLAND], 0)
|
299
|
+
denominator=max(changes[ANNUAL_CROPLAND], 0) + max(changes[PERMANENT_CROPLAND], 0)
|
300
|
+
),
|
280
301
|
denominator=-changes[ANNUAL_CROPLAND]
|
281
302
|
)
|
282
303
|
|
@@ -297,11 +318,13 @@ def _estimate_conversions_to_permanent_cropland(
|
|
297
318
|
other_land_loss_to_annual_cropland: float
|
298
319
|
) -> dict:
|
299
320
|
"""Estimate percentage of land sources when converted to: Annual cropland"""
|
321
|
+
|
300
322
|
def conversion_to_permanent_cropland(factor: float):
|
301
323
|
return _safe_divide(
|
302
324
|
numerator=_safe_divide(
|
303
325
|
numerator=factor * max(changes[PERMANENT_CROPLAND], 0),
|
304
|
-
denominator=max(changes[ANNUAL_CROPLAND], 0) + max(changes[PERMANENT_CROPLAND], 0)
|
326
|
+
denominator=max(changes[ANNUAL_CROPLAND], 0) + max(changes[PERMANENT_CROPLAND], 0)
|
327
|
+
),
|
305
328
|
denominator=-changes[PERMANENT_CROPLAND]
|
306
329
|
)
|
307
330
|
|
@@ -360,10 +383,10 @@ def _get_shares_of_expansion(
|
|
360
383
|
PERMANENT_CROPLAND: percent_permanent_cropland_was,
|
361
384
|
PERMANENT_PASTURE: percent_pasture_was
|
362
385
|
}
|
363
|
-
return {
|
386
|
+
return scale_values_to_one({
|
364
387
|
k: expansion_for_type[land_use_type].get(k, 0)
|
365
388
|
for k in LAND_USE_TERMS_FOR_TRANSFORMATION.keys()
|
366
|
-
}
|
389
|
+
})
|
367
390
|
|
368
391
|
|
369
392
|
def _get_faostat_name(term: dict) -> str:
|
@@ -391,10 +414,11 @@ def _get_harvested_area(country_id: str, year: int, faostat_name: str) -> float:
|
|
391
414
|
"""
|
392
415
|
Returns a dictionary of harvested areas for the country & year, indexed by landCover term (crop)
|
393
416
|
"""
|
394
|
-
|
417
|
+
lookup_name = "region-crop-cropGroupingFaostatProduction-areaHarvested.csv"
|
418
|
+
|
395
419
|
return safe_parse_float(
|
396
420
|
value=extract_grouped_data(
|
397
|
-
data=
|
421
|
+
data=get_region_lookup_value(lookup_name, country_id, faostat_name, model=MODEL, key=MODEL_KEY),
|
398
422
|
key=str(year)
|
399
423
|
),
|
400
424
|
default=None
|
@@ -452,8 +476,7 @@ def _run(site: dict, existing_nodes: list, percentage_transformed_from: dict):
|
|
452
476
|
|
453
477
|
|
454
478
|
def get_ratio_of_expanded_area(country_id: str, fao_name: str, end_year: int) -> float:
|
455
|
-
|
456
|
-
table_value = get_table_value(lookup, 'termid', country_id, column_name(fao_name))
|
479
|
+
table_value = get_region_lookup_value(_LOOKUP_EXPANSION, country_id, fao_name, model=MODEL, key=MODEL_KEY)
|
457
480
|
expansion = safe_parse_float(value=extract_grouped_data(table_value, str(end_year)), default=None)
|
458
481
|
end_value = _get_harvested_area(
|
459
482
|
country_id=country_id,
|
@@ -472,16 +495,16 @@ def _get_sum_for_land_category(
|
|
472
495
|
fao_stat_to_ipcc_type: dict,
|
473
496
|
include_negatives: bool = True
|
474
497
|
) -> float:
|
475
|
-
return sum(
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
)
|
498
|
+
return sum([
|
499
|
+
safe_parse_float(value=extract_grouped_data(table_value, str(year)), default=None)
|
500
|
+
for fao_name, table_value in values.items()
|
501
|
+
if not _is_missing_or_none(extract_grouped_data(table_value, str(year))) and
|
502
|
+
fao_stat_to_ipcc_type[fao_name] == ipcc_land_use_category and
|
503
|
+
(
|
504
|
+
include_negatives or
|
505
|
+
safe_parse_float(value=extract_grouped_data(table_value, str(year)), default=None) > 0.0
|
506
|
+
)
|
507
|
+
])
|
485
508
|
|
486
509
|
|
487
510
|
def _get_sums_of_crop_expansion(country_id: str, year: int, include_negatives: bool = True) -> tuple[float, float]:
|
@@ -489,9 +512,12 @@ def _get_sums_of_crop_expansion(country_id: str, year: int, include_negatives: b
|
|
489
512
|
Sum net expansion for all annual and permanent crops, returned as two values.
|
490
513
|
Returns a tuple of (expansion of annual crops, expansion of permanent crops)
|
491
514
|
"""
|
492
|
-
lookup = download_lookup(
|
493
|
-
|
494
|
-
|
515
|
+
lookup = download_lookup(_LOOKUP_EXPANSION.replace('region', f"{country_id}")) or download_lookup(_LOOKUP_EXPANSION)
|
516
|
+
columns = lookup_columns(lookup)
|
517
|
+
values = {
|
518
|
+
name: get_table_value(lookup, 'termid', country_id, column_name(name))
|
519
|
+
for name in columns if name != "termid"
|
520
|
+
}
|
495
521
|
|
496
522
|
fao_stat_to_ipcc_type = _get_complete_faostat_to_crop_mapping()
|
497
523
|
|
@@ -513,8 +539,9 @@ def _get_sums_of_crop_expansion(country_id: str, year: int, include_negatives: b
|
|
513
539
|
return annual_sum_of_expansion, permanent_sum_of_expansion
|
514
540
|
|
515
541
|
|
516
|
-
def _get_net_expansion_cultivated_vs_harvested(
|
517
|
-
|
542
|
+
def _get_net_expansion_cultivated_vs_harvested(
|
543
|
+
annual_crops_net_expansion, changes, land_use_type, permanent_crops_net_expansion
|
544
|
+
):
|
518
545
|
if land_use_type == ANNUAL_CROPLAND:
|
519
546
|
net_expansion_cultivated_vs_harvested = _safe_divide(numerator=max(0, changes[ANNUAL_CROPLAND]),
|
520
547
|
denominator=(annual_crops_net_expansion / 1000))
|
@@ -673,14 +700,14 @@ def _should_run_historical_land_use_change_single_crop(
|
|
673
700
|
|
674
701
|
site_area = {
|
675
702
|
land_type: (
|
676
|
-
|
677
|
-
)
|
678
|
-
for land_type in LAND_USE_TERMS_FOR_TRANSFORMATION.keys()
|
703
|
+
shares_of_expansion[land_type] * expansion_factor * e9_net_expansion * net_expansion_cultivated_vs_harvested
|
704
|
+
) for land_type in LAND_USE_TERMS_FOR_TRANSFORMATION.keys()
|
679
705
|
if land_type != land_use_type
|
680
706
|
}
|
681
707
|
site_area[land_use_type] = 1 - sum(site_area.values())
|
708
|
+
capped_site_area = cap_values(dictionary=site_area, lower_limit=0, upper_limit=1)
|
682
709
|
|
683
|
-
sum_of_site_areas_is_100 = site_area_sum_to_100(
|
710
|
+
sum_of_site_areas_is_100 = site_area_sum_to_100(capped_site_area)
|
684
711
|
site_type_allowed = site.get("siteType") in SITE_TYPES
|
685
712
|
|
686
713
|
logRequirements(
|
@@ -691,7 +718,7 @@ def _should_run_historical_land_use_change_single_crop(
|
|
691
718
|
land_use_type=land_use_type,
|
692
719
|
country_id=country_id,
|
693
720
|
changes=log_as_table(changes),
|
694
|
-
site_area=log_as_table(
|
721
|
+
site_area=log_as_table(capped_site_area),
|
695
722
|
sum_of_site_areas_is_100=sum_of_site_areas_is_100,
|
696
723
|
site_type_allowed=site_type_allowed
|
697
724
|
)
|
@@ -699,7 +726,7 @@ def _should_run_historical_land_use_change_single_crop(
|
|
699
726
|
should_run = all([not missing_changes, country_id, site_type_allowed, sum_of_site_areas_is_100])
|
700
727
|
logShouldRun(site, MODEL, term.get("@id"), should_run, model_key=MODEL_KEY)
|
701
728
|
|
702
|
-
return should_run,
|
729
|
+
return should_run, capped_site_area
|
703
730
|
|
704
731
|
|
705
732
|
def _get_land_use_term_from_node(node: dict) -> str:
|
@@ -13,7 +13,9 @@ These are the steps:
|
|
13
13
|
"""
|
14
14
|
from functools import reduce
|
15
15
|
from hestia_earth.schema import TermTermType, EmissionMethodTier, SiteSiteType
|
16
|
-
from hestia_earth.utils.lookup import
|
16
|
+
from hestia_earth.utils.lookup import (
|
17
|
+
download_lookup, column_name, extract_grouped_data_closest_date, find_term_ids_by
|
18
|
+
)
|
17
19
|
from hestia_earth.utils.model import filter_list_term_type
|
18
20
|
from hestia_earth.utils.tools import non_empty_list, flatten, list_sum, safe_parse_float
|
19
21
|
from hestia_earth.utils.emission import cycle_emissions_in_system_boundary
|
@@ -26,6 +28,7 @@ from hestia_earth.models.utils.cycle import cycle_end_year
|
|
26
28
|
from hestia_earth.models.utils.crop import get_crop_grouping_faostat_production, get_landCover_term_id
|
27
29
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
28
30
|
from hestia_earth.models.utils.blank_node import get_lookup_value
|
31
|
+
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
29
32
|
from . import MODEL
|
30
33
|
|
31
34
|
REQUIREMENTS = {
|
@@ -65,7 +68,7 @@ RETURNS = {
|
|
65
68
|
}]
|
66
69
|
}
|
67
70
|
LOOKUPS = {
|
68
|
-
"region-crop-cropGroupingFaostatProduction-yield": "
|
71
|
+
"region-crop-cropGroupingFaostatProduction-yield": "",
|
69
72
|
"crop": [
|
70
73
|
"correspondingSeedTermIds",
|
71
74
|
"cropGroupingFaostatProduction",
|
@@ -133,7 +136,7 @@ def _filter_emissions(cycle: dict):
|
|
133
136
|
'id': group_id,
|
134
137
|
'emissions': list(filter(
|
135
138
|
lambda id: id in required_emission_term_ids,
|
136
|
-
|
139
|
+
find_term_ids_by(lookup, column_name('inputProductionGroupId'), group_id)
|
137
140
|
))
|
138
141
|
}
|
139
142
|
for group_id in group_ids
|
@@ -169,11 +172,12 @@ def _evs(product: dict):
|
|
169
172
|
|
170
173
|
def _faostat_yield(country_id: str, end_year: int, product: dict):
|
171
174
|
grouping = get_crop_grouping_faostat_production(MODEL, product.get('term', {}))
|
172
|
-
return safe_parse_float(extract_grouped_data_closest_date(
|
173
|
-
|
174
|
-
'termid',
|
175
|
+
return safe_parse_float(extract_grouped_data_closest_date(get_region_lookup_value(
|
176
|
+
'region-crop-cropGroupingFaostatProduction-yield.csv',
|
175
177
|
country_id,
|
176
|
-
|
178
|
+
grouping,
|
179
|
+
model=MODEL,
|
180
|
+
model_key=MODEL_KEY
|
177
181
|
), end_year))
|
178
182
|
|
179
183
|
|
@@ -2,12 +2,12 @@ from os.path import dirname, abspath
|
|
2
2
|
import sys
|
3
3
|
from importlib import import_module
|
4
4
|
|
5
|
-
from hestia_earth.models.utils.blank_node import run_if_required
|
6
|
-
|
7
5
|
CURRENT_DIR = dirname(abspath(__file__)) + '/'
|
8
6
|
sys.path.append(CURRENT_DIR)
|
9
7
|
MODEL = 'impact_assessment'
|
10
8
|
PKG = '.'.join(['hestia_earth', 'models', MODEL])
|
11
9
|
|
12
10
|
|
13
|
-
def run(model: str, data):
|
11
|
+
def run(model: str, data):
|
12
|
+
run = getattr(import_module(f".{model}", package=PKG), 'run')
|
13
|
+
return run(data)
|
@@ -136,7 +136,7 @@ LOOKUPS = {
|
|
136
136
|
"mjKgABNetEnergyGrowthSheepGoatsIpcc2019",
|
137
137
|
"isWoolProducingAnimal"
|
138
138
|
],
|
139
|
-
"system-liveAnimal-activityCoefficient-ipcc2019": "
|
139
|
+
"system-liveAnimal-activityCoefficient-ipcc2019": "",
|
140
140
|
"landCover": "grazedPastureGrassInputId",
|
141
141
|
"crop-property": ["energyDigestibilityRuminants", "energyContentHigherHeatingValue"],
|
142
142
|
"crop": "grazedPastureGrassInputId",
|
@@ -1,13 +1,14 @@
|
|
1
1
|
from hestia_earth.schema import TermTermType
|
2
|
-
from hestia_earth.utils.lookup import
|
2
|
+
from hestia_earth.utils.lookup import extract_grouped_data
|
3
3
|
from hestia_earth.utils.model import filter_list_term_type
|
4
4
|
from hestia_earth.utils.tools import safe_parse_float, non_empty_list
|
5
5
|
|
6
|
-
from hestia_earth.models.log import logRequirements, logShouldRun
|
6
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
7
7
|
from hestia_earth.models.utils.blank_node import merge_blank_nodes
|
8
8
|
from hestia_earth.models.utils.property import _new_property, node_has_no_property
|
9
9
|
from hestia_earth.models.utils.productivity import PRODUCTIVITY, get_productivity
|
10
10
|
from hestia_earth.models.utils.term import get_lookup_value
|
11
|
+
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
11
12
|
from .. import MODEL
|
12
13
|
|
13
14
|
|
@@ -24,11 +25,8 @@ def _get_practice(term_id: str, animal: dict, practice_column: str):
|
|
24
25
|
def productivity_lookup_value(term_id: str, lookup: str, country: dict, animal: dict):
|
25
26
|
country_id = country.get('@id')
|
26
27
|
productivity_key = get_productivity(country)
|
27
|
-
|
28
|
-
lookup =
|
29
|
-
column = column_name(animal.get('term').get('@id'))
|
30
|
-
value = get_table_value(lookup, 'termid', country_id, column)
|
31
|
-
debugMissingLookup(lookup_name, 'termid', country_id, column, value, model=MODEL, term=term_id)
|
28
|
+
column = animal.get('term').get('@id')
|
29
|
+
value = get_region_lookup_value(f"{lookup}.csv", country_id, column, model=MODEL, term=term_id)
|
32
30
|
return safe_parse_float(
|
33
31
|
extract_grouped_data(value, productivity_key.value) or
|
34
32
|
extract_grouped_data(value, PRODUCTIVITY.HIGH.value), # defaults to high if low is not found
|
@@ -195,10 +195,10 @@ def _is_ionophore(cycle: dict, total_feed: float):
|
|
195
195
|
has_input = find_term_match(inputs, 'ionophores', None) is not None
|
196
196
|
maize_input = find_term_match(inputs, 'maizeSteamFlaked')
|
197
197
|
maize_feed = get_total_value_converted_with_min_ratio(MODEL, None, blank_nodes=[maize_input]) if maize_input else 0
|
198
|
-
maize_feed_ratio = maize_feed / total_feed
|
198
|
+
maize_feed_ratio = maize_feed / total_feed if all([maize_feed, total_feed]) else 0
|
199
199
|
|
200
200
|
debugValues(cycle, model=MODEL, term=TERM_ID,
|
201
|
-
|
201
|
+
maize_feed_in_MJ=maize_feed,
|
202
202
|
maize_feed_ratio=maize_feed_ratio)
|
203
203
|
|
204
204
|
return has_input and maize_feed_ratio >= 0.9
|