hestia-earth-models 0.72.2__py3-none-any.whl → 0.73.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hestia_earth/models/{akagiEtAl2011AndIpcc2006 → akagiEtAl2011}/__init__.py +1 -1
- hestia_earth/models/akagiEtAl2011/ch4ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/nh3ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/noxToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/pm25ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/so2ToAirCropResidueBurning.py +32 -0
- hestia_earth/models/akagiEtAl2011/utils.py +45 -0
- hestia_earth/models/aware/scarcityWeightedWaterUse.py +2 -2
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsTotalLandUseEffects.py +1 -1
- hestia_earth/models/chaudharyBrooks2018/utils.py +1 -1
- hestia_earth/models/config/Cycle.json +48 -7
- hestia_earth/models/config/ImpactAssessment.json +22 -0
- hestia_earth/models/cycle/completeness/soilAmendment.py +1 -1
- hestia_earth/models/cycle/product/economicValueShare.py +3 -1
- hestia_earth/models/cycle/product/price.py +35 -10
- hestia_earth/models/cycle/product/revenue.py +5 -2
- hestia_earth/models/dammgen2009/noxToAirExcreta.py +14 -18
- hestia_earth/models/ecoinventV3/__init__.py +11 -6
- hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +1 -1
- hestia_earth/models/emepEea2019/utils.py +2 -1
- hestia_earth/models/faostat2018/liveweightPerHead.py +1 -1
- hestia_earth/models/faostat2018/product/price.py +2 -2
- hestia_earth/models/faostat2018/seed.py +3 -2
- hestia_earth/models/faostat2018/utils.py +6 -5
- hestia_earth/models/geospatialDatabase/altitude.py +2 -1
- hestia_earth/models/geospatialDatabase/drainageClass.py +2 -1
- hestia_earth/models/geospatialDatabase/organicCarbonPerKgSoil.py +2 -1
- hestia_earth/models/geospatialDatabase/totalNitrogenPerKgSoil.py +2 -1
- hestia_earth/models/geospatialDatabase/totalPhosphorusPerKgSoil.py +2 -1
- hestia_earth/models/geospatialDatabase/utils.py +1 -1
- hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +1 -1
- hestia_earth/models/hestia/brackishWater.py +1 -1
- hestia_earth/models/hestia/default_emissions.py +105 -0
- hestia_earth/models/hestia/default_resourceUse.py +110 -0
- hestia_earth/models/hestia/freshWater.py +1 -1
- hestia_earth/models/hestia/inorganicFertiliser.py +12 -12
- hestia_earth/models/hestia/landCover.py +7 -5
- hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +3 -0
- hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +3 -0
- hestia_earth/models/hestia/liveAnimal.py +1 -1
- hestia_earth/models/hestia/management.py +1 -1
- hestia_earth/models/hestia/netPrimaryProduction.py +1 -1
- hestia_earth/models/hestia/organicCarbonPerHa.py +2 -2
- hestia_earth/models/hestia/salineWater.py +1 -1
- hestia_earth/models/hestia/seed_emissions.py +34 -20
- hestia_earth/models/hestia/totalNitrogenPerKgSoil.py +1 -1
- hestia_earth/models/hestia/waterSalinity.py +2 -1
- hestia_earth/models/ipcc2006/aboveGroundCropResidueRemoved.py +2 -2
- hestia_earth/models/ipcc2006/aboveGroundCropResidueTotal.py +10 -6
- hestia_earth/models/ipcc2006/belowGroundCropResidue.py +12 -8
- hestia_earth/models/ipcc2019/animal/utils.py +1 -1
- hestia_earth/models/ipcc2019/belowGroundCropResidue.py +1 -1
- hestia_earth/models/ipcc2019/carbonContent.py +1 -1
- hestia_earth/models/ipcc2019/ch4ToAirAquacultureSystems.py +17 -9
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +6 -6
- hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +4 -2
- hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +1 -1
- hestia_earth/models/ipcc2019/croppingDuration.py +4 -2
- hestia_earth/models/ipcc2019/ligninContent.py +1 -1
- hestia_earth/models/{akagiEtAl2011AndIpcc2006 → ipcc2019}/n2OToAirCropResidueBurningDirect.py +8 -4
- hestia_earth/models/ipcc2019/nitrogenContent.py +1 -1
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +6 -2
- hestia_earth/models/ipcc2019/pastureGrass_utils.py +13 -12
- hestia_earth/models/ipcc2019/utils.py +6 -2
- hestia_earth/models/koble2014/residueBurnt.py +6 -3
- hestia_earth/models/koble2014/residueRemoved.py +1 -1
- hestia_earth/models/mocking/search-results.json +1577 -1573
- hestia_earth/models/pooreNemecek2018/aboveGroundCropResidueTotal.py +1 -1
- hestia_earth/models/pooreNemecek2018/belowGroundCropResidue.py +1 -1
- hestia_earth/models/pooreNemecek2018/excretaKgVs.py +1 -1
- hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py +1 -1
- hestia_earth/models/pooreNemecek2018/longFallowDuration.py +1 -1
- hestia_earth/models/pooreNemecek2018/nurseryDensity.py +1 -1
- hestia_earth/models/pooreNemecek2018/nurseryDuration.py +1 -1
- hestia_earth/models/pooreNemecek2018/plantationDensity.py +1 -1
- hestia_earth/models/pooreNemecek2018/plantationLifespan.py +1 -1
- hestia_earth/models/pooreNemecek2018/plantationProductiveLifespan.py +3 -1
- hestia_earth/models/pooreNemecek2018/saplingsDepreciatedAmountPerCycle.py +1 -1
- hestia_earth/models/resourceUseNotRelevant/__init__.py +65 -0
- hestia_earth/models/schererPfister2015/nErosionSoilFlux.py +5 -3
- hestia_earth/models/schererPfister2015/pErosionSoilFlux.py +5 -3
- hestia_earth/models/schererPfister2015/utils.py +5 -4
- hestia_earth/models/stehfestBouwman2006/n2OToAirSoilFlux_utils.py +1 -1
- hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirSoilFlux_utils.py +3 -3
- hestia_earth/models/utils/background_emissions.py +14 -10
- hestia_earth/models/utils/blank_node.py +6 -4
- hestia_earth/models/utils/crop.py +1 -1
- hestia_earth/models/utils/cropResidue.py +16 -0
- hestia_earth/models/utils/cycle.py +1 -1
- hestia_earth/models/utils/ecoClimateZone.py +2 -2
- hestia_earth/models/utils/excretaManagement.py +1 -1
- hestia_earth/models/utils/feedipedia.py +3 -3
- hestia_earth/models/utils/fertiliser.py +7 -1
- hestia_earth/models/utils/inorganicFertiliser.py +2 -2
- hestia_earth/models/utils/input.py +34 -1
- hestia_earth/models/utils/liveAnimal.py +2 -2
- hestia_earth/models/utils/lookup.py +1 -1
- hestia_earth/models/utils/measurement.py +5 -4
- hestia_earth/models/utils/productivity.py +1 -1
- hestia_earth/models/utils/property.py +4 -2
- hestia_earth/models/utils/site.py +2 -1
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.0.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.0.dist-info}/RECORD +124 -113
- tests/models/akagiEtAl2011/test_ch4ToAirCropResidueBurning.py +33 -0
- tests/models/akagiEtAl2011/test_nh3ToAirCropResidueBurning.py +33 -0
- tests/models/{akagiEtAl2011AndIpcc2006 → akagiEtAl2011}/test_noxToAirCropResidueBurning.py +5 -17
- tests/models/akagiEtAl2011/test_pm25ToAirCropResidueBurning.py +33 -0
- tests/models/akagiEtAl2011/test_so2ToAirCropResidueBurning.py +33 -0
- tests/models/akagiEtAl2011/test_utils.py +18 -0
- tests/models/cycle/product/test_price.py +1 -11
- tests/models/dammgen2009/test_noxToAirExcreta.py +30 -10
- tests/models/geospatialDatabase/test_utils.py +2 -1
- tests/models/hestia/test_default_emissions.py +25 -0
- tests/models/hestia/test_default_resourceUse.py +26 -0
- tests/models/hestia/test_landCover.py +2 -2
- tests/models/ipcc2019/test_ch4ToAirAquacultureSystems.py +2 -2
- tests/models/{akagiEtAl2011AndIpcc2006/test_nh3ToAirCropResidueBurning.py → ipcc2019/test_n2OToAirCropResidueBurningDirect.py} +2 -2
- tests/models/test_resourceUseNotRelevant.py +27 -0
- tests/models/{akagiEtAl2011AndIpcc2006/test_utils.py → utils/test_cropResidue.py} +6 -6
- hestia_earth/models/akagiEtAl2011AndIpcc2006/ch4ToAirCropResidueBurning.py +0 -57
- hestia_earth/models/akagiEtAl2011AndIpcc2006/nh3ToAirCropResidueBurning.py +0 -57
- hestia_earth/models/akagiEtAl2011AndIpcc2006/noxToAirCropResidueBurning.py +0 -57
- hestia_earth/models/akagiEtAl2011AndIpcc2006/utils.py +0 -15
- tests/models/akagiEtAl2011AndIpcc2006/test_ch4ToAirCropResidueBurning.py +0 -45
- tests/models/akagiEtAl2011AndIpcc2006/test_n2OToAirCropResidueBurningDirect.py +0 -46
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.0.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.0.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.72.2.dist-info → hestia_earth_models-0.73.0.dist-info}/top_level.txt +0 -0
- /tests/models/{akagiEtAl2011AndIpcc2006 → akagiEtAl2011}/__init__.py +0 -0
@@ -6,7 +6,7 @@ from hestia_earth.models.utils.blank_node import run_if_required
|
|
6
6
|
|
7
7
|
CURRENT_DIR = dirname(abspath(__file__)) + '/'
|
8
8
|
sys.path.append(CURRENT_DIR)
|
9
|
-
MODEL = '
|
9
|
+
MODEL = 'akagiEtAl2011'
|
10
10
|
PKG = '.'.join(['hestia_earth', 'models', MODEL])
|
11
11
|
|
12
12
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
2
|
+
|
3
|
+
from .utils import run_emission
|
4
|
+
|
5
|
+
REQUIREMENTS = {
|
6
|
+
"Cycle": {
|
7
|
+
"or": {
|
8
|
+
"products": [{
|
9
|
+
"@type": "Product",
|
10
|
+
"term.@id": ["aboveGroundCropResidueBurnt", "discardedCropBurnt"],
|
11
|
+
"value": ""
|
12
|
+
}],
|
13
|
+
"completeness.cropResidue": "True"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
RETURNS = {
|
18
|
+
"Emission": [{
|
19
|
+
"value": "",
|
20
|
+
"sd": "",
|
21
|
+
"methodTier": "tier 1",
|
22
|
+
"statsDefinition": "modelled"
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
LOOKUPS = {
|
26
|
+
"emission": ["akagiEtAl2011CropResidueBurningFactor", "akagiEtAl2011CropResidueBurningFactor-sd"]
|
27
|
+
}
|
28
|
+
TERM_ID = 'ch4ToAirCropResidueBurning'
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
30
|
+
|
31
|
+
|
32
|
+
def run(cycle: dict): return run_emission(TERM_ID, cycle)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
2
|
+
|
3
|
+
from .utils import run_emission
|
4
|
+
|
5
|
+
REQUIREMENTS = {
|
6
|
+
"Cycle": {
|
7
|
+
"or": {
|
8
|
+
"products": [{
|
9
|
+
"@type": "Product",
|
10
|
+
"term.@id": ["aboveGroundCropResidueBurnt", "discardedCropBurnt"],
|
11
|
+
"value": ""
|
12
|
+
}],
|
13
|
+
"completeness.cropResidue": "True"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
RETURNS = {
|
18
|
+
"Emission": [{
|
19
|
+
"value": "",
|
20
|
+
"sd": "",
|
21
|
+
"methodTier": "tier 1",
|
22
|
+
"statsDefinition": "modelled"
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
LOOKUPS = {
|
26
|
+
"emission": ["akagiEtAl2011CropResidueBurningFactor", "akagiEtAl2011CropResidueBurningFactor-sd"]
|
27
|
+
}
|
28
|
+
TERM_ID = 'nh3ToAirCropResidueBurning'
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
30
|
+
|
31
|
+
|
32
|
+
def run(cycle: dict): return run_emission(TERM_ID, cycle)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
2
|
+
|
3
|
+
from .utils import run_emission
|
4
|
+
|
5
|
+
REQUIREMENTS = {
|
6
|
+
"Cycle": {
|
7
|
+
"or": {
|
8
|
+
"products": [{
|
9
|
+
"@type": "Product",
|
10
|
+
"term.@id": ["aboveGroundCropResidueBurnt", "discardedCropBurnt"],
|
11
|
+
"value": ""
|
12
|
+
}],
|
13
|
+
"completeness.cropResidue": "True"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
RETURNS = {
|
18
|
+
"Emission": [{
|
19
|
+
"value": "",
|
20
|
+
"sd": "",
|
21
|
+
"methodTier": "tier 1",
|
22
|
+
"statsDefinition": "modelled"
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
LOOKUPS = {
|
26
|
+
"emission": ["akagiEtAl2011CropResidueBurningFactor", "akagiEtAl2011CropResidueBurningFactor-sd"]
|
27
|
+
}
|
28
|
+
TERM_ID = 'noxToAirCropResidueBurning'
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
30
|
+
|
31
|
+
|
32
|
+
def run(cycle: dict): return run_emission(TERM_ID, cycle)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
2
|
+
|
3
|
+
from .utils import run_emission
|
4
|
+
|
5
|
+
REQUIREMENTS = {
|
6
|
+
"Cycle": {
|
7
|
+
"or": {
|
8
|
+
"products": [{
|
9
|
+
"@type": "Product",
|
10
|
+
"term.@id": ["aboveGroundCropResidueBurnt", "discardedCropBurnt"],
|
11
|
+
"value": ""
|
12
|
+
}],
|
13
|
+
"completeness.cropResidue": "True"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
RETURNS = {
|
18
|
+
"Emission": [{
|
19
|
+
"value": "",
|
20
|
+
"sd": "",
|
21
|
+
"methodTier": "tier 1",
|
22
|
+
"statsDefinition": "modelled"
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
LOOKUPS = {
|
26
|
+
"emission": ["akagiEtAl2011CropResidueBurningFactor", "akagiEtAl2011CropResidueBurningFactor-sd"]
|
27
|
+
}
|
28
|
+
TERM_ID = 'pm25ToAirCropResidueBurning'
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
30
|
+
|
31
|
+
|
32
|
+
def run(cycle: dict): return run_emission(TERM_ID, cycle)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
2
|
+
|
3
|
+
from .utils import run_emission
|
4
|
+
|
5
|
+
REQUIREMENTS = {
|
6
|
+
"Cycle": {
|
7
|
+
"or": {
|
8
|
+
"products": [{
|
9
|
+
"@type": "Product",
|
10
|
+
"term.@id": ["aboveGroundCropResidueBurnt", "discardedCropBurnt"],
|
11
|
+
"value": ""
|
12
|
+
}],
|
13
|
+
"completeness.cropResidue": "True"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
RETURNS = {
|
18
|
+
"Emission": [{
|
19
|
+
"value": "",
|
20
|
+
"sd": "",
|
21
|
+
"methodTier": "tier 1",
|
22
|
+
"statsDefinition": "modelled"
|
23
|
+
}]
|
24
|
+
}
|
25
|
+
LOOKUPS = {
|
26
|
+
"emission": ["akagiEtAl2011CropResidueBurningFactor", "akagiEtAl2011CropResidueBurningFactor-sd"]
|
27
|
+
}
|
28
|
+
TERM_ID = 'so2ToAirCropResidueBurning'
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
30
|
+
|
31
|
+
|
32
|
+
def run(cycle: dict): return run_emission(TERM_ID, cycle)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
2
|
+
|
3
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
4
|
+
from hestia_earth.models.utils.emission import _new_emission
|
5
|
+
from hestia_earth.models.utils.blank_node import get_lookup_value
|
6
|
+
from hestia_earth.models.utils.cropResidue import get_crop_residue_burnt_value
|
7
|
+
from . import MODEL
|
8
|
+
|
9
|
+
TIER = EmissionMethodTier.TIER_1.value
|
10
|
+
LOOKUP_NAME = 'akagiEtAl2011CropResidueBurningFactor'
|
11
|
+
|
12
|
+
|
13
|
+
def _emission(term_id: str, value: float, sd: float = None):
|
14
|
+
emission = _new_emission(term_id, MODEL)
|
15
|
+
emission['value'] = [value]
|
16
|
+
emission['methodTier'] = TIER
|
17
|
+
if sd is not None:
|
18
|
+
emission['sd'] = [sd]
|
19
|
+
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
20
|
+
return emission
|
21
|
+
|
22
|
+
|
23
|
+
def _run(term_id: str, product_value: list):
|
24
|
+
value = sum(product_value)
|
25
|
+
term = {'termType': TermTermType.EMISSION.value, '@id': term_id}
|
26
|
+
factor = get_lookup_value(term, LOOKUP_NAME)
|
27
|
+
factor_sd = get_lookup_value(term, LOOKUP_NAME + '-sd')
|
28
|
+
return [_emission(term_id, value * factor, value * factor_sd)]
|
29
|
+
|
30
|
+
|
31
|
+
def _should_run(term_id: str, cycle: dict):
|
32
|
+
crop_residue_burnt_value = get_crop_residue_burnt_value(cycle)
|
33
|
+
has_crop_residue_burnt = len(crop_residue_burnt_value) > 0
|
34
|
+
|
35
|
+
logRequirements(cycle, model=MODEL, term=term_id,
|
36
|
+
has_crop_residue_burnt=has_crop_residue_burnt)
|
37
|
+
|
38
|
+
should_run = all([has_crop_residue_burnt])
|
39
|
+
logShouldRun(cycle, MODEL, term_id, should_run, methodTier=TIER)
|
40
|
+
return should_run, crop_residue_burnt_value
|
41
|
+
|
42
|
+
|
43
|
+
def run_emission(term_id: str, cycle: dict):
|
44
|
+
should_run, crop_residue_burnt_value = _should_run(term_id, cycle)
|
45
|
+
return _run(term_id, crop_residue_burnt_value) if should_run else []
|
@@ -61,7 +61,7 @@ def _get_factor_from_basinId(site: dict, aware_id: str):
|
|
61
61
|
download_lookup(f"{AWARE_KEY}.csv"), column_name(AWARE_KEY), int(aware_id), column_name(lookup_col)
|
62
62
|
)
|
63
63
|
debugMissingLookup(f"{AWARE_KEY}.csv", AWARE_KEY, aware_id, lookup_col, value, model=MODEL, term=TERM_ID)
|
64
|
-
return safe_parse_float(value, None)
|
64
|
+
return safe_parse_float(value, default=None)
|
65
65
|
|
66
66
|
|
67
67
|
def _get_factor_from_region(impact_assessment: dict, site: dict):
|
@@ -71,7 +71,7 @@ def _get_factor_from_region(impact_assessment: dict, site: dict):
|
|
71
71
|
lookup_suffix = 'unspecified' if not site_type else ('irri' if site_type in IRRIGATED_SITE_TYPES else 'non_irri')
|
72
72
|
column = f"Agg_CF_{lookup_suffix}"
|
73
73
|
value = get_region_lookup_value(lookup_name, region_id, column, model=MODEL, term=TERM_ID)
|
74
|
-
return safe_parse_float(value, None)
|
74
|
+
return safe_parse_float(value, default=None)
|
75
75
|
|
76
76
|
|
77
77
|
def run(impact_assessment: dict):
|
@@ -45,7 +45,7 @@ def _indicator(value: float):
|
|
45
45
|
def impact_value(impact_assessment: dict, term_id: str):
|
46
46
|
impact = find_term_match(impact_assessment.get('impacts', []), term_id)
|
47
47
|
value = impact.get('value')
|
48
|
-
value = safe_parse_float(value, None)
|
48
|
+
value = safe_parse_float(value, default=None)
|
49
49
|
debugValues(impact, model=MODEL, term=TERM_ID, node=term_id, value=value, coefficient=1)
|
50
50
|
return value
|
51
51
|
|
@@ -33,4 +33,4 @@ def get_region_factor(term_id: str, impact_assessment: dict, lookup_suffix: str,
|
|
33
33
|
term_id, lookup_name, 'ecoregion', ecoregion, site_type
|
34
34
|
)
|
35
35
|
value = extract_grouped_data(value, group_key) if group_key else value
|
36
|
-
return safe_parse_float(value)
|
36
|
+
return safe_parse_float(value, default=None)
|
@@ -976,6 +976,17 @@
|
|
976
976
|
},
|
977
977
|
"stage": 2
|
978
978
|
},
|
979
|
+
{
|
980
|
+
"key": "emissions",
|
981
|
+
"model": "hestia",
|
982
|
+
"value": "default_emissions",
|
983
|
+
"runStrategy": "always",
|
984
|
+
"mergeStrategy": "list",
|
985
|
+
"mergeArgs": {
|
986
|
+
"replaceThreshold": ["value", 0.01]
|
987
|
+
},
|
988
|
+
"stage": 2
|
989
|
+
},
|
979
990
|
[
|
980
991
|
{
|
981
992
|
"key": "emissions",
|
@@ -1649,7 +1660,7 @@
|
|
1649
1660
|
[
|
1650
1661
|
{
|
1651
1662
|
"key": "emissions",
|
1652
|
-
"model": "
|
1663
|
+
"model": "akagiEtAl2011",
|
1653
1664
|
"value": "ch4ToAirCropResidueBurning",
|
1654
1665
|
"runStrategy": "add_blank_node_if_missing",
|
1655
1666
|
"runArgs": {
|
@@ -1664,8 +1675,8 @@
|
|
1664
1675
|
},
|
1665
1676
|
{
|
1666
1677
|
"key": "emissions",
|
1667
|
-
"model": "
|
1668
|
-
"value": "
|
1678
|
+
"model": "akagiEtAl2011",
|
1679
|
+
"value": "nh3ToAirCropResidueBurning",
|
1669
1680
|
"runStrategy": "add_blank_node_if_missing",
|
1670
1681
|
"runArgs": {
|
1671
1682
|
"runNonMeasured": true,
|
@@ -1679,8 +1690,8 @@
|
|
1679
1690
|
},
|
1680
1691
|
{
|
1681
1692
|
"key": "emissions",
|
1682
|
-
"model": "
|
1683
|
-
"value": "
|
1693
|
+
"model": "akagiEtAl2011",
|
1694
|
+
"value": "noxToAirCropResidueBurning",
|
1684
1695
|
"runStrategy": "add_blank_node_if_missing",
|
1685
1696
|
"runArgs": {
|
1686
1697
|
"runNonMeasured": true,
|
@@ -1694,8 +1705,23 @@
|
|
1694
1705
|
},
|
1695
1706
|
{
|
1696
1707
|
"key": "emissions",
|
1697
|
-
"model": "
|
1698
|
-
"value": "
|
1708
|
+
"model": "akagiEtAl2011",
|
1709
|
+
"value": "pm25ToAirCropResidueBurning",
|
1710
|
+
"runStrategy": "add_blank_node_if_missing",
|
1711
|
+
"runArgs": {
|
1712
|
+
"runNonMeasured": true,
|
1713
|
+
"runNonAddedTerm": true
|
1714
|
+
},
|
1715
|
+
"mergeStrategy": "list",
|
1716
|
+
"mergeArgs": {
|
1717
|
+
"replaceThreshold": ["value", 0.01]
|
1718
|
+
},
|
1719
|
+
"stage": 2
|
1720
|
+
},
|
1721
|
+
{
|
1722
|
+
"key": "emissions",
|
1723
|
+
"model": "akagiEtAl2011",
|
1724
|
+
"value": "so2ToAirCropResidueBurning",
|
1699
1725
|
"runStrategy": "add_blank_node_if_missing",
|
1700
1726
|
"runArgs": {
|
1701
1727
|
"runNonMeasured": true,
|
@@ -1767,6 +1793,21 @@
|
|
1767
1793
|
},
|
1768
1794
|
"stage": 2
|
1769
1795
|
},
|
1796
|
+
{
|
1797
|
+
"key": "emissions",
|
1798
|
+
"model": "ipcc2019",
|
1799
|
+
"value": "n2OToAirCropResidueBurningDirect",
|
1800
|
+
"runStrategy": "add_blank_node_if_missing",
|
1801
|
+
"runArgs": {
|
1802
|
+
"runNonMeasured": true,
|
1803
|
+
"runNonAddedTerm": true
|
1804
|
+
},
|
1805
|
+
"mergeStrategy": "list",
|
1806
|
+
"mergeArgs": {
|
1807
|
+
"replaceThreshold": ["value", 0.01]
|
1808
|
+
},
|
1809
|
+
"stage": 2
|
1810
|
+
},
|
1770
1811
|
{
|
1771
1812
|
"key": "emissions",
|
1772
1813
|
"model": "ipcc2019",
|
@@ -56,6 +56,17 @@
|
|
56
56
|
},
|
57
57
|
"stage": 1
|
58
58
|
},
|
59
|
+
{
|
60
|
+
"key": "emissionsResourceUse",
|
61
|
+
"model": "hestia",
|
62
|
+
"value": "default_resourceUse",
|
63
|
+
"runStrategy": "always",
|
64
|
+
"mergeStrategy": "list",
|
65
|
+
"mergeArgs": {
|
66
|
+
"replaceThreshold": ["value", 0.01]
|
67
|
+
},
|
68
|
+
"stage": 1
|
69
|
+
},
|
59
70
|
[
|
60
71
|
{
|
61
72
|
"key": "emissionsResourceUse",
|
@@ -216,6 +227,17 @@
|
|
216
227
|
"stage": 1
|
217
228
|
}
|
218
229
|
],
|
230
|
+
{
|
231
|
+
"key": "emissionsResourceUse",
|
232
|
+
"model": "resourceUseNotRelevant",
|
233
|
+
"value": "all",
|
234
|
+
"runStrategy": "always",
|
235
|
+
"mergeStrategy": "list",
|
236
|
+
"mergeArgs": {
|
237
|
+
"replaceLowerTier": true
|
238
|
+
},
|
239
|
+
"stage": 1
|
240
|
+
},
|
219
241
|
[
|
220
242
|
{
|
221
243
|
"key": "impacts",
|
@@ -29,7 +29,7 @@ def run(cycle: dict):
|
|
29
29
|
soilPh = measurement_value(soilPh_measurement)
|
30
30
|
|
31
31
|
soilPh_added = is_from_model(soilPh_measurement)
|
32
|
-
soilPh_above_6_5 = soilPh > 6.5
|
32
|
+
soilPh_above_6_5 = soilPh is not None and soilPh > 6.5
|
33
33
|
|
34
34
|
logRequirements(cycle, model=MODEL, term=None, key=MODEL_KEY,
|
35
35
|
soilPh_added=soilPh_added,
|
@@ -31,8 +31,10 @@ RETURNS = {
|
|
31
31
|
LOOKUPS = {
|
32
32
|
"@doc": "Depending on the primary product [termType](https://hestia.earth/schema/Product#term)",
|
33
33
|
"crop": "global_economic_value_share",
|
34
|
+
"processedFood": "global_economic_value_share",
|
34
35
|
"excreta": "global_economic_value_share",
|
35
|
-
"animalProduct": "global_economic_value_share"
|
36
|
+
"animalProduct": "global_economic_value_share",
|
37
|
+
"waste": "global_economic_value_share"
|
36
38
|
}
|
37
39
|
MODEL_KEY = 'economicValueShare'
|
38
40
|
MAX_VALUE = 100.5
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from hestia_earth.utils.tools import non_empty_list
|
1
|
+
from hestia_earth.utils.tools import list_sum, non_empty_list
|
2
2
|
|
3
3
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
4
4
|
from hestia_earth.models.utils.currency import DEFAULT_CURRENCY
|
@@ -7,7 +7,15 @@ from .. import MODEL
|
|
7
7
|
|
8
8
|
REQUIREMENTS = {
|
9
9
|
"Cycle": {
|
10
|
-
"products": [{
|
10
|
+
"products": [{
|
11
|
+
"@type": "Product",
|
12
|
+
"optional": {
|
13
|
+
"revenue": "0"
|
14
|
+
},
|
15
|
+
"none": {
|
16
|
+
"price": ""
|
17
|
+
}
|
18
|
+
}]
|
11
19
|
}
|
12
20
|
}
|
13
21
|
RETURNS = {
|
@@ -15,6 +23,14 @@ RETURNS = {
|
|
15
23
|
"price": ""
|
16
24
|
}]
|
17
25
|
}
|
26
|
+
LOOKUPS = {
|
27
|
+
"@doc": "Depending on the primary product [termType](https://hestia.earth/schema/Product#term)",
|
28
|
+
"crop": "global_economic_value_share",
|
29
|
+
"processedFood": "global_economic_value_share",
|
30
|
+
"excreta": "global_economic_value_share",
|
31
|
+
"animalProduct": "global_economic_value_share",
|
32
|
+
"waste": "global_economic_value_share"
|
33
|
+
}
|
18
34
|
MODEL_KEY = 'price'
|
19
35
|
|
20
36
|
|
@@ -24,26 +40,35 @@ def _product(product: dict, value: float):
|
|
24
40
|
return {'currency': DEFAULT_CURRENCY, **product, MODEL_KEY: value}
|
25
41
|
|
26
42
|
|
27
|
-
def
|
43
|
+
def _should_run_product(cycle: dict, product: dict):
|
28
44
|
term_id = product.get('term', {}).get('@id')
|
45
|
+
|
46
|
+
value = list_sum(product.get('value') or [], default=None)
|
47
|
+
is_yield_0 = value == 0
|
48
|
+
|
29
49
|
share = lookup_share(MODEL_KEY, product)
|
30
50
|
share_is_0 = share is not None and share == 0
|
31
51
|
|
52
|
+
revenue = product.get('revenue', -1)
|
53
|
+
revenue_is_0 = revenue == 0
|
54
|
+
|
32
55
|
logRequirements(cycle, model=MODEL, term=term_id, key=MODEL_KEY, by='economicValueShare',
|
33
|
-
|
56
|
+
global_economic_value_share=share,
|
57
|
+
share_is_0=share_is_0,
|
58
|
+
revenue=revenue,
|
59
|
+
revenue_is_0=revenue_is_0,
|
60
|
+
product_yield=value,
|
61
|
+
is_yield_0=is_yield_0)
|
34
62
|
|
35
|
-
should_run =
|
63
|
+
should_run = any([share_is_0, revenue_is_0, is_yield_0])
|
36
64
|
logShouldRun(cycle, MODEL, term_id, should_run, key=MODEL_KEY, by='economicValueShare')
|
37
65
|
return should_run
|
38
66
|
|
39
67
|
|
40
|
-
def _should_run_product(product: dict): return product.get(MODEL_KEY) is None
|
41
|
-
|
42
|
-
|
43
68
|
def run(cycle: dict):
|
44
|
-
products = list(filter(
|
69
|
+
products = list(filter(lambda p: p.get(MODEL_KEY) is None, cycle.get('products', [])))
|
45
70
|
return non_empty_list([
|
46
71
|
(
|
47
|
-
_product(p, 0) if
|
72
|
+
_product(p, 0) if _should_run_product(cycle, p) else None
|
48
73
|
) for p in products
|
49
74
|
])
|
@@ -1,22 +1,19 @@
|
|
1
1
|
from hestia_earth.schema import EmissionMethodTier
|
2
|
+
from hestia_earth.utils.model import find_term_match
|
3
|
+
from hestia_earth.utils.tools import list_sum
|
2
4
|
|
3
5
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
4
6
|
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
5
7
|
from hestia_earth.models.utils.emission import _new_emission
|
6
|
-
from hestia_earth.models.utils.input import total_excreta
|
7
|
-
from hestia_earth.models.utils.excretaManagement import get_lookup_factor
|
8
8
|
from . import MODEL
|
9
9
|
|
10
10
|
REQUIREMENTS = {
|
11
11
|
"Cycle": {
|
12
|
-
"
|
13
|
-
{"@type": "
|
12
|
+
"emissions": [
|
13
|
+
{"@type": "Emission", "value": "", "term.@id": "n2OToAirExcretaDirect"}
|
14
14
|
]
|
15
15
|
}
|
16
16
|
}
|
17
|
-
LOOKUPS = {
|
18
|
-
"excretaManagement": "EF_NO-N"
|
19
|
-
}
|
20
17
|
RETURNS = {
|
21
18
|
"Emission": [{
|
22
19
|
"value": "",
|
@@ -25,6 +22,7 @@ RETURNS = {
|
|
25
22
|
}
|
26
23
|
TERM_ID = 'noxToAirExcreta'
|
27
24
|
TIER = EmissionMethodTier.TIER_1.value
|
25
|
+
N2O_TERM_ID = 'n2OToAirExcretaDirect'
|
28
26
|
|
29
27
|
|
30
28
|
def _emission(value: float):
|
@@ -34,24 +32,22 @@ def _emission(value: float):
|
|
34
32
|
return emission
|
35
33
|
|
36
34
|
|
37
|
-
def _run(
|
38
|
-
value =
|
35
|
+
def _run(n2o: dict):
|
36
|
+
value = 0.1 * list_sum(n2o.get("value", [])) / get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
37
|
+
value = value * get_atomic_conversion(Units.KG_NOX, Units.TO_N)
|
39
38
|
return [_emission(value)]
|
40
39
|
|
41
40
|
|
42
41
|
def _should_run(cycle: dict):
|
43
|
-
|
44
|
-
NO_N_EF = get_lookup_factor(cycle.get('practices', []), LOOKUPS['excretaManagement'])
|
42
|
+
n2o = find_term_match(cycle.get('emissions', []), N2O_TERM_ID)
|
45
43
|
|
46
|
-
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
47
|
-
excretaKgN=excretaKgN,
|
48
|
-
NO_N_EF=NO_N_EF)
|
44
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID, has_n2o=n2o is not None)
|
49
45
|
|
50
|
-
should_run = all([
|
46
|
+
should_run = all([n2o])
|
51
47
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
52
|
-
return should_run,
|
48
|
+
return should_run, n2o
|
53
49
|
|
54
50
|
|
55
51
|
def run(cycle: dict):
|
56
|
-
should_run,
|
57
|
-
return _run(
|
52
|
+
should_run, n2o = _should_run(cycle)
|
53
|
+
return _run(n2o) if should_run else []
|
@@ -79,7 +79,7 @@ def _emission(term_id: str, value: float, input: dict):
|
|
79
79
|
return emission
|
80
80
|
|
81
81
|
|
82
|
-
def _add_emission(cycle: dict, input: dict):
|
82
|
+
def _add_emission(cycle: dict, input: dict, **extra_logs):
|
83
83
|
input_term_id = input.get('term', {}).get('@id')
|
84
84
|
operation_term_id = input.get('operation', {}).get('@id')
|
85
85
|
animal_term_id = input.get('animal', {}).get('@id')
|
@@ -89,7 +89,7 @@ def _add_emission(cycle: dict, input: dict):
|
|
89
89
|
emissions = ecoinventV3_emissions(ecoinventName)
|
90
90
|
for emission_term_id, value in emissions:
|
91
91
|
# log run on each emission so we know it did run
|
92
|
-
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, emission_id=emission_term_id)
|
92
|
+
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, emission_id=emission_term_id, **extra_logs)
|
93
93
|
debugValues(cycle, model=MODEL, term=emission_term_id,
|
94
94
|
value=value,
|
95
95
|
coefficient=coefficient,
|
@@ -112,6 +112,10 @@ def _run_input(cycle: dict):
|
|
112
112
|
mappings = get_input_mappings(MODEL, cycle, input)
|
113
113
|
has_mappings = len(mappings) > 0
|
114
114
|
|
115
|
+
# grouping the inputs together in the logs
|
116
|
+
input_parent_term_id = input.get('parent', {}).get('@id')
|
117
|
+
extra_logs = {'input_group_id': input_parent_term_id} if input_parent_term_id else {}
|
118
|
+
|
115
119
|
# skip input that has background emissions we have already gap-filled (model run before)
|
116
120
|
has_no_gap_filled_background_emissions = no_gap_filled_background_emissions_func(input)
|
117
121
|
|
@@ -119,13 +123,14 @@ def _run_input(cycle: dict):
|
|
119
123
|
has_ecoinvent_mappings=has_mappings,
|
120
124
|
ecoinvent_mappings=';'.join([v[0] for v in mappings]),
|
121
125
|
has_no_gap_filled_background_emissions=has_no_gap_filled_background_emissions,
|
122
|
-
input_value=input_value
|
126
|
+
input_value=input_value,
|
127
|
+
**extra_logs)
|
123
128
|
|
124
129
|
should_run = all([has_mappings, has_no_gap_filled_background_emissions, input_value])
|
125
|
-
logShouldRun(cycle, MODEL, input_term_id, should_run, methodTier=TIER)
|
130
|
+
logShouldRun(cycle, MODEL, input_term_id, should_run, methodTier=TIER, **extra_logs)
|
126
131
|
|
127
|
-
grouped_emissions = reduce(_add_emission(cycle, input), mappings, {}) if should_run else {}
|
128
|
-
log_missing_emissions_func(input_term_id, list(grouped_emissions.keys()))
|
132
|
+
grouped_emissions = reduce(_add_emission(cycle, input, **extra_logs), mappings, {}) if should_run else {}
|
133
|
+
log_missing_emissions_func(input_term_id, list(grouped_emissions.keys()), **extra_logs)
|
129
134
|
return [
|
130
135
|
_emission(term_id, value * input_value, input)
|
131
136
|
for term_id, value in grouped_emissions.items()
|
@@ -19,4 +19,4 @@ def get_input_coefficient(model: str, cycle: dict, country_id: str, ecoinventNam
|
|
19
19
|
# find the ratio for the country / year
|
20
20
|
data = get_region_lookup_value(REGION_EMBER_SOURCES_LOOKUP_NAME, country_id, source_name, model=model)
|
21
21
|
percentage = extract_grouped_data(data, str(year))
|
22
|
-
return safe_parse_float(percentage, 0) / 100
|
22
|
+
return safe_parse_float(percentage, default=0) / 100
|
@@ -95,7 +95,8 @@ def group_fuel_inputs(inputs: list):
|
|
95
95
|
|
96
96
|
def _get_emissions_factor(animal: dict, lookup_col: str) -> float:
|
97
97
|
return safe_parse_float(
|
98
|
-
get_lookup_value(animal.get("term", {}), lookup_col, model=MODEL, term=animal.get("term", ""))
|
98
|
+
get_lookup_value(animal.get("term", {}), lookup_col, model=MODEL, term=animal.get("term", "")),
|
99
|
+
default=None
|
99
100
|
)
|
100
101
|
|
101
102
|
|
@@ -55,7 +55,7 @@ def _product_value(product: dict, year: int, country_id: str):
|
|
55
55
|
groupingFAO = get_animalProduct_lookup_value(MODEL, product_id, FAO_LOOKUP_COLUMN)
|
56
56
|
|
57
57
|
data = get_region_lookup_value(LOOKUP_WEIGHT, country_id, groupingFAO, model=MODEL, term=TERM_ID)
|
58
|
-
average_carcass_weight = safe_parse_float(extract_grouped_data_closest_date(data, year), None)
|
58
|
+
average_carcass_weight = safe_parse_float(extract_grouped_data_closest_date(data, year), default=None)
|
59
59
|
# average_carcass_weight is in hg, divide by 10 to go back to kg
|
60
60
|
kg_carcass_weight = average_carcass_weight / 10 if average_carcass_weight else None
|
61
61
|
|