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
@@ -1,6 +1,6 @@
1
1
  from hestia_earth.schema import CycleFunctionalUnit, SiteSiteType, TermTermType
2
2
  from hestia_earth.utils.model import filter_list_term_type, find_term_match, find_primary_product
3
- from hestia_earth.utils.tools import list_sum, safe_parse_float, safe_parse_date
3
+ from hestia_earth.utils.tools import flatten, list_sum, safe_parse_float, safe_parse_date
4
4
 
5
5
  from ..log import logRequirements, debugValues
6
6
  from .lookup import factor_value
@@ -70,7 +70,8 @@ def get_crop_residue_decomposition_N_total(cycle: dict) -> float:
70
70
  products = [
71
71
  p for p in products if get_lookup_value(p.get('term'), 'decomposesOnField')
72
72
  ]
73
- return list_sum(get_N_total(products), None) if _is_term_type_complete(cycle, TermTermType.CROPRESIDUE) else None
73
+ default_value = 0 if _is_term_type_complete(cycle, TermTermType.CROPRESIDUE) else None
74
+ return list_sum(get_N_total(products), default_value)
74
75
 
75
76
 
76
77
  def get_excreta_N_total(cycle: dict) -> float:
@@ -95,7 +96,8 @@ def get_excreta_N_total(cycle: dict) -> float:
95
96
  inputs = filter_list_term_type(cycle.get('inputs', []), TermTermType.EXCRETA)
96
97
  products = filter_list_term_type(cycle.get('products', []), TermTermType.EXCRETA)
97
98
  values = get_N_total(inputs) + get_N_total(products)
98
- return list_sum(values, None) if _is_term_type_complete(cycle, TermTermType.EXCRETA) else None
99
+ default_value = 0 if _is_term_type_complete(cycle, TermTermType.EXCRETA) else None
100
+ return list_sum(values, default_value)
99
101
 
100
102
 
101
103
  def get_organic_fertiliser_N_total(cycle: dict) -> float:
@@ -120,7 +122,8 @@ def get_organic_fertiliser_N_total(cycle: dict) -> float:
120
122
  The total value as a number.
121
123
  """
122
124
  values = get_N_total(filter_list_term_type(cycle.get('inputs', []), TermTermType.ORGANICFERTILISER))
123
- return list_sum(values, None) if _is_term_type_complete(cycle, 'fertiliser') else None
125
+ default_value = 0 if _is_term_type_complete(cycle, 'fertiliser') else None
126
+ return list_sum(values, default_value)
124
127
 
125
128
 
126
129
  def get_organic_fertiliser_P_total(cycle: dict) -> float:
@@ -145,7 +148,8 @@ def get_organic_fertiliser_P_total(cycle: dict) -> float:
145
148
  The total value as a number.
146
149
  """
147
150
  values = get_P2O5_total(filter_list_term_type(cycle.get('inputs', []), TermTermType.ORGANICFERTILISER))
148
- return list_sum(values, None) if _is_term_type_complete(cycle, 'fertiliser') else None
151
+ default_value = 0 if _is_term_type_complete(cycle, 'fertiliser') else None
152
+ return list_sum(values, default_value)
149
153
 
150
154
 
151
155
  def get_inorganic_fertiliser_N_total(cycle: dict) -> float:
@@ -168,7 +172,8 @@ def get_inorganic_fertiliser_N_total(cycle: dict) -> float:
168
172
  The total value as a number.
169
173
  """
170
174
  values = get_N_total(filter_list_term_type(cycle.get('inputs', []), TermTermType.INORGANICFERTILISER))
171
- return list_sum(values, None) if _is_term_type_complete(cycle, 'fertiliser') else None
175
+ default_value = 0 if _is_term_type_complete(cycle, 'fertiliser') else None
176
+ return list_sum(values, default_value)
172
177
 
173
178
 
174
179
  def get_inorganic_fertiliser_P_total(cycle: dict) -> float:
@@ -191,7 +196,8 @@ def get_inorganic_fertiliser_P_total(cycle: dict) -> float:
191
196
  The total value as a number.
192
197
  """
193
198
  values = get_P2O5_total(filter_list_term_type(cycle.get('inputs', []), TermTermType.INORGANICFERTILISER))
194
- return list_sum(values, None) if _is_term_type_complete(cycle, 'fertiliser') else None
199
+ default_value = 0 if _is_term_type_complete(cycle, 'fertiliser') else None
200
+ return list_sum(values, default_value)
195
201
 
196
202
 
197
203
  def get_max_rooting_depth(cycle: dict) -> float:
@@ -364,7 +370,7 @@ def is_organic(cycle: dict):
364
370
 
365
371
  def is_irrigated(cycle: dict):
366
372
  """
367
- Check if the `Cycle` is irrigated, i.e. if it contains an irrigated `Practice`.
373
+ Check if the `Cycle` is irrigated, i.e. if it contains an irrigated `Practice` with a value above `0`.
368
374
 
369
375
  Parameters
370
376
  ----------
@@ -376,7 +382,10 @@ def is_irrigated(cycle: dict):
376
382
  bool
377
383
  `True` if the `Cycle` is irrigated, `False` otherwise.
378
384
  """
379
- return list_sum(find_term_match(cycle.get('practices', []), 'irrigated').get('value', [])) > 0
385
+ irrigated_practices = [
386
+ p for p in cycle.get('practices', []) if p.get('term', {}).get('@id', '').startswith('irrigated')
387
+ ]
388
+ return list_sum(flatten([p.get('value', []) for p in irrigated_practices])) > 0
380
389
 
381
390
 
382
391
  def cycle_end_year(cycle: dict):
@@ -17,7 +17,7 @@ from .term import get_lookup_value
17
17
  # TODO: verify those values
18
18
  MAX_DEPTH = 1000
19
19
  OLDEST_DATE = '1800'
20
-
20
+ SOIL_TEXTURE_IDS = ['sandContent', 'siltContent', 'clayContent']
21
21
  MEASUREMENT_REDUCE = {
22
22
  'mean': lambda value: mean(value),
23
23
  'mode': lambda value: mode(value),
@@ -87,24 +87,24 @@ def node_has_property(term_id: str):
87
87
  return lambda product: find_term_match(product.get('properties', []), term_id, None) is not None
88
88
 
89
89
 
90
- def node_property_lookup_value(model: str, term: dict, prop_id: str, default=None):
90
+ def node_property_lookup_value(model: str, term: dict, prop_id: str, default=None, **log_args):
91
91
  # as the lookup table might not exist, we are making sure we return `0` in thise case
92
92
  try:
93
93
  lookup_name = f"{term.get('termType')}-property.csv"
94
94
  lookup = download_lookup(lookup_name)
95
95
  term_id = term.get('@id')
96
96
  value = extract_grouped_data(get_table_value(lookup, 'termid', term_id, column_name(prop_id)), 'Avg')
97
- debugMissingLookup(lookup_name, 'termid', term_id, prop_id, value, model=model, term=term_id)
97
+ debugMissingLookup(lookup_name, 'termid', term_id, prop_id, value, model=model, term=term_id, **log_args)
98
98
  return safe_parse_float(value, default=None)
99
99
  except Exception:
100
100
  return default
101
101
 
102
102
 
103
- def get_node_property_value(model: str, node: dict, prop_id: str, default=None):
103
+ def get_node_property_value(model: str, node: dict, prop_id: str, default=None, **log_args):
104
104
  prop = get_node_property(node, prop_id)
105
105
  term = (prop or {}).get('term', download_hestia(prop_id))
106
106
  units = (term or {}).get('units')
107
- value = prop.get('value') if prop else node_property_lookup_value(model, node.get('term', {}), prop_id)
107
+ value = prop.get('value') if prop else node_property_lookup_value(model, node.get('term', {}), prop_id, **log_args)
108
108
  return default if value is None else (value / 100 if units == '%' else value)
109
109
 
110
110
 
@@ -8,13 +8,13 @@ from .constant import Units
8
8
  LIMIT = 1000
9
9
 
10
10
 
11
- def get_lookup_value(lookup_term: dict, column: str, skip_debug: bool = False, **kwargs):
11
+ def get_lookup_value(lookup_term: dict, column: str, skip_debug: bool = False, **log_args):
12
12
  table_name = f"{lookup_term.get('termType')}.csv" if lookup_term else None
13
13
  value = get_table_value(
14
14
  download_lookup(table_name), 'termid', lookup_term.get('@id'), column_name(column)
15
15
  ) if table_name else None
16
16
  debugMissingLookup(
17
- table_name, 'termid', lookup_term.get('@id'), column, value, **kwargs
17
+ table_name, 'termid', lookup_term.get('@id'), column, value, **log_args
18
18
  ) if lookup_term and not skip_debug else None
19
19
  return value
20
20
 
@@ -544,7 +544,7 @@ def get_residue_removed_or_burnt_terms():
544
544
  return list(map(lambda n: n["@id"], terms))
545
545
 
546
546
 
547
- def get_rice_plant_upland_terms():
547
+ def get_upland_rice_land_cover_terms():
548
548
  """
549
549
  Find all `landCover` terms related to upland rice the Glossary.
550
550
 
@@ -566,6 +566,28 @@ def get_rice_plant_upland_terms():
566
566
  return list(map(lambda n: n["@id"], terms))
567
567
 
568
568
 
569
+ def get_upland_rice_crop_terms():
570
+ """
571
+ Find all `crop` terms related to upland rice the Glossary.
572
+
573
+ Returns
574
+ -------
575
+ list
576
+ List of matching term `@id` as `str`.
577
+ """
578
+ terms = search({
579
+ "bool": {
580
+ "must": [
581
+ {"match": {"@type": SchemaType.TERM.value}},
582
+ {"match": {"termType.keyword": TermTermType.CROP.value}},
583
+ {"match_phrase": {"name": "rice"}},
584
+ {"match": {"name": "upland"}}
585
+ ],
586
+ }
587
+ }, limit=LIMIT)
588
+ return list(map(lambda n: n["@id"], terms))
589
+
590
+
569
591
  def get_pasture_system_terms():
570
592
  """
571
593
  Find all `system` terms with the name `pasture`:
@@ -581,3 +603,26 @@ def get_pasture_system_terms():
581
603
  'name': 'pasture'
582
604
  }, limit=LIMIT)
583
605
  return list(map(lambda n: n["@id"], terms))
606
+
607
+
608
+ def get_long_fallow_land_cover_terms():
609
+ """
610
+ Find all `landCover` terms with the name `long fallow`:
611
+ https://hestia.earth/glossary?termType=landCover&query=long%fallow
612
+
613
+ Returns
614
+ -------
615
+ list
616
+ List of matching term `@id` as `str`.
617
+ """
618
+ terms = search({
619
+ "bool": {
620
+ "must": [
621
+ {"match": {"@type": SchemaType.TERM.value}},
622
+ {"match": {"termType.keyword": TermTermType.LANDCOVER.value}},
623
+ {"match_phrase_prefix": {"name": "long"}},
624
+ {"match": {"name": "fallow"}}
625
+ ],
626
+ }
627
+ }, limit=LIMIT)
628
+ return list(map(lambda n: n["@id"], terms))
@@ -1 +1 @@
1
- VERSION = '0.57.2'
1
+ VERSION = '0.59.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hestia-earth-models
3
- Version: 0.57.2
3
+ Version: 0.59.0
4
4
  Summary: Hestia's set of modules for filling gaps in the activity data using external datasets (e.g. populating soil properties with a geospatial dataset using provided coordinates) and internal lookups (e.g. populating machinery use from fuel use). Includes rules for when gaps should be filled versus not (e.g. never gap fill yield, gap fill crop residue if yield provided etc.).
5
5
  Home-page: https://gitlab.com/hestia-earth/hestia-engine-models
6
6
  Author: Hestia Team
@@ -11,7 +11,7 @@ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
11
  Classifier: Programming Language :: Python :: 3.6
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: hestia-earth.schema ==26.*
14
+ Requires-Dist: hestia-earth.schema ==27.*
15
15
  Requires-Dist: hestia-earth.utils >=0.12.2
16
16
  Requires-Dist: python-dateutil >=2.8.1
17
17
  Requires-Dist: CurrencyConverter ==0.16.8
@@ -55,19 +55,15 @@ run('no3ToGroundwaterSoilFlux', cycle_data)
55
55
 
56
56
  ### Using Spatial Models
57
57
 
58
- We have models that can gap-fill geographical information on a `Site`.
59
- If you want to use thse models:
58
+ We have models that can gap-fill geographical information on a `Site`. If you want to use these models:
60
59
  1. Install the library: `pip install hestia_earth.earth_engine`
61
60
  2. Follow the [Getting Started instructions](https://gitlab.com/hestia-earth/hestia-earth-engine#getting-started).
62
61
 
63
- ### Using Ecoinvent Model
62
+ ### Using the ecoinventV3 model
64
63
 
65
64
  ecoinvent is a consistent, transparent, and well validated life cycle inventory database.
66
65
  We use ecoinvent data to ascertain the environmental impacts of activities that occur outside of our system boundary, for example data on the environmental impacts of extracting oil and producing diesel, or the impacts of manufacturing plastics.
67
- To include these data in your environmental impact assessments using Hestia, you must own a suitable [ecoinvent license](https://ecoinvent.org/offerings/licences/).
68
66
 
69
- Please contact us at community@hestia.earth for instructions to download the required file to run the model.
70
- Once downloaded, copy the file in the _hestia_earth/models/data/ecoinventV3_ folder.
71
- Thank you!
67
+ The `ecoinventV3` model requires a valid [license](https://ecoinvent.org/offerings/licences/) to run. We are currently working on a way to enable users of this code with a valid ecoinvent licence to run these models themselves, but for now, these models are only available on the public platform.
72
68
 
73
69