hestia-earth-models 0.57.2__py3-none-any.whl → 0.59.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.

Potentially problematic release.


This version of hestia-earth-models might be problematic. Click here for more details.

Files changed (109) hide show
  1. hestia_earth/models/cycle/aboveGroundCropResidueTotal.py +17 -12
  2. hestia_earth/models/cycle/excretaKgMass.py +4 -5
  3. hestia_earth/models/cycle/excretaKgN.py +4 -5
  4. hestia_earth/models/cycle/excretaKgVs.py +4 -5
  5. hestia_earth/models/cycle/inorganicFertiliser.py +2 -2
  6. hestia_earth/models/cycle/{irrigated.py → irrigatedTypeUnspecified.py} +4 -4
  7. hestia_earth/models/cycle/liveAnimal.py +9 -11
  8. hestia_earth/models/cycle/milkYield.py +154 -0
  9. hestia_earth/models/cycle/residueIncorporated.py +1 -1
  10. hestia_earth/models/cycle/utils.py +6 -0
  11. hestia_earth/models/emepEea2019/nh3ToAirInorganicFertiliser.py +3 -3
  12. hestia_earth/models/faostat2018/seed.py +2 -3
  13. hestia_earth/models/geospatialDatabase/clayContent.py +17 -4
  14. hestia_earth/models/geospatialDatabase/sandContent.py +17 -4
  15. hestia_earth/models/geospatialDatabase/siltContent.py +2 -2
  16. hestia_earth/models/impact_assessment/irrigated.py +0 -3
  17. hestia_earth/models/ipcc2006/co2ToAirOrganicSoilCultivation.py +2 -2
  18. hestia_earth/models/ipcc2006/n2OToAirCropResidueDecompositionIndirect.py +2 -2
  19. hestia_earth/models/ipcc2006/n2OToAirExcretaDirect.py +1 -1
  20. hestia_earth/models/ipcc2006/n2OToAirExcretaIndirect.py +8 -4
  21. hestia_earth/models/ipcc2006/n2OToAirInorganicFertiliserDirect.py +4 -1
  22. hestia_earth/models/ipcc2006/n2OToAirInorganicFertiliserIndirect.py +1 -1
  23. hestia_earth/models/ipcc2006/n2OToAirOrganicFertiliserDirect.py +1 -1
  24. hestia_earth/models/ipcc2006/n2OToAirOrganicFertiliserIndirect.py +1 -1
  25. hestia_earth/models/ipcc2006/utils.py +11 -8
  26. hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +4 -4
  27. hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +16 -7
  28. hestia_earth/models/ipcc2019/co2ToAirSoilCarbonStockChangeManagementChange.py +759 -0
  29. hestia_earth/models/ipcc2019/croppingDuration.py +12 -6
  30. hestia_earth/models/ipcc2019/n2OToAirCropResidueDecompositionDirect.py +5 -52
  31. hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserDirect.py +104 -0
  32. hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserIndirect.py +1 -1
  33. hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserDirect.py +105 -0
  34. hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserIndirect.py +1 -1
  35. hestia_earth/models/ipcc2019/no3ToGroundwaterCropResidueDecomposition.py +1 -1
  36. hestia_earth/models/ipcc2019/no3ToGroundwaterExcreta.py +1 -1
  37. hestia_earth/models/ipcc2019/no3ToGroundwaterInorganicFertiliser.py +1 -1
  38. hestia_earth/models/ipcc2019/no3ToGroundwaterOrganicFertiliser.py +1 -1
  39. hestia_earth/models/ipcc2019/organicCarbonPerHa.py +1088 -1268
  40. hestia_earth/models/ipcc2019/pastureGrass.py +4 -4
  41. hestia_earth/models/ipcc2019/utils.py +102 -1
  42. hestia_earth/models/koble2014/aboveGroundCropResidue.py +15 -17
  43. hestia_earth/models/koble2014/cropResidueManagement.py +2 -2
  44. hestia_earth/models/koble2014/utils.py +19 -3
  45. hestia_earth/models/linkedImpactAssessment/__init__.py +4 -2
  46. hestia_earth/models/log.py +15 -3
  47. hestia_earth/models/mocking/search-results.json +184 -118
  48. hestia_earth/models/pooreNemecek2018/excretaKgN.py +6 -7
  49. hestia_earth/models/pooreNemecek2018/excretaKgVs.py +7 -6
  50. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterCropResidueDecomposition.py +3 -2
  51. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterExcreta.py +3 -2
  52. hestia_earth/models/pooreNemecek2018/no3ToGroundwaterInorganicFertiliser.py +3 -2
  53. hestia_earth/models/pooreNemecek2018/saplings.py +0 -1
  54. hestia_earth/models/site/management.py +168 -0
  55. hestia_earth/models/site/organicCarbonPerHa.py +251 -89
  56. hestia_earth/models/stehfestBouwman2006/n2OToAirCropResidueDecompositionDirect.py +3 -2
  57. hestia_earth/models/stehfestBouwman2006/n2OToAirExcretaDirect.py +3 -2
  58. hestia_earth/models/stehfestBouwman2006/n2OToAirInorganicFertiliserDirect.py +3 -2
  59. hestia_earth/models/stehfestBouwman2006/n2OToAirOrganicFertiliserDirect.py +3 -2
  60. hestia_earth/models/stehfestBouwman2006/noxToAirCropResidueDecomposition.py +3 -2
  61. hestia_earth/models/stehfestBouwman2006/noxToAirExcreta.py +3 -2
  62. hestia_earth/models/stehfestBouwman2006/noxToAirInorganicFertiliser.py +3 -2
  63. hestia_earth/models/stehfestBouwman2006/noxToAirOrganicFertiliser.py +3 -2
  64. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirCropResidueDecomposition.py +3 -2
  65. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirExcreta.py +3 -2
  66. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirInorganicFertiliser.py +3 -2
  67. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirOrganicFertiliser.py +3 -2
  68. hestia_earth/models/utils/aggregated.py +1 -0
  69. hestia_earth/models/utils/blank_node.py +394 -72
  70. hestia_earth/models/utils/cropResidue.py +13 -0
  71. hestia_earth/models/utils/cycle.py +18 -9
  72. hestia_earth/models/utils/measurement.py +1 -1
  73. hestia_earth/models/utils/property.py +4 -4
  74. hestia_earth/models/utils/term.py +48 -3
  75. hestia_earth/models/version.py +1 -1
  76. {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/METADATA +5 -9
  77. {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/RECORD +109 -97
  78. {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/WHEEL +1 -1
  79. tests/models/cycle/animal/input/test_hestiaAggregatedData.py +2 -14
  80. tests/models/cycle/input/test_hestiaAggregatedData.py +4 -16
  81. tests/models/cycle/test_coldCarcassWeightPerHead.py +1 -1
  82. tests/models/cycle/test_coldDressedCarcassWeightPerHead.py +1 -1
  83. tests/models/cycle/{test_irrigated.py → test_irrigatedTypeUnspecified.py} +1 -1
  84. tests/models/cycle/test_milkYield.py +58 -0
  85. tests/models/cycle/test_readyToCookWeightPerHead.py +1 -1
  86. tests/models/emepEea2019/test_nh3ToAirInorganicFertiliser.py +1 -1
  87. tests/models/geospatialDatabase/test_clayContent.py +9 -3
  88. tests/models/geospatialDatabase/test_sandContent.py +9 -3
  89. tests/models/ipcc2006/test_n2OToAirExcretaDirect.py +7 -2
  90. tests/models/ipcc2006/test_n2OToAirExcretaIndirect.py +1 -1
  91. tests/models/ipcc2006/test_n2OToAirInorganicFertiliserDirect.py +7 -2
  92. tests/models/ipcc2006/test_n2OToAirInorganicFertiliserIndirect.py +7 -2
  93. tests/models/ipcc2006/test_n2OToAirOrganicFertiliserDirect.py +7 -2
  94. tests/models/ipcc2006/test_n2OToAirOrganicFertiliserIndirect.py +7 -2
  95. tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +1 -1
  96. tests/models/ipcc2019/test_co2ToAirSoilCarbonStockChangeManagementChange.py +228 -0
  97. tests/models/ipcc2019/test_n2OToAirInorganicFertiliserDirect.py +74 -0
  98. tests/models/ipcc2019/test_n2OToAirOrganicFertiliserDirect.py +74 -0
  99. tests/models/ipcc2019/test_organicCarbonPerHa.py +303 -1044
  100. tests/models/koble2014/test_residueBurnt.py +1 -2
  101. tests/models/koble2014/test_residueLeftOnField.py +1 -2
  102. tests/models/koble2014/test_residueRemoved.py +1 -2
  103. tests/models/koble2014/test_utils.py +52 -0
  104. tests/models/site/test_management.py +117 -0
  105. tests/models/site/test_organicCarbonPerHa.py +51 -5
  106. tests/models/utils/test_blank_node.py +230 -34
  107. tests/models/utils/test_term.py +17 -3
  108. {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/LICENSE +0 -0
  109. {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/top_level.txt +0 -0
@@ -60,29 +60,35 @@ def _get_value(country: str, col: str):
60
60
  return value
61
61
 
62
62
 
63
- def _run(country: str, cycleDuration: float):
63
+ def _run(country: str):
64
64
  value = _get_value(country, LOOKUP_COL_PREFIX)
65
65
  min = _get_value(country, f"{LOOKUP_COL_PREFIX}_min")
66
66
  max = _get_value(country, f"{LOOKUP_COL_PREFIX}_max")
67
67
  sd = _get_value(country, f"{LOOKUP_COL_PREFIX}_sd")
68
- return [_practice(value, min, max, sd)] if value <= cycleDuration else []
68
+ return [_practice(value, min, max, sd)]
69
69
 
70
70
 
71
71
  def _should_run(cycle: dict):
72
72
  country = cycle.get('site', {}).get('country', {}).get('@id')
73
+ croppingDuration = _get_value(country, LOOKUP_COL_PREFIX)
74
+
73
75
  cycleDuration = cycle.get('cycleDuration', 0)
74
76
  flooded_rice = has_flooded_rice(cycle.get('products', []))
75
77
 
78
+ croppingDuration_below_cycleDuration = croppingDuration <= cycleDuration
79
+
76
80
  logRequirements(cycle, model=MODEL, term=TERM_ID,
77
81
  country=country,
82
+ has_flooded_rice=flooded_rice,
78
83
  cycleDuration=cycleDuration,
79
- has_flooded_rice=flooded_rice)
84
+ croppingDuration=croppingDuration,
85
+ croppingDuration_below_cycleDuration=croppingDuration_below_cycleDuration)
80
86
 
81
87
  should_run = all([country, cycleDuration, flooded_rice])
82
88
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
83
- return should_run, country, cycleDuration
89
+ return should_run, country
84
90
 
85
91
 
86
92
  def run(cycle: dict):
87
- should_run, country, cycleDuration = _should_run(cycle)
88
- return _run(country, cycleDuration) if should_run else []
93
+ should_run, country = _should_run(cycle)
94
+ return _run(country) if should_run else []
@@ -1,15 +1,12 @@
1
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 safe_parse_float
4
2
 
5
3
  from hestia_earth.models.log import logRequirements, logShouldRun, debugValues, log_as_table
6
4
  from hestia_earth.models.utils.constant import Units, get_atomic_conversion
7
5
  from hestia_earth.models.utils.completeness import _is_term_type_complete
8
6
  from hestia_earth.models.utils.emission import _new_emission
9
7
  from hestia_earth.models.utils.cycle import get_ecoClimateZone, get_crop_residue_decomposition_N_total
10
- from hestia_earth.models.utils.ecoClimateZone import get_ecoClimateZone_lookup_value
11
- from hestia_earth.models.utils.term import get_lookup_value
12
8
  from hestia_earth.models.utils.product import has_flooded_rice
9
+ from .utils import get_N2O_factors
13
10
  from . import MODEL
14
11
 
15
12
  REQUIREMENTS = {
@@ -51,28 +48,6 @@ LOOKUPS = {
51
48
  }
52
49
  TERM_ID = 'n2OToAirCropResidueDecompositionDirect'
53
50
  TIER = EmissionMethodTier.TIER_1.value
54
- FACTORS = {
55
- 'dry': {
56
- 'value': 0.005,
57
- 'min': 0,
58
- 'max': 0.011
59
- },
60
- 'wet': {
61
- 'value': 0.006,
62
- 'min': 0.001,
63
- 'max': 0.011
64
- },
65
- 'default': {
66
- 'value': 0.01,
67
- 'min': 0.001,
68
- 'max': 0.018
69
- },
70
- 'flooded_rice': {
71
- 'value': 0.004,
72
- 'min': 0,
73
- 'max': 0.029
74
- }
75
- }
76
51
 
77
52
 
78
53
  def _emission(value: float, min: float, max: float, sd: float, aggregated: bool = False):
@@ -87,33 +62,11 @@ def _emission(value: float, min: float, max: float, sd: float, aggregated: bool
87
62
  return emission
88
63
 
89
64
 
90
- def _get_waterRegime_lookup(practice: dict, col: str):
91
- return safe_parse_float(get_lookup_value(practice.get('term', {}), col, model=MODEL, term=TERM_ID), None)
92
-
93
-
94
- def _flooded_rice_factors(cycle: dict):
95
- practices = filter_list_term_type(cycle.get('practices', []), TermTermType.WATERREGIME)
96
- practice = next((p for p in practices if _get_waterRegime_lookup(p, LOOKUPS['waterRegime'][0]) is not None), None)
97
-
98
- factors = {
99
- 'value': _get_waterRegime_lookup(practice, LOOKUPS['waterRegime'][0]),
100
- 'min': _get_waterRegime_lookup(practice, LOOKUPS['waterRegime'][1]),
101
- 'max': _get_waterRegime_lookup(practice, LOOKUPS['waterRegime'][2])
102
- } if practice else FACTORS['flooded_rice']
103
-
104
- return (factors, practice is None)
105
-
106
-
107
- def _is_wet(ecoClimateZone: str = None):
108
- return get_ecoClimateZone_lookup_value(ecoClimateZone, 'wet') == 1 if ecoClimateZone else None
109
-
110
-
111
65
  def _run(cycle: dict, N_total: float, ecoClimateZone: str = None, flooded_rice: bool = False):
112
66
  converted_N_total = N_total * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
113
- is_wet = _is_wet(ecoClimateZone)
114
- factors_key = 'default' if is_wet is None else 'wet' if is_wet else 'dry'
115
-
116
- factors, aggregated = _flooded_rice_factors(cycle) if flooded_rice else (FACTORS[factors_key], is_wet is None)
67
+ factors, aggregated = get_N2O_factors(
68
+ TERM_ID, cycle, TermTermType.CROPRESIDUE, ecoClimateZone=ecoClimateZone, flooded_rice=flooded_rice
69
+ )
117
70
 
118
71
  debugValues(cycle, model=MODEL, term=TERM_ID,
119
72
  factors_used=log_as_table(factors),
@@ -139,7 +92,7 @@ def _should_run(cycle: dict):
139
92
  has_flooded_rice=flooded_rice,
140
93
  ecoClimateZone=ecoClimateZone)
141
94
 
142
- should_run = all([term_type_complete, N_crop_residue])
95
+ should_run = all([N_crop_residue is not None, term_type_complete])
143
96
  logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
144
97
  return should_run, N_crop_residue, ecoClimateZone, flooded_rice
145
98
 
@@ -0,0 +1,104 @@
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_ecoClimateZone, get_inorganic_fertiliser_N_total
8
+ from hestia_earth.models.utils.product import has_flooded_rice
9
+ from .utils import get_N2O_factors
10
+ from . import MODEL
11
+
12
+ REQUIREMENTS = {
13
+ "Cycle": {
14
+ "completeness.fertiliser": "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
+ "optional": {
25
+ "endDate": "",
26
+ "site": {
27
+ "@type": "Site",
28
+ "measurements": [
29
+ {"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}
30
+ ]
31
+ },
32
+ "products": [{"@type": "Product", "term.@id": "riceGrainInHuskFlooded"}],
33
+ "practices": [{"@type": "Practice", "term.termType": "waterRegime"}]
34
+ }
35
+ }
36
+ }
37
+ RETURNS = {
38
+ "Emission": [{
39
+ "value": "",
40
+ "min": "",
41
+ "max": "",
42
+ "sd": "",
43
+ "methodTier": "tier 1",
44
+ "statsDefinition": "modelled",
45
+ "methodModelDescription": ["Aggregated version", "Disaggregated version"]
46
+ }]
47
+ }
48
+ LOOKUPS = {
49
+ "waterRegime": ["IPCC_2019_N2O_rice", "IPCC_2019_N2O_rice-min", "IPCC_2019_N2O_rice-max"]
50
+ }
51
+ TERM_ID = 'n2OToAirInorganicFertiliserDirect'
52
+ TIER = EmissionMethodTier.TIER_1.value
53
+
54
+
55
+ def _emission(value: float, min: float, max: float, sd: float, aggregated: bool = False):
56
+ emission = _new_emission(TERM_ID, MODEL)
57
+ emission['value'] = [value]
58
+ emission['min'] = [min]
59
+ emission['max'] = [max]
60
+ emission['sd'] = [sd]
61
+ emission['methodTier'] = TIER
62
+ emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
63
+ emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
64
+ return emission
65
+
66
+
67
+ def _run(cycle: dict, N_total: float, ecoClimateZone: str = None, flooded_rice: bool = False):
68
+ converted_N_total = N_total * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
69
+ factors, aggregated = get_N2O_factors(
70
+ TERM_ID, cycle, TermTermType.INORGANICFERTILISER, ecoClimateZone=ecoClimateZone, flooded_rice=flooded_rice
71
+ )
72
+
73
+ debugValues(cycle, model=MODEL, term=TERM_ID,
74
+ factors_used=log_as_table(factors),
75
+ aggregated=aggregated)
76
+
77
+ value = converted_N_total * factors['value']
78
+ min = converted_N_total * factors['min']
79
+ max = converted_N_total * factors['max']
80
+ sd = converted_N_total * (factors['max'] - factors['min'])/4
81
+ return [_emission(value, min, max, sd, aggregated=aggregated)]
82
+
83
+
84
+ def _should_run(cycle: dict):
85
+ term_type_complete = _is_term_type_complete(cycle, 'fertiliser')
86
+ N_total = get_inorganic_fertiliser_N_total(cycle)
87
+ ecoClimateZone = get_ecoClimateZone(cycle)
88
+
89
+ flooded_rice = has_flooded_rice(cycle.get('products', []))
90
+
91
+ logRequirements(cycle, model=MODEL, term=TERM_ID,
92
+ term_type_cropResidue_complete=term_type_complete,
93
+ N_total=N_total,
94
+ has_flooded_rice=flooded_rice,
95
+ ecoClimateZone=ecoClimateZone)
96
+
97
+ should_run = all([N_total is not None, term_type_complete])
98
+ logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
99
+ return should_run, N_total, ecoClimateZone, flooded_rice
100
+
101
+
102
+ def run(cycle: dict):
103
+ should_run, N_total, ecoClimateZone, flooded_rice = _should_run(cycle)
104
+ return _run(cycle, N_total, ecoClimateZone, flooded_rice) if should_run else []
@@ -99,7 +99,7 @@ def _should_run(cycle: dict):
99
99
  term_type_fertiliser_complete=fertiliser_complete,
100
100
  term_type_water_complete=water_complete)
101
101
 
102
- should_run = all([N_inorganic_fertiliser, ecoClimateZone, fertiliser_complete, water_complete])
102
+ should_run = all([N_inorganic_fertiliser is not None, ecoClimateZone, fertiliser_complete, water_complete])
103
103
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
104
104
  return should_run
105
105
 
@@ -0,0 +1,105 @@
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_ecoClimateZone, get_organic_fertiliser_N_total
8
+ from hestia_earth.models.utils.product import has_flooded_rice
9
+ from .utils import get_N2O_factors
10
+ from . import MODEL
11
+
12
+ REQUIREMENTS = {
13
+ "Cycle": {
14
+ "completeness.fertiliser": "True",
15
+ "inputs": [{
16
+ "@type": "Input",
17
+ "value": "",
18
+ "term.units": ["kg", "kg N"],
19
+ "term.termType": "organicFertiliser",
20
+ "optional": {
21
+ "properties": [{"@type": "Property", "value": "", "term.@id": "nitrogenContent"}]
22
+ }
23
+ }],
24
+ "optional": {
25
+ "endDate": "",
26
+ "site": {
27
+ "@type": "Site",
28
+ "measurements": [
29
+ {"@type": "Measurement", "value": "", "term.@id": "ecoClimateZone"}
30
+ ]
31
+ },
32
+ "products": [{"@type": "Product", "term.@id": "riceGrainInHuskFlooded"}],
33
+ "practices": [{"@type": "Practice", "term.termType": "waterRegime"}]
34
+ }
35
+ }
36
+ }
37
+ RETURNS = {
38
+ "Emission": [{
39
+ "value": "",
40
+ "min": "",
41
+ "max": "",
42
+ "sd": "",
43
+ "methodTier": "tier 1",
44
+ "statsDefinition": "modelled",
45
+ "methodModelDescription": ["Aggregated version", "Disaggregated version"]
46
+ }]
47
+ }
48
+ LOOKUPS = {
49
+ "waterRegime": ["IPCC_2019_N2O_rice", "IPCC_2019_N2O_rice-min", "IPCC_2019_N2O_rice-max"]
50
+ }
51
+ TERM_ID = 'n2OToAirOrganicFertiliserDirect'
52
+ TIER = EmissionMethodTier.TIER_1.value
53
+
54
+
55
+ def _emission(value: float, min: float, max: float, sd: float, aggregated: bool = False):
56
+ emission = _new_emission(TERM_ID, MODEL)
57
+ emission['value'] = [value]
58
+ emission['min'] = [min]
59
+ emission['max'] = [max]
60
+ emission['sd'] = [sd]
61
+ emission['methodTier'] = TIER
62
+ emission['statsDefinition'] = EmissionStatsDefinition.MODELLED.value
63
+ emission['methodModelDescription'] = 'Aggregated version' if aggregated else 'Disaggregated version'
64
+ return emission
65
+
66
+
67
+ def _run(cycle: dict, N_total: float, ecoClimateZone: str = None, flooded_rice: bool = False):
68
+ converted_N_total = N_total * get_atomic_conversion(Units.KG_N2O, Units.TO_N)
69
+ factors, aggregated = get_N2O_factors(
70
+ TERM_ID, cycle, TermTermType.ORGANICFERTILISER, ecoClimateZone=ecoClimateZone, flooded_rice=flooded_rice
71
+ )
72
+
73
+ debugValues(cycle, model=MODEL, term=TERM_ID,
74
+ factors_used=log_as_table(factors),
75
+ aggregated=aggregated)
76
+
77
+ print(N_total, get_atomic_conversion(Units.KG_N2O, Units.TO_N), factors['value'])
78
+ value = converted_N_total * factors['value']
79
+ min = converted_N_total * factors['min']
80
+ max = converted_N_total * factors['max']
81
+ sd = converted_N_total * (factors['max'] - factors['min'])/4
82
+ return [_emission(value, min, max, sd, aggregated=aggregated)]
83
+
84
+
85
+ def _should_run(cycle: dict):
86
+ term_type_complete = _is_term_type_complete(cycle, 'fertiliser')
87
+ N_total = get_organic_fertiliser_N_total(cycle)
88
+ ecoClimateZone = get_ecoClimateZone(cycle)
89
+
90
+ flooded_rice = has_flooded_rice(cycle.get('products', []))
91
+
92
+ logRequirements(cycle, model=MODEL, term=TERM_ID,
93
+ term_type_cropResidue_complete=term_type_complete,
94
+ N_total=N_total,
95
+ has_flooded_rice=flooded_rice,
96
+ ecoClimateZone=ecoClimateZone)
97
+
98
+ should_run = all([N_total is not None, term_type_complete])
99
+ logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
100
+ return should_run, N_total, ecoClimateZone, flooded_rice
101
+
102
+
103
+ def run(cycle: dict):
104
+ should_run, N_total, ecoClimateZone, flooded_rice = _should_run(cycle)
105
+ return _run(cycle, N_total, ecoClimateZone, flooded_rice) if should_run else []
@@ -100,7 +100,7 @@ def _should_run(cycle: dict):
100
100
  term_type_fertiliser_complete=fertiliser_complete,
101
101
  term_type_water_complete=water_complete)
102
102
 
103
- should_run = all([N_organic_fertiliser, ecoClimateZone, fertiliser_complete, water_complete])
103
+ should_run = all([N_organic_fertiliser is not None, ecoClimateZone, fertiliser_complete, water_complete])
104
104
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
105
105
  return should_run
106
106
 
@@ -78,7 +78,7 @@ def _should_run(cycle: dict):
78
78
  term_type_cropResidue_complete=crop_residue_complete,
79
79
  term_type_water_complete=water_complete)
80
80
 
81
- should_run = all([N_crop_residue, ecoClimateZone, crop_residue_complete, water_complete])
81
+ should_run = all([N_crop_residue is not None, ecoClimateZone, crop_residue_complete, water_complete])
82
82
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
83
83
  return should_run, N_crop_residue
84
84
 
@@ -80,7 +80,7 @@ def _should_run(cycle: dict):
80
80
  term_type_excreta_complete=excreta_complete,
81
81
  term_type_water_complete=water_complete)
82
82
 
83
- should_run = all([N_excreta, ecoClimateZone, excreta_complete, water_complete])
83
+ should_run = all([N_excreta is not None, ecoClimateZone, excreta_complete, water_complete])
84
84
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
85
85
  return should_run
86
86
 
@@ -79,7 +79,7 @@ def _should_run(cycle: dict):
79
79
  term_type_fertiliser_complete=fertiliser_complete,
80
80
  term_type_water_complete=water_complete)
81
81
 
82
- should_run = all([N_inorganic_fertiliser, ecoClimateZone, fertiliser_complete, water_complete])
82
+ should_run = all([N_inorganic_fertiliser is not None, ecoClimateZone, fertiliser_complete, water_complete])
83
83
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
84
84
  return should_run
85
85
 
@@ -80,7 +80,7 @@ def _should_run(cycle: dict):
80
80
  term_type_fertiliser_complete=fertiliser_complete,
81
81
  term_type_water_complete=water_complete)
82
82
 
83
- should_run = all([N_organic_fertiliser, ecoClimateZone, fertiliser_complete, water_complete])
83
+ should_run = all([N_organic_fertiliser is not None, ecoClimateZone, fertiliser_complete, water_complete])
84
84
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
85
85
  return should_run
86
86