hestia-earth-models 0.59.1__py3-none-any.whl → 0.59.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hestia-earth-models might be problematic. Click here for more details.
- hestia_earth/models/cycle/irrigatedTypeUnspecified.py +6 -7
- hestia_earth/models/impact_assessment/irrigated.py +4 -1
- hestia_earth/models/ipcc2006/n2OToAirCropResidueDecompositionDirect.py +83 -0
- hestia_earth/models/ipcc2006/n2OToAirCropResidueDecompositionIndirect.py +3 -3
- hestia_earth/models/ipcc2006/n2OToAirExcretaIndirect.py +3 -3
- hestia_earth/models/ipcc2006/n2OToAirInorganicFertiliserIndirect.py +5 -4
- hestia_earth/models/ipcc2006/n2OToAirOrganicFertiliserIndirect.py +5 -4
- hestia_earth/models/ipcc2006/utils.py +12 -16
- hestia_earth/models/ipcc2019/n2OToAirCropResidueDecompositionDirect.py +8 -7
- hestia_earth/models/ipcc2019/n2OToAirCropResidueDecompositionIndirect.py +100 -0
- hestia_earth/models/ipcc2019/n2OToAirExcretaIndirect.py +100 -0
- hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserIndirect.py +54 -61
- hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserIndirect.py +58 -66
- hestia_earth/models/ipcc2019/nh3ToAirInorganicFertiliser.py +112 -0
- hestia_earth/models/ipcc2019/nh3ToAirOrganicFertiliser.py +107 -0
- hestia_earth/models/ipcc2019/noxToAirInorganicFertiliser.py +112 -0
- hestia_earth/models/ipcc2019/noxToAirOrganicFertiliser.py +107 -0
- hestia_earth/models/ipcc2019/organicCarbonPerHa.py +67 -21
- hestia_earth/models/ipcc2019/utils.py +28 -16
- hestia_earth/models/site/soilMeasurement.py +197 -0
- hestia_earth/models/utils/cycle.py +7 -6
- hestia_earth/models/utils/emission.py +15 -0
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.59.1.dist-info → hestia_earth_models-0.59.3.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.59.1.dist-info → hestia_earth_models-0.59.3.dist-info}/RECORD +40 -24
- tests/models/ipcc2006/test_n2OToAirCropResidueDecompositionDirect.py +50 -0
- tests/models/ipcc2019/test_n2OToAirCropResidueDecompositionIndirect.py +71 -0
- tests/models/ipcc2019/test_n2OToAirExcretaIndirect.py +71 -0
- tests/models/ipcc2019/test_n2OToAirInorganicFertiliserIndirect.py +36 -13
- tests/models/ipcc2019/test_n2OToAirOrganicFertiliserIndirect.py +36 -13
- tests/models/ipcc2019/test_nh3ToAirInorganicFertiliser.py +47 -0
- tests/models/ipcc2019/test_nh3ToAirOrganicFertiliser.py +35 -0
- tests/models/ipcc2019/test_noxToAirInorganicFertiliser.py +47 -0
- tests/models/ipcc2019/test_noxToAirOrganicFertiliser.py +35 -0
- tests/models/ipcc2019/test_organicCarbonPerHa.py +51 -5
- tests/models/site/test_soilMeasurement.py +159 -0
- tests/models/utils/test_blank_node.py +5 -5
- {hestia_earth_models-0.59.1.dist-info → hestia_earth_models-0.59.3.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.59.1.dist-info → hestia_earth_models-0.59.3.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.59.1.dist-info → hestia_earth_models-0.59.3.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from hestia_earth.schema import TermTermType, CycleFunctionalUnit
|
|
2
|
-
from hestia_earth.utils.model import filter_list_term_type
|
|
3
2
|
|
|
4
3
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
4
|
+
from hestia_earth.models.utils.cycle import is_irrigated
|
|
5
5
|
from hestia_earth.models.utils.practice import _new_practice
|
|
6
6
|
from hestia_earth.models.utils.input import get_total_irrigation_m3
|
|
7
7
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
@@ -12,7 +12,7 @@ REQUIREMENTS = {
|
|
|
12
12
|
"completeness.water": "",
|
|
13
13
|
"functionalUnit": "1 ha",
|
|
14
14
|
"none": {
|
|
15
|
-
"practices": [{"@type": "Practice", "
|
|
15
|
+
"practices": [{"@type": "Practice", "value": "> 0", "term.termType": "waterRegime"}]
|
|
16
16
|
},
|
|
17
17
|
"optional": {
|
|
18
18
|
"inputs": [{"@type": "Input", "term.termType": "water", "value": ""}]
|
|
@@ -24,6 +24,9 @@ RETURNS = {
|
|
|
24
24
|
"value": ""
|
|
25
25
|
}]
|
|
26
26
|
}
|
|
27
|
+
LOOKUPS = {
|
|
28
|
+
"waterRegime": "irrigated"
|
|
29
|
+
}
|
|
27
30
|
TERM_ID = 'irrigatedTypeUnspecified'
|
|
28
31
|
MIN_IRRIGATION_M3 = 250
|
|
29
32
|
|
|
@@ -34,9 +37,6 @@ def _practice(value: float):
|
|
|
34
37
|
return practice
|
|
35
38
|
|
|
36
39
|
|
|
37
|
-
def _is_irrigation_practice(practice: dict): return practice.get('term', {}).get('units', '') in ['%', '% area']
|
|
38
|
-
|
|
39
|
-
|
|
40
40
|
def _run(irrigation_m3: float):
|
|
41
41
|
value = 100 if irrigation_m3 > MIN_IRRIGATION_M3 else 0
|
|
42
42
|
return [_practice(value)]
|
|
@@ -47,8 +47,7 @@ def _should_run(cycle: dict):
|
|
|
47
47
|
water_complete = _is_term_type_complete(cycle, TermTermType.WATER)
|
|
48
48
|
irrigation_value_m3 = get_total_irrigation_m3(cycle)
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
no_irrigation_practice = not any(map(_is_irrigation_practice, water_regime))
|
|
50
|
+
no_irrigation_practice = not is_irrigated(cycle, model=MODEL, term=TERM_ID)
|
|
52
51
|
|
|
53
52
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
54
53
|
no_irrigation_practice=no_irrigation_practice,
|
|
@@ -18,10 +18,13 @@ REQUIREMENTS = {
|
|
|
18
18
|
RETURNS = {
|
|
19
19
|
"`true` if the `Cycle` was irrigated, `false` otherwise": ""
|
|
20
20
|
}
|
|
21
|
+
LOOKUPS = {
|
|
22
|
+
"waterRegime": "irrigated"
|
|
23
|
+
}
|
|
21
24
|
MODEL_KEY = 'irrigated'
|
|
22
25
|
|
|
23
26
|
|
|
24
27
|
def run(impact: dict):
|
|
25
|
-
value = is_irrigated(impact.get('cycle', {}))
|
|
28
|
+
value = is_irrigated(impact.get('cycle', {}), model=MODEL, model_key=MODEL_KEY)
|
|
26
29
|
logger.debug('model=%s, key=%s, value=%s', MODEL, MODEL_KEY, value)
|
|
27
30
|
return value
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
|
2
|
+
|
|
3
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, debugValues, log_as_table
|
|
4
|
+
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
5
|
+
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
6
|
+
from hestia_earth.models.utils.emission import _new_emission
|
|
7
|
+
from hestia_earth.models.utils.cycle import get_crop_residue_decomposition_N_total
|
|
8
|
+
from hestia_earth.models.utils.product import has_flooded_rice
|
|
9
|
+
from .utils import N2O_FACTORS
|
|
10
|
+
from . import MODEL
|
|
11
|
+
|
|
12
|
+
REQUIREMENTS = {
|
|
13
|
+
"Cycle": {
|
|
14
|
+
"completeness.cropResidue": "True",
|
|
15
|
+
"products": [{
|
|
16
|
+
"@type": "Product",
|
|
17
|
+
"value": "",
|
|
18
|
+
"term.termType": "cropResidue",
|
|
19
|
+
"properties": [{"@type": "Property", "value": "", "term.@id": "nitrogenContent"}]
|
|
20
|
+
}],
|
|
21
|
+
"optional": {
|
|
22
|
+
"products": [{"@type": "Product", "term.@id": "riceGrainInHuskFlooded"}]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
RETURNS = {
|
|
27
|
+
"Emission": [{
|
|
28
|
+
"value": "",
|
|
29
|
+
"min": "",
|
|
30
|
+
"max": "",
|
|
31
|
+
"methodTier": "tier 1",
|
|
32
|
+
"statsDefinition": "modelled"
|
|
33
|
+
}]
|
|
34
|
+
}
|
|
35
|
+
LOOKUPS = {
|
|
36
|
+
"cropResidue": "decomposesOnField"
|
|
37
|
+
}
|
|
38
|
+
TERM_ID = 'n2OToAirCropResidueDecompositionDirect'
|
|
39
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _emission(value: float, min: float, max: float):
|
|
43
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
44
|
+
emission['value'] = [value]
|
|
45
|
+
emission['min'] = [min]
|
|
46
|
+
emission['max'] = [max]
|
|
47
|
+
emission['methodTier'] = TIER
|
|
48
|
+
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
49
|
+
return emission
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _run(cycle: dict, N_total: float):
|
|
53
|
+
flooded_rice = has_flooded_rice(cycle.get('products', []))
|
|
54
|
+
|
|
55
|
+
converted_N_total = N_total * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
56
|
+
factors = N2O_FACTORS['flooded_rice'] if flooded_rice else N2O_FACTORS['default']
|
|
57
|
+
|
|
58
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
59
|
+
has_flooded_rice=flooded_rice,
|
|
60
|
+
factors_used=log_as_table(factors))
|
|
61
|
+
|
|
62
|
+
value = converted_N_total * factors['value']
|
|
63
|
+
min = converted_N_total * factors['min']
|
|
64
|
+
max = converted_N_total * factors['max']
|
|
65
|
+
return [_emission(value, min, max)]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def _should_run(cycle: dict):
|
|
69
|
+
term_type_complete = _is_term_type_complete(cycle, TermTermType.CROPRESIDUE)
|
|
70
|
+
N_crop_residue = get_crop_residue_decomposition_N_total(cycle)
|
|
71
|
+
|
|
72
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
73
|
+
term_type_cropResidue_complete=term_type_complete,
|
|
74
|
+
N_crop_residue=N_crop_residue)
|
|
75
|
+
|
|
76
|
+
should_run = all([N_crop_residue is not None, term_type_complete])
|
|
77
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
78
|
+
return should_run, N_crop_residue
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def run(cycle: dict):
|
|
82
|
+
should_run, N_total = _should_run(cycle)
|
|
83
|
+
return _run(cycle, N_total) if should_run else []
|
|
@@ -3,8 +3,8 @@ from hestia_earth.schema import EmissionMethodTier, TermTermType
|
|
|
3
3
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
4
4
|
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
5
5
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
6
|
-
from hestia_earth.models.utils.emission import _new_emission
|
|
7
|
-
from .utils import
|
|
6
|
+
from hestia_earth.models.utils.emission import _new_emission, get_nh3_no3_nox_to_n
|
|
7
|
+
from .utils import COEFF_NH3NOX_N2O, COEFF_NO3_N2O
|
|
8
8
|
from . import MODEL
|
|
9
9
|
|
|
10
10
|
REQUIREMENTS = {
|
|
@@ -43,7 +43,7 @@ def _run(no3: float, nh3: float, nox: float):
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
def _should_run(cycle: dict):
|
|
46
|
-
nh3_n, no3_n, nox_n = get_nh3_no3_nox_to_n(cycle, NH3_TERM_ID, NO3_TERM_ID, NOX_TERM_ID
|
|
46
|
+
nh3_n, no3_n, nox_n = get_nh3_no3_nox_to_n(cycle, NH3_TERM_ID, NO3_TERM_ID, NOX_TERM_ID)
|
|
47
47
|
term_type_complete = _is_term_type_complete(cycle, TermTermType.CROPRESIDUE)
|
|
48
48
|
|
|
49
49
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
@@ -3,8 +3,8 @@ from hestia_earth.schema import EmissionMethodTier, TermTermType
|
|
|
3
3
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
4
4
|
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
5
5
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
6
|
-
from hestia_earth.models.utils.emission import _new_emission
|
|
7
|
-
from .utils import
|
|
6
|
+
from hestia_earth.models.utils.emission import _new_emission, get_nh3_no3_nox_to_n
|
|
7
|
+
from .utils import COEFF_NH3NOX_N2O, COEFF_NO3_N2O
|
|
8
8
|
from . import MODEL
|
|
9
9
|
|
|
10
10
|
REQUIREMENTS = {
|
|
@@ -43,7 +43,7 @@ def _run(no3_n: float, nh3_n: float, nox_n: float):
|
|
|
43
43
|
|
|
44
44
|
|
|
45
45
|
def _should_run(cycle: dict):
|
|
46
|
-
nh3_n, no3_n, nox_n = get_nh3_no3_nox_to_n(cycle, NH3_TERM_ID, NO3_TERM_ID, NOX_TERM_ID
|
|
46
|
+
nh3_n, no3_n, nox_n = get_nh3_no3_nox_to_n(cycle, NH3_TERM_ID, NO3_TERM_ID, NOX_TERM_ID)
|
|
47
47
|
term_type_complete = _is_term_type_complete(cycle, TermTermType.EXCRETA)
|
|
48
48
|
|
|
49
49
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from hestia_earth.schema import EmissionMethodTier
|
|
2
2
|
|
|
3
3
|
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
|
4
|
+
from hestia_earth.models.utils import sum_values
|
|
4
5
|
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
5
6
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
6
7
|
from hestia_earth.models.utils.cycle import get_inorganic_fertiliser_N_total
|
|
7
|
-
from hestia_earth.models.utils.emission import _new_emission
|
|
8
|
-
from .utils import
|
|
8
|
+
from hestia_earth.models.utils.emission import _new_emission, get_nh3_no3_nox_to_n
|
|
9
|
+
from .utils import COEFF_NH3NOX_N2O, COEFF_NO3_N2O
|
|
9
10
|
from . import MODEL
|
|
10
11
|
|
|
11
12
|
REQUIREMENTS = {
|
|
@@ -54,9 +55,9 @@ def _run(cycle: dict, N_total: float):
|
|
|
54
55
|
nh3_n=nh3_n,
|
|
55
56
|
nox_n=nox_n)
|
|
56
57
|
value = COEFF_NH3NOX_N2O * (
|
|
57
|
-
|
|
58
|
+
sum_values([nh3_n, nox_n]) or N_total * 0.2
|
|
58
59
|
) + COEFF_NO3_N2O * (
|
|
59
|
-
N_total * 0.3
|
|
60
|
+
no3_n or N_total * 0.3
|
|
60
61
|
)
|
|
61
62
|
return [_emission(value * get_atomic_conversion(Units.KG_N2O, Units.TO_N))]
|
|
62
63
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
from hestia_earth.schema import EmissionMethodTier
|
|
2
2
|
|
|
3
3
|
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
|
4
|
+
from hestia_earth.models.utils import sum_values
|
|
4
5
|
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
5
6
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
6
7
|
from hestia_earth.models.utils.cycle import get_organic_fertiliser_N_total
|
|
7
|
-
from hestia_earth.models.utils.emission import _new_emission
|
|
8
|
-
from .utils import
|
|
8
|
+
from hestia_earth.models.utils.emission import _new_emission, get_nh3_no3_nox_to_n
|
|
9
|
+
from .utils import COEFF_NH3NOX_N2O, COEFF_NO3_N2O
|
|
9
10
|
from . import MODEL
|
|
10
11
|
|
|
11
12
|
REQUIREMENTS = {
|
|
@@ -53,9 +54,9 @@ def _run(cycle: dict, N_total: float):
|
|
|
53
54
|
nh3_n=nh3_n,
|
|
54
55
|
nox_n=nox_n)
|
|
55
56
|
value = COEFF_NH3NOX_N2O * (
|
|
56
|
-
|
|
57
|
+
sum_values([nh3_n, nox_n]) or N_total * 0.2
|
|
57
58
|
) + COEFF_NO3_N2O * (
|
|
58
|
-
N_total * 0.3
|
|
59
|
+
no3_n or N_total * 0.3
|
|
59
60
|
)
|
|
60
61
|
return [_emission(value * get_atomic_conversion(Units.KG_N2O, Units.TO_N))]
|
|
61
62
|
|
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
from hestia_earth.utils.model import find_primary_product
|
|
2
2
|
|
|
3
|
-
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
4
|
-
from hestia_earth.models.utils.blank_node import find_terms_value
|
|
5
|
-
|
|
6
3
|
COEFF_NH3NOX_N2O = 0.01
|
|
7
4
|
COEFF_NO3_N2O = 0.0075
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return (nh3, no3, nox)
|
|
5
|
+
N2O_FACTORS = {
|
|
6
|
+
'default': {
|
|
7
|
+
'value': 0.01,
|
|
8
|
+
'min': 0.003,
|
|
9
|
+
'max': 0.03
|
|
10
|
+
},
|
|
11
|
+
'flooded_rice': {
|
|
12
|
+
'value': 0.003,
|
|
13
|
+
'min': 0,
|
|
14
|
+
'max': 0.006
|
|
15
|
+
}
|
|
16
|
+
}
|
|
21
17
|
|
|
22
18
|
|
|
23
19
|
def get_N_N2O_excreta_coeff_from_primary_product(cycle: dict):
|
|
@@ -62,13 +62,16 @@ def _emission(value: float, min: float, max: float, sd: float, aggregated: bool
|
|
|
62
62
|
return emission
|
|
63
63
|
|
|
64
64
|
|
|
65
|
-
def _run(cycle: dict, N_total: float,
|
|
65
|
+
def _run(cycle: dict, N_total: float, flooded_rice: bool = False):
|
|
66
|
+
ecoClimateZone = get_ecoClimateZone(cycle)
|
|
67
|
+
|
|
66
68
|
converted_N_total = N_total * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
67
69
|
factors, aggregated = get_N2O_factors(
|
|
68
70
|
TERM_ID, cycle, TermTermType.CROPRESIDUE, ecoClimateZone=ecoClimateZone, flooded_rice=flooded_rice
|
|
69
71
|
)
|
|
70
72
|
|
|
71
73
|
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
74
|
+
ecoClimateZone=ecoClimateZone,
|
|
72
75
|
factors_used=log_as_table(factors),
|
|
73
76
|
aggregated=aggregated)
|
|
74
77
|
|
|
@@ -82,21 +85,19 @@ def _run(cycle: dict, N_total: float, ecoClimateZone: str = None, flooded_rice:
|
|
|
82
85
|
def _should_run(cycle: dict):
|
|
83
86
|
term_type_complete = _is_term_type_complete(cycle, TermTermType.CROPRESIDUE)
|
|
84
87
|
N_crop_residue = get_crop_residue_decomposition_N_total(cycle)
|
|
85
|
-
ecoClimateZone = get_ecoClimateZone(cycle)
|
|
86
88
|
|
|
87
89
|
flooded_rice = has_flooded_rice(cycle.get('products', []))
|
|
88
90
|
|
|
89
91
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
90
92
|
term_type_cropResidue_complete=term_type_complete,
|
|
91
93
|
N_crop_residue=N_crop_residue,
|
|
92
|
-
has_flooded_rice=flooded_rice
|
|
93
|
-
ecoClimateZone=ecoClimateZone)
|
|
94
|
+
has_flooded_rice=flooded_rice)
|
|
94
95
|
|
|
95
96
|
should_run = all([N_crop_residue is not None, term_type_complete])
|
|
96
97
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
97
|
-
return should_run, N_crop_residue,
|
|
98
|
+
return should_run, N_crop_residue, flooded_rice
|
|
98
99
|
|
|
99
100
|
|
|
100
101
|
def run(cycle: dict):
|
|
101
|
-
should_run, N_total,
|
|
102
|
-
return _run(cycle, N_total,
|
|
102
|
+
should_run, N_total, flooded_rice = _should_run(cycle)
|
|
103
|
+
return _run(cycle, N_total, flooded_rice) if should_run else []
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
|
2
|
+
|
|
3
|
+
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun, log_as_table
|
|
4
|
+
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
5
|
+
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
6
|
+
from hestia_earth.models.utils.emission import _new_emission, get_nh3_no3_nox_to_n
|
|
7
|
+
from hestia_earth.models.utils.cycle import get_ecoClimateZone
|
|
8
|
+
from .utils import ecoClimate_factors, EF4_FACTORS, EF5_FACTORS
|
|
9
|
+
from . import MODEL
|
|
10
|
+
|
|
11
|
+
REQUIREMENTS = {
|
|
12
|
+
"Cycle": {
|
|
13
|
+
"completeness.cropResidue": "True",
|
|
14
|
+
"emissions": [
|
|
15
|
+
{"@type": "Emission", "value": "", "term.@id": "no3ToGroundwaterCropResidueDecomposition"},
|
|
16
|
+
{"@type": "Emission", "value": "", "term.@id": "nh3ToAirCropResidueDecomposition"},
|
|
17
|
+
{"@type": "Emission", "value": "", "term.@id": "noxToAirCropResidueDecomposition"}
|
|
18
|
+
],
|
|
19
|
+
"optional": {
|
|
20
|
+
"site": {
|
|
21
|
+
"@type": "Site",
|
|
22
|
+
"measurements": [
|
|
23
|
+
{"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
RETURNS = {
|
|
30
|
+
"Emission": [{
|
|
31
|
+
"value": "",
|
|
32
|
+
"methodTier": "tier 1"
|
|
33
|
+
}]
|
|
34
|
+
}
|
|
35
|
+
TERM_ID = 'n2OToAirCropResidueDecompositionIndirect'
|
|
36
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
37
|
+
NO3_TERM_ID = 'no3ToGroundwaterCropResidueDecomposition'
|
|
38
|
+
NH3_TERM_ID = 'nh3ToAirCropResidueDecomposition'
|
|
39
|
+
NOX_TERM_ID = 'noxToAirCropResidueDecomposition'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _emission(value: float, min: float, max: float, aggregated: bool = False):
|
|
43
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
44
|
+
emission['value'] = [value]
|
|
45
|
+
emission['min'] = [min]
|
|
46
|
+
emission['max'] = [max]
|
|
47
|
+
emission['methodTier'] = TIER
|
|
48
|
+
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
49
|
+
emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
|
|
50
|
+
return emission
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _run(cycle: dict, no3: float, nh3: float, nox: float):
|
|
54
|
+
ecoClimateZone = get_ecoClimateZone(cycle)
|
|
55
|
+
|
|
56
|
+
ef4, aggregated = ecoClimate_factors(EF4_FACTORS, ecoClimateZone=ecoClimateZone)
|
|
57
|
+
ef5 = EF5_FACTORS.get('default')
|
|
58
|
+
|
|
59
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
60
|
+
ecoClimateZone=ecoClimateZone,
|
|
61
|
+
ef4_factors_used=log_as_table(ef4),
|
|
62
|
+
ef5_factors_used=log_as_table(ef5),
|
|
63
|
+
aggregated=aggregated)
|
|
64
|
+
|
|
65
|
+
value = sum([
|
|
66
|
+
no3 * ef5['value'],
|
|
67
|
+
nh3 * ef4['value'],
|
|
68
|
+
nox * ef4['value']
|
|
69
|
+
]) * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
70
|
+
min = sum([
|
|
71
|
+
no3 * ef5['min'],
|
|
72
|
+
nh3 * ef4['min'],
|
|
73
|
+
nox * ef4['min']
|
|
74
|
+
]) * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
75
|
+
max = sum([
|
|
76
|
+
no3 * ef5['max'],
|
|
77
|
+
nh3 * ef4['max'],
|
|
78
|
+
nox * ef4['max']
|
|
79
|
+
]) * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
80
|
+
return [_emission(value, min, max, aggregated=aggregated)]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _should_run(cycle: dict):
|
|
84
|
+
nh3_n, no3_n, nox_n = get_nh3_no3_nox_to_n(cycle, NH3_TERM_ID, NO3_TERM_ID, NOX_TERM_ID)
|
|
85
|
+
term_type_complete = _is_term_type_complete(cycle, TermTermType.CROPRESIDUE)
|
|
86
|
+
|
|
87
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
88
|
+
no3_n=no3_n,
|
|
89
|
+
nh3_n=nh3_n,
|
|
90
|
+
nox_n=nox_n,
|
|
91
|
+
term_type_cropResidue_complete=term_type_complete)
|
|
92
|
+
|
|
93
|
+
should_run = all([no3_n is not None, nh3_n is not None, nox_n is not None, term_type_complete])
|
|
94
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
95
|
+
return should_run, no3_n, nh3_n, nox_n
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def run(cycle: dict):
|
|
99
|
+
should_run, no3, nh3, nox = _should_run(cycle)
|
|
100
|
+
return _run(cycle, no3, nh3, nox) if should_run else []
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
|
2
|
+
|
|
3
|
+
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun, log_as_table
|
|
4
|
+
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
5
|
+
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
6
|
+
from hestia_earth.models.utils.emission import _new_emission, get_nh3_no3_nox_to_n
|
|
7
|
+
from hestia_earth.models.utils.cycle import get_ecoClimateZone
|
|
8
|
+
from .utils import ecoClimate_factors, EF4_FACTORS, EF5_FACTORS
|
|
9
|
+
from . import MODEL
|
|
10
|
+
|
|
11
|
+
REQUIREMENTS = {
|
|
12
|
+
"Cycle": {
|
|
13
|
+
"completeness.excreta": "True",
|
|
14
|
+
"emissions": [
|
|
15
|
+
{"@type": "Emission", "value": "", "term.@id": "no3ToGroundwaterExcreta"},
|
|
16
|
+
{"@type": "Emission", "value": "", "term.@id": "nh3ToAirExcreta"},
|
|
17
|
+
{"@type": "Emission", "value": "", "term.@id": "noxToAirExcreta"}
|
|
18
|
+
],
|
|
19
|
+
"optional": {
|
|
20
|
+
"site": {
|
|
21
|
+
"@type": "Site",
|
|
22
|
+
"measurements": [
|
|
23
|
+
{"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
RETURNS = {
|
|
30
|
+
"Emission": [{
|
|
31
|
+
"value": "",
|
|
32
|
+
"methodTier": "tier 1"
|
|
33
|
+
}]
|
|
34
|
+
}
|
|
35
|
+
TERM_ID = 'n2OToAirExcretaIndirect'
|
|
36
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
37
|
+
NO3_TERM_ID = 'no3ToGroundwaterExcreta'
|
|
38
|
+
NH3_TERM_ID = 'nh3ToAirExcreta'
|
|
39
|
+
NOX_TERM_ID = 'noxToAirExcreta'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _emission(value: float, min: float, max: float, aggregated: bool = False):
|
|
43
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
44
|
+
emission['value'] = [value]
|
|
45
|
+
emission['min'] = [min]
|
|
46
|
+
emission['max'] = [max]
|
|
47
|
+
emission['methodTier'] = TIER
|
|
48
|
+
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
49
|
+
emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
|
|
50
|
+
return emission
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _run(cycle: dict, no3: float, nh3: float, nox: float):
|
|
54
|
+
ecoClimateZone = get_ecoClimateZone(cycle)
|
|
55
|
+
|
|
56
|
+
ef4, aggregated = ecoClimate_factors(EF4_FACTORS, ecoClimateZone=ecoClimateZone)
|
|
57
|
+
ef5 = EF5_FACTORS.get('default')
|
|
58
|
+
|
|
59
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
60
|
+
ecoClimateZone=ecoClimateZone,
|
|
61
|
+
ef4_factors_used=log_as_table(ef4),
|
|
62
|
+
ef5_factors_used=log_as_table(ef5),
|
|
63
|
+
aggregated=aggregated)
|
|
64
|
+
|
|
65
|
+
value = sum([
|
|
66
|
+
no3 * ef5['value'],
|
|
67
|
+
nh3 * ef4['value'],
|
|
68
|
+
nox * ef4['value']
|
|
69
|
+
]) * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
70
|
+
min = sum([
|
|
71
|
+
no3 * ef5['min'],
|
|
72
|
+
nh3 * ef4['min'],
|
|
73
|
+
nox * ef4['min']
|
|
74
|
+
]) * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
75
|
+
max = sum([
|
|
76
|
+
no3 * ef5['max'],
|
|
77
|
+
nh3 * ef4['max'],
|
|
78
|
+
nox * ef4['max']
|
|
79
|
+
]) * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
80
|
+
return [_emission(value, min, max, aggregated=aggregated)]
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _should_run(cycle: dict):
|
|
84
|
+
nh3_n, no3_n, nox_n = get_nh3_no3_nox_to_n(cycle, NH3_TERM_ID, NO3_TERM_ID, NOX_TERM_ID)
|
|
85
|
+
term_type_complete = _is_term_type_complete(cycle, TermTermType.EXCRETA)
|
|
86
|
+
|
|
87
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
88
|
+
no3_n=no3_n,
|
|
89
|
+
nh3_n=nh3_n,
|
|
90
|
+
nox_n=nox_n,
|
|
91
|
+
term_type_cropResidue_complete=term_type_complete)
|
|
92
|
+
|
|
93
|
+
should_run = all([no3_n is not None, nh3_n is not None, nox_n is not None, term_type_complete])
|
|
94
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
95
|
+
return should_run, no3_n, nh3_n, nox_n
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def run(cycle: dict):
|
|
99
|
+
should_run, no3, nh3, nox = _should_run(cycle)
|
|
100
|
+
return _run(cycle, no3, nh3, nox) if should_run else []
|