hestia-earth-models 0.74.8__py3-none-any.whl → 0.74.10__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/cache_sites.py +1 -1
- hestia_earth/models/faostat2018/liveweightPerHead.py +1 -1
- hestia_earth/models/faostat2018/product/price.py +1 -1
- hestia_earth/models/geospatialDatabase/ecoClimateZone.py +1 -1
- hestia_earth/models/geospatialDatabase/region.py +1 -1
- hestia_earth/models/geospatialDatabase/utils.py +1 -1
- hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +2 -1
- hestia_earth/models/haversineFormula/transport/distance.py +1 -1
- hestia_earth/models/hestia/aboveGroundCropResidue.py +1 -3
- hestia_earth/models/hestia/cropResidueManagement.py +1 -0
- hestia_earth/models/hestia/excretaKgMass.py +1 -1
- hestia_earth/models/hestia/landCover.py +13 -6
- hestia_earth/models/hestia/landOccupationDuringCycle.py +1 -1
- hestia_earth/models/hestia/management.py +25 -11
- hestia_earth/models/hestia/pastureGrass.py +1 -1
- hestia_earth/models/impact_assessment/post_checks/__init__.py +3 -2
- hestia_earth/models/impact_assessment/post_checks/remove_no_value.py +13 -0
- hestia_earth/models/ipcc2019/biocharOrganicCarbonPerHa.py +2 -1
- hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +16 -13
- hestia_earth/models/ipcc2019/organicCarbonPerHa.py +5 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +88 -101
- hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +21 -0
- hestia_earth/models/mocking/search-results.json +1 -1
- hestia_earth/models/site/pre_checks/country.py +1 -2
- hestia_earth/models/utils/__init__.py +7 -5
- hestia_earth/models/utils/blank_node.py +7 -2
- hestia_earth/models/utils/completeness.py +1 -2
- hestia_earth/models/utils/emission.py +1 -1
- hestia_earth/models/utils/indicator.py +1 -1
- hestia_earth/models/utils/input.py +1 -1
- hestia_earth/models/utils/management.py +1 -1
- hestia_earth/models/utils/measurement.py +2 -1
- hestia_earth/models/utils/method.py +1 -2
- hestia_earth/models/utils/practice.py +1 -1
- hestia_earth/models/utils/product.py +2 -1
- hestia_earth/models/utils/property.py +2 -1
- hestia_earth/models/utils/term.py +1 -27
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/RECORD +49 -46
- tests/models/hestia/test_aboveGroundCropResidue.py +13 -35
- tests/models/hestia/test_landOccupationDuringCycle.py +9 -2
- tests/models/impact_assessment/post_checks/test_remove_cache_fields.py +6 -0
- tests/models/impact_assessment/post_checks/test_remove_no_value.py +17 -0
- tests/models/ipcc2019/test_ch4ToAirExcreta.py +0 -12
- tests/models/ipcc2019/test_organicCarbonPerHa_tier_1.py +1 -1
- {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/top_level.txt +0 -0
|
@@ -3,11 +3,11 @@ from enum import Enum
|
|
|
3
3
|
from pydash.objects import merge
|
|
4
4
|
from hestia_earth.schema import TermTermType
|
|
5
5
|
from hestia_earth.utils.tools import flatten, non_empty_list
|
|
6
|
+
from hestia_earth.utils.term import download_term
|
|
6
7
|
|
|
7
8
|
from .log import logger
|
|
8
9
|
from .utils import CACHE_KEY, cached_value
|
|
9
10
|
from .utils.site import CACHE_YEARS_KEY
|
|
10
|
-
from .utils.term import download_term
|
|
11
11
|
from .site.pre_checks.cache_geospatialDatabase import (
|
|
12
12
|
list_vectors, list_rasters, cache_site_results, _should_run
|
|
13
13
|
)
|
|
@@ -2,10 +2,10 @@ from hestia_earth.schema import TermTermType
|
|
|
2
2
|
from hestia_earth.utils.lookup import extract_grouped_data_closest_date
|
|
3
3
|
from hestia_earth.utils.model import filter_list_term_type
|
|
4
4
|
from hestia_earth.utils.tools import non_empty_list, safe_parse_date, safe_parse_float
|
|
5
|
+
from hestia_earth.utils.term import download_term
|
|
5
6
|
|
|
6
7
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
7
8
|
from hestia_earth.models.utils.constant import Units
|
|
8
|
-
from hestia_earth.models.utils.term import download_term
|
|
9
9
|
from hestia_earth.models.utils.property import _new_property, node_has_no_property
|
|
10
10
|
from hestia_earth.models.utils.product import convert_product_to_unit
|
|
11
11
|
from hestia_earth.models.utils.animalProduct import FAO_LOOKUP_COLUMN, get_animalProduct_lookup_value
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from hestia_earth.schema import TermTermType
|
|
2
2
|
from hestia_earth.utils.lookup import extract_grouped_data
|
|
3
3
|
from hestia_earth.utils.tools import non_empty_list, safe_parse_float, safe_parse_date
|
|
4
|
+
from hestia_earth.utils.term import download_term
|
|
4
5
|
|
|
5
6
|
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
|
6
7
|
from hestia_earth.models.utils.constant import Units
|
|
7
|
-
from hestia_earth.models.utils.term import download_term
|
|
8
8
|
from hestia_earth.models.utils.currency import DEFAULT_CURRENCY
|
|
9
9
|
from hestia_earth.models.utils.crop import FAOSTAT_PRODUCTION_LOOKUP_COLUMN, get_crop_grouping_faostat_production
|
|
10
10
|
from hestia_earth.models.utils.animalProduct import FAO_LOOKUP_COLUMN, get_animalProduct_grouping_fao
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from hestia_earth.schema import TermTermType
|
|
2
2
|
from hestia_earth.utils.model import linked_node
|
|
3
|
+
from hestia_earth.utils.term import download_term
|
|
3
4
|
|
|
4
5
|
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
|
5
6
|
from .utils import download, has_coordinates
|
|
6
|
-
from hestia_earth.models.utils.term import download_term
|
|
7
7
|
from . import MODEL
|
|
8
8
|
|
|
9
9
|
REQUIREMENTS = {
|
|
@@ -4,10 +4,10 @@ from area import area
|
|
|
4
4
|
from functools import reduce, lru_cache
|
|
5
5
|
from hestia_earth.schema import TermTermType
|
|
6
6
|
from hestia_earth.utils.tools import non_empty_list
|
|
7
|
+
from hestia_earth.utils.term import download_term
|
|
7
8
|
|
|
8
9
|
from hestia_earth.models.log import debugValues, logErrorRun, logRequirements
|
|
9
10
|
from hestia_earth.models.utils.site import cached_value, region_factor, region_level_1_id
|
|
10
|
-
from hestia_earth.models.utils.term import download_term
|
|
11
11
|
from . import MODEL
|
|
12
12
|
|
|
13
13
|
MAX_AREA_SIZE = int(os.getenv('MAX_AREA_SIZE', '5000'))
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from hestia_earth.schema import CycleFunctionalUnit, TermTermType
|
|
2
2
|
from hestia_earth.utils.model import find_term_match, filter_list_term_type
|
|
3
3
|
from hestia_earth.utils.tools import list_sum, non_empty_list, safe_parse_float
|
|
4
|
+
from hestia_earth.utils.term import download_term
|
|
4
5
|
|
|
5
6
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
6
7
|
from hestia_earth.models.utils.property import _new_property, node_has_no_property
|
|
7
|
-
from hestia_earth.models.utils.term import get_irrigation_terms
|
|
8
|
+
from hestia_earth.models.utils.term import get_irrigation_terms
|
|
8
9
|
from hestia_earth.models.utils.crop import get_crop_lookup_value
|
|
9
10
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
10
11
|
from . import MODEL
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from haversine import haversine
|
|
2
2
|
from hestia_earth.schema import TermTermType
|
|
3
3
|
from hestia_earth.utils.tools import non_empty_list
|
|
4
|
+
from hestia_earth.utils.term import download_term
|
|
4
5
|
|
|
5
6
|
from hestia_earth.models.log import logRequirements, logShouldRun, debugValues
|
|
6
7
|
from hestia_earth.models.utils.method import include_methodModel
|
|
7
|
-
from hestia_earth.models.utils.term import download_term
|
|
8
8
|
from .. import MODEL
|
|
9
9
|
|
|
10
10
|
REQUIREMENTS = {
|
|
@@ -112,12 +112,10 @@ def _run(cycle: dict, total_values: list):
|
|
|
112
112
|
|
|
113
113
|
if value == 0:
|
|
114
114
|
values.extend([_product(term_id, value)])
|
|
115
|
-
elif remaining_value
|
|
115
|
+
elif remaining_value >= 0 and value is not None and value >= 0:
|
|
116
116
|
value = value if value < remaining_value else remaining_value
|
|
117
117
|
values.extend([_product(term_id, value)])
|
|
118
118
|
remaining_value = remaining_value - value
|
|
119
|
-
if remaining_value == 0:
|
|
120
|
-
break
|
|
121
119
|
|
|
122
120
|
return values + [
|
|
123
121
|
# whatever remains is "left on field"
|
|
@@ -21,6 +21,7 @@ RETURNS = {
|
|
|
21
21
|
}]
|
|
22
22
|
}
|
|
23
23
|
MODEL_KEY = 'cropResidueManagement'
|
|
24
|
+
TERM_ID = 'residueBurnt,residueIncorporated,residueLeftOnField,residueRemoved,residueIncorporatedLessThan30DaysBeforeCultivation,residueIncorporatedMoreThan30DaysBeforeCultivation' # noqa: E501
|
|
24
25
|
PRACTICE_IDS = [
|
|
25
26
|
residueBurnt.TERM_ID,
|
|
26
27
|
residueIncorporated.TERM_ID,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
from hestia_earth.schema import NodeType, TermTermType
|
|
2
2
|
from hestia_earth.utils.model import filter_list_term_type, find_term_match
|
|
3
3
|
from hestia_earth.utils.tools import non_empty_list, list_sum
|
|
4
|
+
from hestia_earth.utils.term import download_term
|
|
4
5
|
|
|
5
6
|
from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
|
|
6
7
|
from hestia_earth.models.utils import get_kg_term_id, get_kg_N_term_id, get_kg_VS_term_id, _filter_list_term_unit
|
|
7
|
-
from hestia_earth.models.utils.term import download_term
|
|
8
8
|
from hestia_earth.models.utils.constant import Units
|
|
9
9
|
from hestia_earth.models.utils.product import _new_product, convert_product_to_unit
|
|
10
10
|
from . import MODEL
|
|
@@ -10,7 +10,7 @@ from hestia_earth.utils.model import filter_list_term_type
|
|
|
10
10
|
from hestia_earth.utils.tools import safe_parse_float, to_precision
|
|
11
11
|
|
|
12
12
|
from hestia_earth.models.log import logRequirements, log_as_table, logShouldRun
|
|
13
|
-
from hestia_earth.models.utils import _omit
|
|
13
|
+
from hestia_earth.models.utils import _omit, clamp
|
|
14
14
|
from hestia_earth.models.utils.constant import DAYS_IN_YEAR
|
|
15
15
|
from hestia_earth.models.utils.management import _new_management
|
|
16
16
|
from hestia_earth.models.utils.term import get_lookup_value
|
|
@@ -896,11 +896,15 @@ def _should_run_historical_land_use_change_single_crop(
|
|
|
896
896
|
land_use_type=land_use_type,
|
|
897
897
|
permanent_crops_net_expansion=permanent_crops_net_expansion
|
|
898
898
|
)
|
|
899
|
+
capped_expansion_factor = clamp(
|
|
900
|
+
value=expansion_factor * e9_net_expansion * net_expansion_cultivated_vs_harvested,
|
|
901
|
+
min_value=0,
|
|
902
|
+
max_value=1
|
|
903
|
+
)
|
|
899
904
|
|
|
900
905
|
site_area = {
|
|
901
|
-
land_type: (
|
|
902
|
-
|
|
903
|
-
) for land_type in LAND_USE_TERMS_FOR_TRANSFORMATION.keys()
|
|
906
|
+
land_type: (shares_of_expansion[land_type] * capped_expansion_factor)
|
|
907
|
+
for land_type in LAND_USE_TERMS_FOR_TRANSFORMATION.keys()
|
|
904
908
|
if land_type != land_use_type
|
|
905
909
|
}
|
|
906
910
|
site_area[land_use_type] = 1 - sum(site_area.values())
|
|
@@ -941,6 +945,9 @@ def _get_land_use_term_from_node(node: dict):
|
|
|
941
945
|
return _get_lookup_with_cache(lookup_term=node.get("term", {}), column=LOOKUPS.get("landCover")[1])
|
|
942
946
|
|
|
943
947
|
|
|
948
|
+
def _date_strip(date: str): return date[:10] if date else None
|
|
949
|
+
|
|
950
|
+
|
|
944
951
|
def _collect_land_use_types(nodes: list) -> list:
|
|
945
952
|
"""Look up the land use type from management nodes."""
|
|
946
953
|
return [
|
|
@@ -949,8 +956,8 @@ def _collect_land_use_types(nodes: list) -> list:
|
|
|
949
956
|
"term": node.get("term", {}),
|
|
950
957
|
"id": node.get("term", {}).get("@id"),
|
|
951
958
|
"land-use-type": _get_land_use_term_from_node(node),
|
|
952
|
-
"endDate": _gapfill_datestr(datestr=node.get("endDate"), mode=DatestrGapfillMode.END)
|
|
953
|
-
"startDate": _gapfill_datestr(datestr=node.get("startDate"), mode=DatestrGapfillMode.START)
|
|
959
|
+
"endDate": _date_strip(_gapfill_datestr(datestr=node.get("endDate"), mode=DatestrGapfillMode.END)),
|
|
960
|
+
"startDate": _date_strip(_gapfill_datestr(datestr=node.get("startDate"), mode=DatestrGapfillMode.START))
|
|
954
961
|
} for node in nodes
|
|
955
962
|
]
|
|
956
963
|
|
|
@@ -212,7 +212,7 @@ def _format_inventory(inventory: list[SiteData], default: str = "None") -> str:
|
|
|
212
212
|
|
|
213
213
|
def _should_run(impact_assessment: dict):
|
|
214
214
|
|
|
215
|
-
cycle = impact_assessment.get("cycle")
|
|
215
|
+
cycle = impact_assessment.get("cycle", {})
|
|
216
216
|
functional_unit = cycle.get("functionalUnit")
|
|
217
217
|
|
|
218
218
|
product = get_product(impact_assessment)
|
|
@@ -286,7 +286,7 @@ def _dates_overlap(target_practice: dict, node: dict, cycle: dict, site_type_id:
|
|
|
286
286
|
])
|
|
287
287
|
|
|
288
288
|
|
|
289
|
-
def _should_run_practice(management_nodes: list, cycle: dict, site_type_id: str):
|
|
289
|
+
def _should_run_practice(site: dict, management_nodes: list, cycle: dict, site_type_id: str):
|
|
290
290
|
"""
|
|
291
291
|
Include only landUseManagement practices where GAP_FILL_TO_MANAGEMENT = True
|
|
292
292
|
"""
|
|
@@ -297,21 +297,34 @@ def _should_run_practice(management_nodes: list, cycle: dict, site_type_id: str)
|
|
|
297
297
|
for node in filter_list_term_type(management_nodes, TermTermType.LANDCOVER)
|
|
298
298
|
]
|
|
299
299
|
|
|
300
|
-
def
|
|
300
|
+
def exec(practice: dict):
|
|
301
301
|
term = practice.get('term', {})
|
|
302
|
-
|
|
303
|
-
|
|
302
|
+
term_id = term['@id']
|
|
303
|
+
should_gap_fill = term.get('termType') != TermTermType.LANDUSEMANAGEMENT.value or _should_gap_fill(term)
|
|
304
|
+
target_group = get_lookup_value(term, 'sumIs100Group', skip_debug=True, model=MODEL)
|
|
305
|
+
no_other_land_cover_in_same_group = next((
|
|
304
306
|
True for node in landCover_management_nodes
|
|
305
307
|
if (
|
|
306
308
|
node['sumIs100Group'] == target_group and
|
|
307
309
|
_dates_overlap(target_practice=practice, node=node, cycle=cycle, site_type_id=site_type_id)
|
|
308
310
|
)
|
|
309
|
-
), None) is
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
311
|
+
), None) is None
|
|
312
|
+
# cannot gap-fill landCover without a `startDate`
|
|
313
|
+
has_required_startDate = term.get('termType') != TermTermType.LANDCOVER.value or practice.get('startDate')
|
|
314
|
+
|
|
315
|
+
should_run = all([
|
|
316
|
+
should_gap_fill,
|
|
317
|
+
has_required_startDate,
|
|
318
|
+
no_other_land_cover_in_same_group
|
|
319
|
+
])
|
|
320
|
+
if not should_run:
|
|
321
|
+
logRequirements(site, model=MODEL, term=term_id, model_key=MODEL_KEY,
|
|
322
|
+
should_gap_fill=should_gap_fill,
|
|
323
|
+
has_required_startDate=has_required_startDate,
|
|
324
|
+
no_other_land_cover_in_same_group=no_other_land_cover_in_same_group)
|
|
325
|
+
logShouldRun(site, MODEL, term_id, False, model_key=MODEL_KEY)
|
|
326
|
+
return should_run
|
|
327
|
+
return exec
|
|
315
328
|
|
|
316
329
|
|
|
317
330
|
def _run_from_practices(site: dict, cycle: dict, site_type_id: str):
|
|
@@ -330,7 +343,8 @@ def _run_from_practices(site: dict, cycle: dict, site_type_id: str):
|
|
|
330
343
|
]
|
|
331
344
|
management_nodes = site.get("management", [])
|
|
332
345
|
return list(map(_map_to_value, filter(
|
|
333
|
-
_should_run_practice(management_nodes
|
|
346
|
+
_should_run_practice(site, management_nodes, cycle, site_type_id),
|
|
347
|
+
practices
|
|
334
348
|
)))
|
|
335
349
|
|
|
336
350
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from hestia_earth.schema import SiteSiteType, TermTermType
|
|
2
2
|
from hestia_earth.utils.model import linked_node
|
|
3
|
+
from hestia_earth.utils.term import download_term
|
|
3
4
|
|
|
4
5
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
5
6
|
from hestia_earth.models.utils.practice import _new_practice
|
|
6
|
-
from hestia_earth.models.utils.term import download_term
|
|
7
7
|
from . import MODEL
|
|
8
8
|
|
|
9
9
|
REQUIREMENTS = {
|
|
@@ -2,7 +2,7 @@ from os.path import dirname, abspath
|
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
4
|
from hestia_earth.models.utils import _run_in_serie
|
|
5
|
-
from . import cycle, site, remove_cache_fields
|
|
5
|
+
from . import cycle, site, remove_cache_fields, remove_no_value
|
|
6
6
|
|
|
7
7
|
CURRENT_DIR = dirname(abspath(__file__)) + '/'
|
|
8
8
|
sys.path.append(CURRENT_DIR)
|
|
@@ -10,7 +10,8 @@ sys.path.append(CURRENT_DIR)
|
|
|
10
10
|
MODELS = [
|
|
11
11
|
cycle.run,
|
|
12
12
|
site.run,
|
|
13
|
-
remove_cache_fields.run
|
|
13
|
+
remove_cache_fields.run,
|
|
14
|
+
remove_no_value.run
|
|
14
15
|
]
|
|
15
16
|
|
|
16
17
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
_KEYS = ['impacts', 'endpoints']
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def _has_value(blank_node: dict):
|
|
5
|
+
return blank_node.get('value') is not None
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def _filter_has_value(impact: dict, key: str):
|
|
9
|
+
return list(filter(_has_value, impact[key]))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def run(impact: dict):
|
|
13
|
+
return impact | {key: _filter_has_value(impact, key) for key in _KEYS if impact.get(key)}
|
|
@@ -110,7 +110,7 @@ def _should_run(site: dict) -> tuple[bool, dict]:
|
|
|
110
110
|
"""
|
|
111
111
|
cycles = related_cycles(site)
|
|
112
112
|
site_type = site.get("siteType")
|
|
113
|
-
ipcc_soil_category = _assign_ipcc_soil_category(site.get("measurements", []))
|
|
113
|
+
ipcc_soil_category, soil_logs = _assign_ipcc_soil_category(site.get("measurements", []))
|
|
114
114
|
|
|
115
115
|
has_cycles = len(cycles) > 0
|
|
116
116
|
has_valid_site_type = site_type in _VALID_SITE_TYPES
|
|
@@ -140,6 +140,7 @@ def _should_run(site: dict) -> tuple[bool, dict]:
|
|
|
140
140
|
should_compile_inventory=should_compile_inventory,
|
|
141
141
|
seed=seed,
|
|
142
142
|
inventory=_format_inventory(inventory),
|
|
143
|
+
**soil_logs,
|
|
143
144
|
**_format_logs(logs)
|
|
144
145
|
)
|
|
145
146
|
|
|
@@ -7,7 +7,6 @@ from hestia_earth.utils.tools import safe_parse_float, list_sum
|
|
|
7
7
|
from hestia_earth.models.log import debugValues, logRequirements, debugMissingLookup, logShouldRun, log_as_table
|
|
8
8
|
from hestia_earth.models.utils import _filter_list_term_unit
|
|
9
9
|
from hestia_earth.models.utils.constant import Units, DAYS_PER_MONTH
|
|
10
|
-
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
|
11
10
|
from hestia_earth.models.utils.productivity import PRODUCTIVITY, get_productivity
|
|
12
11
|
from hestia_earth.models.utils.emission import _new_emission
|
|
13
12
|
from hestia_earth.models.utils.measurement import most_relevant_measurement_value
|
|
@@ -17,7 +16,6 @@ from . import MODEL
|
|
|
17
16
|
|
|
18
17
|
REQUIREMENTS = {
|
|
19
18
|
"Cycle": {
|
|
20
|
-
"completeness.excreta": "",
|
|
21
19
|
"cycleDuration": "",
|
|
22
20
|
"endDate": "",
|
|
23
21
|
"practices": [{"@type": "Practice", "value": "", "term.termType": "excretaManagement"}],
|
|
@@ -75,7 +73,7 @@ def _emission(value: float):
|
|
|
75
73
|
|
|
76
74
|
|
|
77
75
|
def _run(excreta_b0_product: float, ch4_conv_factor: float):
|
|
78
|
-
value = excreta_b0_product * 0.67 * ch4_conv_factor / 100
|
|
76
|
+
value = (excreta_b0_product or 0) * 0.67 * (ch4_conv_factor or 0) / 100
|
|
79
77
|
return [_emission(value)]
|
|
80
78
|
|
|
81
79
|
|
|
@@ -120,12 +118,15 @@ def _get_ch4_conv_factor(cycle: dict):
|
|
|
120
118
|
ecoClimateZone=ecoClimateZone,
|
|
121
119
|
practice_id=practice_id)
|
|
122
120
|
|
|
123
|
-
return _get_excretaManagement_MCF_from_lookup(practice_id, ecoClimateZone, duration_key) if
|
|
121
|
+
return _get_excretaManagement_MCF_from_lookup(practice_id, ecoClimateZone, duration_key) if all([
|
|
122
|
+
practice_id,
|
|
123
|
+
ecoClimateZone is not None
|
|
124
|
+
]) else None
|
|
124
125
|
|
|
125
126
|
|
|
126
127
|
def _should_run(cycle: dict):
|
|
127
128
|
country = cycle.get('site', {}).get('country', {})
|
|
128
|
-
|
|
129
|
+
|
|
129
130
|
# total of excreta including the CH4 factor
|
|
130
131
|
excreta = filter_list_term_type(cycle.get('inputs', []), TermTermType.EXCRETA)
|
|
131
132
|
excreta = _filter_list_term_unit(excreta, Units.KG_VS)
|
|
@@ -135,21 +136,23 @@ def _should_run(cycle: dict):
|
|
|
135
136
|
excreta_logs = log_as_table([
|
|
136
137
|
{'id': id, 'value': v, 'b0': b0} for id, v, b0 in excreta_values
|
|
137
138
|
])
|
|
138
|
-
|
|
139
|
+
excreta_total = list_sum([
|
|
140
|
+
v * f for id, v, f in excreta_values if v is not None and f is not None
|
|
141
|
+
], default=None)
|
|
139
142
|
|
|
140
143
|
ch4_conv_factor = _get_ch4_conv_factor(cycle)
|
|
141
144
|
|
|
142
145
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
excreta_details=excreta_logs,
|
|
147
|
+
excreta_total=excreta_total,
|
|
148
|
+
CH4_conv_factor=ch4_conv_factor,
|
|
146
149
|
country=country.get('@id'))
|
|
147
150
|
|
|
148
|
-
should_run =
|
|
151
|
+
should_run = all([excreta_total is not None, ch4_conv_factor is not None])
|
|
149
152
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
150
|
-
return should_run,
|
|
153
|
+
return should_run, excreta_total, ch4_conv_factor
|
|
151
154
|
|
|
152
155
|
|
|
153
156
|
def run(cycle: dict):
|
|
154
|
-
should_run,
|
|
155
|
-
return _run(
|
|
157
|
+
should_run, excreta_total, ch4_conv_factor = _should_run(cycle)
|
|
158
|
+
return _run(excreta_total, ch4_conv_factor) if should_run else []
|
|
@@ -23,7 +23,11 @@ REQUIREMENTS = {
|
|
|
23
23
|
],
|
|
24
24
|
"optional": {
|
|
25
25
|
"measurements": [
|
|
26
|
-
{
|
|
26
|
+
{
|
|
27
|
+
"@doc": "The model cannot run on sites with more than 30 percent organic soils (`histols`, `histosol` and their subclasses).", # noqa: E501
|
|
28
|
+
"@type": "Measurement", "value": "",
|
|
29
|
+
"term.termType": ["soilType", "usdaSoilType"]
|
|
30
|
+
}
|
|
27
31
|
],
|
|
28
32
|
"management": [
|
|
29
33
|
{
|