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.

Files changed (49) hide show
  1. hestia_earth/models/cache_sites.py +1 -1
  2. hestia_earth/models/faostat2018/liveweightPerHead.py +1 -1
  3. hestia_earth/models/faostat2018/product/price.py +1 -1
  4. hestia_earth/models/geospatialDatabase/ecoClimateZone.py +1 -1
  5. hestia_earth/models/geospatialDatabase/region.py +1 -1
  6. hestia_earth/models/geospatialDatabase/utils.py +1 -1
  7. hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +2 -1
  8. hestia_earth/models/haversineFormula/transport/distance.py +1 -1
  9. hestia_earth/models/hestia/aboveGroundCropResidue.py +1 -3
  10. hestia_earth/models/hestia/cropResidueManagement.py +1 -0
  11. hestia_earth/models/hestia/excretaKgMass.py +1 -1
  12. hestia_earth/models/hestia/landCover.py +13 -6
  13. hestia_earth/models/hestia/landOccupationDuringCycle.py +1 -1
  14. hestia_earth/models/hestia/management.py +25 -11
  15. hestia_earth/models/hestia/pastureGrass.py +1 -1
  16. hestia_earth/models/impact_assessment/post_checks/__init__.py +3 -2
  17. hestia_earth/models/impact_assessment/post_checks/remove_no_value.py +13 -0
  18. hestia_earth/models/ipcc2019/biocharOrganicCarbonPerHa.py +2 -1
  19. hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +16 -13
  20. hestia_earth/models/ipcc2019/organicCarbonPerHa.py +5 -1
  21. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +88 -101
  22. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +21 -0
  23. hestia_earth/models/mocking/search-results.json +1 -1
  24. hestia_earth/models/site/pre_checks/country.py +1 -2
  25. hestia_earth/models/utils/__init__.py +7 -5
  26. hestia_earth/models/utils/blank_node.py +7 -2
  27. hestia_earth/models/utils/completeness.py +1 -2
  28. hestia_earth/models/utils/emission.py +1 -1
  29. hestia_earth/models/utils/indicator.py +1 -1
  30. hestia_earth/models/utils/input.py +1 -1
  31. hestia_earth/models/utils/management.py +1 -1
  32. hestia_earth/models/utils/measurement.py +2 -1
  33. hestia_earth/models/utils/method.py +1 -2
  34. hestia_earth/models/utils/practice.py +1 -1
  35. hestia_earth/models/utils/product.py +2 -1
  36. hestia_earth/models/utils/property.py +2 -1
  37. hestia_earth/models/utils/term.py +1 -27
  38. hestia_earth/models/version.py +1 -1
  39. {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/METADATA +2 -2
  40. {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/RECORD +49 -46
  41. tests/models/hestia/test_aboveGroundCropResidue.py +13 -35
  42. tests/models/hestia/test_landOccupationDuringCycle.py +9 -2
  43. tests/models/impact_assessment/post_checks/test_remove_cache_fields.py +6 -0
  44. tests/models/impact_assessment/post_checks/test_remove_no_value.py +17 -0
  45. tests/models/ipcc2019/test_ch4ToAirExcreta.py +0 -12
  46. tests/models/ipcc2019/test_organicCarbonPerHa_tier_1.py +1 -1
  47. {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/LICENSE +0 -0
  48. {hestia_earth_models-0.74.8.dist-info → hestia_earth_models-0.74.10.dist-info}/WHEEL +0 -0
  49. {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
@@ -77,4 +77,4 @@ def _should_run(site: dict):
77
77
  return should_run
78
78
 
79
79
 
80
- def run(site: dict): return _run(site) if _should_run(site) else _run_default(site)
80
+ def run(site: dict): return (_run(site) if _should_run(site) else []) or _run_default(site)
@@ -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, download_term
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 > 0 and value is not None and value >= 0:
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
- shares_of_expansion[land_type] * expansion_factor * e9_net_expansion * net_expansion_cultivated_vs_harvested
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)[:10],
953
- "startDate": _gapfill_datestr(datestr=node.get("startDate"), mode=DatestrGapfillMode.START)[:10]
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 run(practice: dict):
300
+ def exec(practice: dict):
301
301
  term = practice.get('term', {})
302
- target_group = get_lookup_value(practice.get("term", {}), 'sumIs100Group', skip_debug=True, model=MODEL)
303
- has_other_land_cover_in_same_group = next((
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 not None
310
- return (
311
- (term.get('termType') != TermTermType.LANDUSEMANAGEMENT.value or _should_gap_fill(term)) and
312
- not has_other_land_cover_in_same_group
313
- )
314
- return run
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=management_nodes, cycle=cycle, site_type_id=site_type_id), practices
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 practice_id else 0
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
- excreta_complete = _is_term_type_complete(cycle, TermTermType.EXCRETA)
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
- excreta_b0_product = list_sum([v * f for id, v, f in excreta_values if v is not None and f is not None])
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
- term_type_excreta_complete=excreta_complete,
144
- excreta=excreta_logs,
145
- ch4_conv_factor=ch4_conv_factor,
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 = excreta_complete or all([excreta_b0_product, ch4_conv_factor])
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, excreta_b0_product, ch4_conv_factor
153
+ return should_run, excreta_total, ch4_conv_factor
151
154
 
152
155
 
153
156
  def run(cycle: dict):
154
- should_run, excreta_b0_product, ch4_conv_factor = _should_run(cycle)
155
- return _run(excreta_b0_product, ch4_conv_factor) if should_run else []
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
- {"@type": "Measurement", "value": "", "term.termType": ["soilType", "usdaSoilType"]}
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
  {