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,107 +1,100 @@
|
|
|
1
|
-
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition
|
|
2
2
|
|
|
3
|
-
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
|
3
|
+
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun, log_as_table
|
|
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.
|
|
7
|
-
from hestia_earth.models.utils.
|
|
8
|
-
from .utils import
|
|
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
9
|
from . import MODEL
|
|
10
10
|
|
|
11
11
|
REQUIREMENTS = {
|
|
12
12
|
"Cycle": {
|
|
13
13
|
"completeness.fertiliser": "True",
|
|
14
|
-
"completeness.water": "True",
|
|
15
|
-
"inputs": [{
|
|
16
|
-
"@type": "Input",
|
|
17
|
-
"value": "",
|
|
18
|
-
"term.units": ["kg", "kg N"],
|
|
19
|
-
"term.termType": "inorganicFertiliser",
|
|
20
|
-
"optional": {
|
|
21
|
-
"properties": [{"@type": "Property", "value": "", "term.@id": "nitrogenContent"}]
|
|
22
|
-
}
|
|
23
|
-
}],
|
|
24
14
|
"emissions": [
|
|
25
15
|
{"@type": "Emission", "value": "", "term.@id": "no3ToGroundwaterInorganicFertiliser"},
|
|
26
16
|
{"@type": "Emission", "value": "", "term.@id": "nh3ToAirInorganicFertiliser"},
|
|
27
17
|
{"@type": "Emission", "value": "", "term.@id": "noxToAirInorganicFertiliser"}
|
|
28
18
|
],
|
|
29
|
-
"site": {
|
|
30
|
-
"@type": "Site",
|
|
31
|
-
"measurements": [{"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}]
|
|
32
|
-
},
|
|
33
19
|
"optional": {
|
|
34
|
-
"
|
|
20
|
+
"site": {
|
|
21
|
+
"@type": "Site",
|
|
22
|
+
"measurements": [
|
|
23
|
+
{"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
35
26
|
}
|
|
36
27
|
}
|
|
37
28
|
}
|
|
38
29
|
RETURNS = {
|
|
39
30
|
"Emission": [{
|
|
40
31
|
"value": "",
|
|
41
|
-
"
|
|
42
|
-
"min": "",
|
|
43
|
-
"max": "",
|
|
44
|
-
"methodTier": "tier 1",
|
|
45
|
-
"statsDefinition": "modelled"
|
|
32
|
+
"methodTier": "tier 1"
|
|
46
33
|
}]
|
|
47
34
|
}
|
|
48
|
-
|
|
49
35
|
TERM_ID = 'n2OToAirInorganicFertiliserIndirect'
|
|
36
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
50
37
|
NO3_TERM_ID = 'no3ToGroundwaterInorganicFertiliser'
|
|
51
38
|
NH3_TERM_ID = 'nh3ToAirInorganicFertiliser'
|
|
52
39
|
NOX_TERM_ID = 'noxToAirInorganicFertiliser'
|
|
53
|
-
TIER = EmissionMethodTier.TIER_1.value
|
|
54
40
|
|
|
55
41
|
|
|
56
|
-
def _emission(value: float,
|
|
42
|
+
def _emission(value: float, min: float, max: float, aggregated: bool = False):
|
|
57
43
|
emission = _new_emission(TERM_ID, MODEL)
|
|
58
44
|
emission['value'] = [value]
|
|
59
|
-
emission['sd'] = [sd]
|
|
60
45
|
emission['min'] = [min]
|
|
61
46
|
emission['max'] = [max]
|
|
62
47
|
emission['methodTier'] = TIER
|
|
63
48
|
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
49
|
+
emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
|
|
64
50
|
return emission
|
|
65
51
|
|
|
66
52
|
|
|
67
|
-
def _run(cycle: dict):
|
|
68
|
-
|
|
69
|
-
|
|
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
|
+
|
|
70
59
|
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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)]
|
|
88
81
|
|
|
89
82
|
|
|
90
83
|
def _should_run(cycle: dict):
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
fertiliser_complete = _is_term_type_complete(cycle, 'fertiliser')
|
|
94
|
-
water_complete = _is_term_type_complete(cycle, TermTermType.WATER)
|
|
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, 'fertiliser')
|
|
95
86
|
|
|
96
87
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
88
|
+
no3_n=no3_n,
|
|
89
|
+
nh3_n=nh3_n,
|
|
90
|
+
nox_n=nox_n,
|
|
91
|
+
term_type_cropResidue_complete=term_type_complete)
|
|
101
92
|
|
|
102
|
-
should_run = all([
|
|
103
|
-
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
|
104
|
-
return should_run
|
|
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
|
|
105
96
|
|
|
106
97
|
|
|
107
|
-
def run(cycle: dict):
|
|
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 []
|
|
@@ -1,108 +1,100 @@
|
|
|
1
|
-
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition
|
|
2
2
|
|
|
3
|
-
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
|
3
|
+
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun, log_as_table
|
|
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.
|
|
7
|
-
from hestia_earth.models.utils.
|
|
8
|
-
from .utils import
|
|
9
|
-
get_FracLEACH_H
|
|
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
|
|
10
9
|
from . import MODEL
|
|
11
10
|
|
|
12
11
|
REQUIREMENTS = {
|
|
13
12
|
"Cycle": {
|
|
14
13
|
"completeness.fertiliser": "True",
|
|
15
|
-
"completeness.water": "True",
|
|
16
|
-
"inputs": [
|
|
17
|
-
{
|
|
18
|
-
"@type": "Input",
|
|
19
|
-
"value": "",
|
|
20
|
-
"term.termType": "organicFertiliser",
|
|
21
|
-
"term.units": "kg N"
|
|
22
|
-
}
|
|
23
|
-
],
|
|
24
14
|
"emissions": [
|
|
25
|
-
{"@type": "Emission", "value": "", "term.@id": "
|
|
26
|
-
{"@type": "Emission", "value": "", "term.@id": "
|
|
27
|
-
{"@type": "Emission", "value": "", "term.@id": "
|
|
15
|
+
{"@type": "Emission", "value": "", "term.@id": "no3ToGroundwaterOrganicFertiliser"},
|
|
16
|
+
{"@type": "Emission", "value": "", "term.@id": "nh3ToAirOrganicFertiliser"},
|
|
17
|
+
{"@type": "Emission", "value": "", "term.@id": "noxToAirOrganicFertiliser"}
|
|
28
18
|
],
|
|
29
|
-
"site": {
|
|
30
|
-
"@type": "Site",
|
|
31
|
-
"measurements": [{"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}]
|
|
32
|
-
},
|
|
33
19
|
"optional": {
|
|
34
|
-
"
|
|
20
|
+
"site": {
|
|
21
|
+
"@type": "Site",
|
|
22
|
+
"measurements": [
|
|
23
|
+
{"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
35
26
|
}
|
|
36
27
|
}
|
|
37
28
|
}
|
|
38
29
|
RETURNS = {
|
|
39
30
|
"Emission": [{
|
|
40
31
|
"value": "",
|
|
41
|
-
"
|
|
42
|
-
"min": "",
|
|
43
|
-
"max": "",
|
|
44
|
-
"methodTier": "tier 1",
|
|
45
|
-
"statsDefinition": "modelled"
|
|
32
|
+
"methodTier": "tier 1"
|
|
46
33
|
}]
|
|
47
34
|
}
|
|
48
|
-
|
|
49
35
|
TERM_ID = 'n2OToAirOrganicFertiliserIndirect'
|
|
50
|
-
NO3_TERM_ID = 'no3ToGroundwaterInorganicFertiliser'
|
|
51
|
-
NH3_TERM_ID = 'nh3ToAirInorganicFertiliser'
|
|
52
|
-
NOX_TERM_ID = 'noxToAirInorganicFertiliser'
|
|
53
36
|
TIER = EmissionMethodTier.TIER_1.value
|
|
37
|
+
NO3_TERM_ID = 'no3ToGroundwaterOrganicFertiliser'
|
|
38
|
+
NH3_TERM_ID = 'nh3ToAirOrganicFertiliser'
|
|
39
|
+
NOX_TERM_ID = 'noxToAirOrganicFertiliser'
|
|
54
40
|
|
|
55
41
|
|
|
56
|
-
def _emission(value: float,
|
|
42
|
+
def _emission(value: float, min: float, max: float, aggregated: bool = False):
|
|
57
43
|
emission = _new_emission(TERM_ID, MODEL)
|
|
58
44
|
emission['value'] = [value]
|
|
59
|
-
emission['sd'] = [sd]
|
|
60
45
|
emission['min'] = [min]
|
|
61
46
|
emission['max'] = [max]
|
|
62
47
|
emission['methodTier'] = TIER
|
|
63
48
|
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
49
|
+
emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
|
|
64
50
|
return emission
|
|
65
51
|
|
|
66
52
|
|
|
67
|
-
def _run(cycle: dict):
|
|
68
|
-
|
|
69
|
-
|
|
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
|
+
|
|
70
59
|
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
60
|
+
ecoClimateZone=ecoClimateZone,
|
|
61
|
+
ef4_factors_used=log_as_table(ef4),
|
|
62
|
+
ef5_factors_used=log_as_table(ef5),
|
|
63
|
+
aggregated=aggregated)
|
|
74
64
|
|
|
75
|
-
value
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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)]
|
|
89
81
|
|
|
90
82
|
|
|
91
83
|
def _should_run(cycle: dict):
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
fertiliser_complete = _is_term_type_complete(cycle, 'fertiliser')
|
|
95
|
-
water_complete = _is_term_type_complete(cycle, TermTermType.WATER)
|
|
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, 'fertiliser')
|
|
96
86
|
|
|
97
87
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
no3_n=no3_n,
|
|
89
|
+
nh3_n=nh3_n,
|
|
90
|
+
nox_n=nox_n,
|
|
91
|
+
term_type_cropResidue_complete=term_type_complete)
|
|
102
92
|
|
|
103
|
-
should_run = all([
|
|
104
|
-
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
|
105
|
-
return should_run
|
|
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
|
|
106
96
|
|
|
107
97
|
|
|
108
|
-
def run(cycle: dict):
|
|
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,112 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
|
2
|
+
from hestia_earth.utils.model import filter_list_term_type, find_term_match
|
|
3
|
+
from hestia_earth.utils.tools import list_sum
|
|
4
|
+
|
|
5
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, debugValues, log_as_table
|
|
6
|
+
from hestia_earth.models.utils.blank_node import get_N_total
|
|
7
|
+
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
8
|
+
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
9
|
+
from hestia_earth.models.utils.emission import _new_emission
|
|
10
|
+
from hestia_earth.models.utils.cycle import get_inorganic_fertiliser_N_total
|
|
11
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
|
12
|
+
from . import MODEL
|
|
13
|
+
|
|
14
|
+
REQUIREMENTS = {
|
|
15
|
+
"Cycle": {
|
|
16
|
+
"completeness.fertiliser": "True",
|
|
17
|
+
"inputs": [
|
|
18
|
+
{
|
|
19
|
+
"@type": "Input",
|
|
20
|
+
"value": "",
|
|
21
|
+
"term.termType": "inorganicFertiliser",
|
|
22
|
+
"optional": {
|
|
23
|
+
"properties": [{"@type": "Property", "value": "", "term.@id": "nitrogenContent"}]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
RETURNS = {
|
|
30
|
+
"Emission": [{
|
|
31
|
+
"value": "",
|
|
32
|
+
"sd": "",
|
|
33
|
+
"min": "",
|
|
34
|
+
"max": "",
|
|
35
|
+
"methodTier": "tier 1",
|
|
36
|
+
"statsDefinition": "modelled",
|
|
37
|
+
"methodModelDescription": ["Aggregated version", "Disaggragated version"]
|
|
38
|
+
}]
|
|
39
|
+
}
|
|
40
|
+
LOOKUPS = {
|
|
41
|
+
"inorganicFertiliser": ["IPCC_2019_FRACGASF_NH3-N", "IPCC_2019_FRACGASF_NH3-N-min", "IPCC_2019_FRACGASF_NH3-N-max"]
|
|
42
|
+
}
|
|
43
|
+
TERM_ID = 'nh3ToAirInorganicFertiliser'
|
|
44
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
45
|
+
TERM_TYPE = TermTermType.INORGANICFERTILISER
|
|
46
|
+
UNSPECIFIED_TERM_ID = 'inorganicNitrogenFertiliserUnspecifiedKgN'
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _emission(value: float, min: float, max: float, aggregated: bool = False):
|
|
50
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
51
|
+
emission['value'] = [value]
|
|
52
|
+
emission['min'] = [min]
|
|
53
|
+
emission['max'] = [max]
|
|
54
|
+
emission['methodTier'] = TIER
|
|
55
|
+
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
56
|
+
emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
|
|
57
|
+
return emission
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _input_values(input: dict):
|
|
61
|
+
N_total = list_sum(get_N_total([input]))
|
|
62
|
+
lookups = LOOKUPS[TERM_TYPE.value]
|
|
63
|
+
return {
|
|
64
|
+
'id': input.get('term', {}).get('@id'),
|
|
65
|
+
'N': N_total,
|
|
66
|
+
'value': get_lookup_value(input.get('term', {}), lookups[0]),
|
|
67
|
+
'min': get_lookup_value(input.get('term', {}), lookups[1]),
|
|
68
|
+
'max': get_lookup_value(input.get('term', {}), lookups[2])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _filter_input_values(values: list, key: str): return [value for value in values if value.get(key)]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _run(cycle: dict):
|
|
76
|
+
inputs = filter_list_term_type(cycle.get('inputs', []), TERM_TYPE)
|
|
77
|
+
input_values = list(map(_input_values, inputs))
|
|
78
|
+
|
|
79
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
80
|
+
input_values=log_as_table(input_values))
|
|
81
|
+
|
|
82
|
+
value = list_sum([
|
|
83
|
+
v.get('N', 0) * v.get('value', 0) for v in _filter_input_values(input_values, 'value')
|
|
84
|
+
]) * get_atomic_conversion(Units.KG_NH3, Units.TO_N)
|
|
85
|
+
|
|
86
|
+
min = list_sum([
|
|
87
|
+
v.get('N', 0) * v.get('min', 0) for v in _filter_input_values(input_values, 'min')
|
|
88
|
+
]) * get_atomic_conversion(Units.KG_NH3, Units.TO_N)
|
|
89
|
+
|
|
90
|
+
max = list_sum([
|
|
91
|
+
v.get('N', 0) * v.get('max', 0) for v in _filter_input_values(input_values, 'max')
|
|
92
|
+
]) * get_atomic_conversion(Units.KG_NH3, Units.TO_N)
|
|
93
|
+
|
|
94
|
+
aggregated = list_sum(find_term_match(inputs, UNSPECIFIED_TERM_ID).get('value', [0])) > 0
|
|
95
|
+
|
|
96
|
+
return [_emission(value, min, max, aggregated=aggregated)]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _should_run(cycle: dict):
|
|
100
|
+
N_inorganic_fertiliser = get_inorganic_fertiliser_N_total(cycle)
|
|
101
|
+
fertiliser_complete = _is_term_type_complete(cycle, 'fertiliser')
|
|
102
|
+
|
|
103
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
104
|
+
N_inorganic_fertiliser=N_inorganic_fertiliser,
|
|
105
|
+
term_type_fertiliser_complete=fertiliser_complete)
|
|
106
|
+
|
|
107
|
+
should_run = all([N_inorganic_fertiliser is not None, fertiliser_complete])
|
|
108
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
|
109
|
+
return should_run
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def run(cycle: dict): return _run(cycle) if _should_run(cycle) else []
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
|
2
|
+
from hestia_earth.utils.model import filter_list_term_type
|
|
3
|
+
from hestia_earth.utils.tools import list_sum
|
|
4
|
+
|
|
5
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, debugValues, log_as_table
|
|
6
|
+
from hestia_earth.models.utils.blank_node import get_N_total
|
|
7
|
+
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
8
|
+
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
9
|
+
from hestia_earth.models.utils.emission import _new_emission
|
|
10
|
+
from hestia_earth.models.utils.cycle import get_organic_fertiliser_N_total
|
|
11
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
|
12
|
+
from . import MODEL
|
|
13
|
+
|
|
14
|
+
REQUIREMENTS = {
|
|
15
|
+
"Cycle": {
|
|
16
|
+
"completeness.fertiliser": "True",
|
|
17
|
+
"inputs": [
|
|
18
|
+
{
|
|
19
|
+
"@type": "Input",
|
|
20
|
+
"value": "",
|
|
21
|
+
"term.termType": "organicFertiliser",
|
|
22
|
+
"optional": {
|
|
23
|
+
"properties": [{"@type": "Property", "value": "", "term.@id": "nitrogenContent"}]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
RETURNS = {
|
|
30
|
+
"Emission": [{
|
|
31
|
+
"value": "",
|
|
32
|
+
"sd": "",
|
|
33
|
+
"min": "",
|
|
34
|
+
"max": "",
|
|
35
|
+
"methodTier": "tier 1",
|
|
36
|
+
"statsDefinition": "modelled",
|
|
37
|
+
"methodModelDescription": "Aggregated version"
|
|
38
|
+
}]
|
|
39
|
+
}
|
|
40
|
+
LOOKUPS = {
|
|
41
|
+
"organicFertiliser": ["IPCC_2019_FRACGASM_NH3-N", "IPCC_2019_FRACGASM_NH3-N-min", "IPCC_2019_FRACGASM_NH3-N-max"]
|
|
42
|
+
}
|
|
43
|
+
TERM_ID = 'nh3ToAirOrganicFertiliser'
|
|
44
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _emission(value: float, min: float, max: float):
|
|
48
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
49
|
+
emission['value'] = [value]
|
|
50
|
+
emission['min'] = [min]
|
|
51
|
+
emission['max'] = [max]
|
|
52
|
+
emission['methodTier'] = TIER
|
|
53
|
+
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
54
|
+
emission['methodModelDescription'] = 'Aggregated version'
|
|
55
|
+
return emission
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _input_values(input: dict):
|
|
59
|
+
N_total = list_sum(get_N_total([input]))
|
|
60
|
+
return {
|
|
61
|
+
'id': input.get('term', {}).get('@id'),
|
|
62
|
+
'N': N_total,
|
|
63
|
+
'value': get_lookup_value(input.get('term', {}), LOOKUPS['organicFertiliser'][0]),
|
|
64
|
+
'min': get_lookup_value(input.get('term', {}), LOOKUPS['organicFertiliser'][1]),
|
|
65
|
+
'max': get_lookup_value(input.get('term', {}), LOOKUPS['organicFertiliser'][2])
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _filter_input_values(values: list, key: str): return [value for value in values if value.get(key)]
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _run(cycle: dict):
|
|
73
|
+
inputs = filter_list_term_type(cycle.get('inputs', []), TermTermType.ORGANICFERTILISER)
|
|
74
|
+
input_values = list(map(_input_values, inputs))
|
|
75
|
+
|
|
76
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
77
|
+
input_values=log_as_table(input_values))
|
|
78
|
+
|
|
79
|
+
value = list_sum([
|
|
80
|
+
v.get('N', 0) * v.get('value', 0) for v in _filter_input_values(input_values, 'value')
|
|
81
|
+
]) * get_atomic_conversion(Units.KG_NH3, Units.TO_N)
|
|
82
|
+
|
|
83
|
+
min = list_sum([
|
|
84
|
+
v.get('N', 0) * v.get('min', 0) for v in _filter_input_values(input_values, 'min')
|
|
85
|
+
]) * get_atomic_conversion(Units.KG_NH3, Units.TO_N)
|
|
86
|
+
|
|
87
|
+
max = list_sum([
|
|
88
|
+
v.get('N', 0) * v.get('max', 0) for v in _filter_input_values(input_values, 'max')
|
|
89
|
+
]) * get_atomic_conversion(Units.KG_NH3, Units.TO_N)
|
|
90
|
+
|
|
91
|
+
return [_emission(value, min, max)]
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _should_run(cycle: dict):
|
|
95
|
+
N_organic_fertiliser = get_organic_fertiliser_N_total(cycle)
|
|
96
|
+
fertiliser_complete = _is_term_type_complete(cycle, 'fertiliser')
|
|
97
|
+
|
|
98
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
99
|
+
N_organic_fertiliser=N_organic_fertiliser,
|
|
100
|
+
term_type_fertiliser_complete=fertiliser_complete)
|
|
101
|
+
|
|
102
|
+
should_run = all([N_organic_fertiliser is not None, fertiliser_complete])
|
|
103
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
|
104
|
+
return should_run
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def run(cycle: dict): return _run(cycle) if _should_run(cycle) else []
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, EmissionStatsDefinition, TermTermType
|
|
2
|
+
from hestia_earth.utils.model import filter_list_term_type, find_term_match
|
|
3
|
+
from hestia_earth.utils.tools import list_sum
|
|
4
|
+
|
|
5
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, debugValues, log_as_table
|
|
6
|
+
from hestia_earth.models.utils.blank_node import get_N_total
|
|
7
|
+
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
8
|
+
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
9
|
+
from hestia_earth.models.utils.emission import _new_emission
|
|
10
|
+
from hestia_earth.models.utils.cycle import get_inorganic_fertiliser_N_total
|
|
11
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
|
12
|
+
from . import MODEL
|
|
13
|
+
|
|
14
|
+
REQUIREMENTS = {
|
|
15
|
+
"Cycle": {
|
|
16
|
+
"completeness.fertiliser": "True",
|
|
17
|
+
"inputs": [
|
|
18
|
+
{
|
|
19
|
+
"@type": "Input",
|
|
20
|
+
"value": "",
|
|
21
|
+
"term.termType": "inorganicFertiliser",
|
|
22
|
+
"optional": {
|
|
23
|
+
"properties": [{"@type": "Property", "value": "", "term.@id": "nitrogenContent"}]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
RETURNS = {
|
|
30
|
+
"Emission": [{
|
|
31
|
+
"value": "",
|
|
32
|
+
"sd": "",
|
|
33
|
+
"min": "",
|
|
34
|
+
"max": "",
|
|
35
|
+
"methodTier": "tier 1",
|
|
36
|
+
"statsDefinition": "modelled",
|
|
37
|
+
"methodModelDescription": ["Aggregated version", "Disaggragated version"]
|
|
38
|
+
}]
|
|
39
|
+
}
|
|
40
|
+
LOOKUPS = {
|
|
41
|
+
"inorganicFertiliser": ["IPCC_2019_FRACGASF_NOx-N", "IPCC_2019_FRACGASF_NOx-N-min", "IPCC_2019_FRACGASF_NOx-N-max"]
|
|
42
|
+
}
|
|
43
|
+
TERM_ID = 'noxToAirInorganicFertiliser'
|
|
44
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
45
|
+
TERM_TYPE = TermTermType.INORGANICFERTILISER
|
|
46
|
+
UNSPECIFIED_TERM_ID = 'inorganicNitrogenFertiliserUnspecifiedKgN'
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _emission(value: float, min: float, max: float, aggregated: bool = False):
|
|
50
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
51
|
+
emission['value'] = [value]
|
|
52
|
+
emission['min'] = [min]
|
|
53
|
+
emission['max'] = [max]
|
|
54
|
+
emission['methodTier'] = TIER
|
|
55
|
+
emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
|
|
56
|
+
emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
|
|
57
|
+
return emission
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _input_values(input: dict):
|
|
61
|
+
N_total = list_sum(get_N_total([input]))
|
|
62
|
+
lookups = LOOKUPS[TERM_TYPE.value]
|
|
63
|
+
return {
|
|
64
|
+
'id': input.get('term', {}).get('@id'),
|
|
65
|
+
'N': N_total,
|
|
66
|
+
'value': get_lookup_value(input.get('term', {}), lookups[0]),
|
|
67
|
+
'min': get_lookup_value(input.get('term', {}), lookups[1]),
|
|
68
|
+
'max': get_lookup_value(input.get('term', {}), lookups[2])
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _filter_input_values(values: list, key: str): return [value for value in values if value.get(key)]
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _run(cycle: dict):
|
|
76
|
+
inputs = filter_list_term_type(cycle.get('inputs', []), TERM_TYPE)
|
|
77
|
+
input_values = list(map(_input_values, inputs))
|
|
78
|
+
|
|
79
|
+
debugValues(cycle, model=MODEL, term=TERM_ID,
|
|
80
|
+
input_values=log_as_table(input_values))
|
|
81
|
+
|
|
82
|
+
value = list_sum([
|
|
83
|
+
v.get('N', 0) * v.get('value', 0) for v in _filter_input_values(input_values, 'value')
|
|
84
|
+
]) * get_atomic_conversion(Units.KG_NOX, Units.TO_N)
|
|
85
|
+
|
|
86
|
+
min = list_sum([
|
|
87
|
+
v.get('N', 0) * v.get('min', 0) for v in _filter_input_values(input_values, 'min')
|
|
88
|
+
]) * get_atomic_conversion(Units.KG_NOX, Units.TO_N)
|
|
89
|
+
|
|
90
|
+
max = list_sum([
|
|
91
|
+
v.get('N', 0) * v.get('max', 0) for v in _filter_input_values(input_values, 'max')
|
|
92
|
+
]) * get_atomic_conversion(Units.KG_NOX, Units.TO_N)
|
|
93
|
+
|
|
94
|
+
aggregated = list_sum(find_term_match(inputs, UNSPECIFIED_TERM_ID).get('value', [0])) > 0
|
|
95
|
+
|
|
96
|
+
return [_emission(value, min, max, aggregated=aggregated)]
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _should_run(cycle: dict):
|
|
100
|
+
N_inorganic_fertiliser = get_inorganic_fertiliser_N_total(cycle)
|
|
101
|
+
fertiliser_complete = _is_term_type_complete(cycle, 'fertiliser')
|
|
102
|
+
|
|
103
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
104
|
+
N_inorganic_fertiliser=N_inorganic_fertiliser,
|
|
105
|
+
term_type_fertiliser_complete=fertiliser_complete)
|
|
106
|
+
|
|
107
|
+
should_run = all([N_inorganic_fertiliser is not None, fertiliser_complete])
|
|
108
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
|
109
|
+
return should_run
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def run(cycle: dict): return _run(cycle) if _should_run(cycle) else []
|