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

Files changed (42) hide show
  1. hestia_earth/models/config/Cycle.json +183 -16
  2. hestia_earth/models/cycle/product/economicValueShare.py +4 -4
  3. hestia_earth/models/emepEea2019/blackCarbonToAirFuelCombustion.py +33 -0
  4. hestia_earth/models/emepEea2019/ch4ToAirFuelCombustion.py +33 -0
  5. hestia_earth/models/emepEea2019/coToAirFuelCombustion.py +33 -0
  6. hestia_earth/models/emepEea2019/nmvocToAirFuelCombustion.py +33 -0
  7. hestia_earth/models/emepEea2019/pm10ToAirFuelCombustion.py +33 -0
  8. hestia_earth/models/emepEea2019/pm25ToAirFuelCombustion.py +33 -0
  9. hestia_earth/models/emepEea2019/tspToAirFuelCombustion.py +33 -0
  10. hestia_earth/models/faostat2018/seed.py +9 -8
  11. hestia_earth/models/geospatialDatabase/histosol.py +31 -11
  12. hestia_earth/models/hestia/aboveGroundCropResidueTotal.py +2 -2
  13. hestia_earth/models/hestia/management.py +5 -4
  14. hestia_earth/models/hestia/soilClassification.py +31 -13
  15. hestia_earth/models/ipcc2019/animal/pastureGrass.py +19 -11
  16. hestia_earth/models/ipcc2019/burning_utils.py +406 -4
  17. hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +26 -8
  18. hestia_earth/models/ipcc2019/ch4ToAirOrganicSoilCultivation.py +8 -11
  19. hestia_earth/models/ipcc2019/co2ToAirOrganicSoilCultivation.py +9 -12
  20. hestia_earth/models/ipcc2019/emissionsToAirOrganicSoilBurning.py +516 -0
  21. hestia_earth/models/ipcc2019/n2OToAirOrganicSoilCultivationDirect.py +10 -13
  22. hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +56 -433
  23. hestia_earth/models/ipcc2019/organicSoilCultivation_utils.py +2 -2
  24. hestia_earth/models/ipcc2019/pastureGrass.py +19 -11
  25. hestia_earth/models/ipcc2019/pastureGrass_utils.py +17 -10
  26. hestia_earth/models/linkedImpactAssessment/emissions.py +1 -1
  27. hestia_earth/models/mocking/search-results.json +1 -1
  28. hestia_earth/models/pefcrGuidanceDocument2017/__init__.py +13 -0
  29. hestia_earth/models/pefcrGuidanceDocument2017/pesticideToAirPesticideApplication.py +29 -0
  30. hestia_earth/models/pefcrGuidanceDocument2017/pesticideToSoilPesticideApplication.py +29 -0
  31. hestia_earth/models/pefcrGuidanceDocument2017/pesticideToWaterPesticideApplication.py +29 -0
  32. hestia_earth/models/pefcrGuidanceDocument2017/utils.py +55 -0
  33. hestia_earth/models/pooreNemecek2018/saplingsDepreciatedAmountPerCycle.py +1 -1
  34. hestia_earth/models/utils/blank_node.py +68 -0
  35. hestia_earth/models/utils/impact_assessment.py +3 -0
  36. hestia_earth/models/version.py +1 -1
  37. hestia_earth/orchestrator/strategies/merge/merge_node.py +32 -2
  38. {hestia_earth_models-0.75.1.dist-info → hestia_earth_models-0.75.3.dist-info}/METADATA +1 -1
  39. {hestia_earth_models-0.75.1.dist-info → hestia_earth_models-0.75.3.dist-info}/RECORD +42 -29
  40. {hestia_earth_models-0.75.1.dist-info → hestia_earth_models-0.75.3.dist-info}/WHEEL +0 -0
  41. {hestia_earth_models-0.75.1.dist-info → hestia_earth_models-0.75.3.dist-info}/licenses/LICENSE +0 -0
  42. {hestia_earth_models-0.75.1.dist-info → hestia_earth_models-0.75.3.dist-info}/top_level.txt +0 -0
@@ -755,22 +755,24 @@
755
755
  "mergeStrategy": "list",
756
756
  "stage": 2
757
757
  },
758
- {
759
- "key": "inputs",
760
- "model": "ipcc2019",
761
- "value": "pastureGrass",
762
- "runStrategy": "always",
763
- "mergeStrategy": "list",
764
- "stage": 2
765
- },
766
- {
767
- "key": "animals",
768
- "model": "ipcc2019",
769
- "value": "animal.pastureGrass",
770
- "runStrategy": "always",
771
- "mergeStrategy": "list",
772
- "stage": 2
773
- },
758
+ [
759
+ {
760
+ "key": "inputs",
761
+ "model": "ipcc2019",
762
+ "value": "pastureGrass",
763
+ "runStrategy": "always",
764
+ "mergeStrategy": "list",
765
+ "stage": 2
766
+ },
767
+ {
768
+ "key": "animals",
769
+ "model": "ipcc2019",
770
+ "value": "animal.pastureGrass",
771
+ "runStrategy": "always",
772
+ "mergeStrategy": "list",
773
+ "stage": 2
774
+ }
775
+ ],
774
776
  [
775
777
  {
776
778
  "key": "products",
@@ -1294,6 +1296,21 @@
1294
1296
  },
1295
1297
  "stage": 2
1296
1298
  },
1299
+ {
1300
+ "key": "emissions",
1301
+ "model": "ipcc2019",
1302
+ "value": "emissionsToAirOrganicSoilBurning",
1303
+ "runStrategy": "always",
1304
+ "runArgs": {
1305
+ "runNonMeasured": true,
1306
+ "runNonAddedTerm": true
1307
+ },
1308
+ "mergeStrategy": "list",
1309
+ "mergeArgs": {
1310
+ "replaceThreshold": ["value", 0.01]
1311
+ },
1312
+ "stage": 2
1313
+ },
1297
1314
  {
1298
1315
  "key": "emissions",
1299
1316
  "model": "schmidt2007",
@@ -1353,6 +1370,51 @@
1353
1370
  "replaceThreshold": ["value", 0.01]
1354
1371
  },
1355
1372
  "stage": 2
1373
+ },
1374
+ {
1375
+ "key": "emissions",
1376
+ "model": "pefcrGuidanceDocument2017",
1377
+ "value": "pesticideToAirPesticideApplication",
1378
+ "runStrategy": "add_blank_node_if_missing",
1379
+ "runArgs": {
1380
+ "runNonMeasured": true,
1381
+ "runNonAddedTerm": true
1382
+ },
1383
+ "mergeStrategy": "list",
1384
+ "mergeArgs": {
1385
+ "replaceThreshold": ["value", 0.01]
1386
+ },
1387
+ "stage": 2
1388
+ },
1389
+ {
1390
+ "key": "emissions",
1391
+ "model": "pefcrGuidanceDocument2017",
1392
+ "value": "pesticideToSoilPesticideApplication",
1393
+ "runStrategy": "add_blank_node_if_missing",
1394
+ "runArgs": {
1395
+ "runNonMeasured": true,
1396
+ "runNonAddedTerm": true
1397
+ },
1398
+ "mergeStrategy": "list",
1399
+ "mergeArgs": {
1400
+ "replaceThreshold": ["value", 0.01]
1401
+ },
1402
+ "stage": 2
1403
+ },
1404
+ {
1405
+ "key": "emissions",
1406
+ "model": "pefcrGuidanceDocument2017",
1407
+ "value": "pesticideToWaterPesticideApplication",
1408
+ "runStrategy": "add_blank_node_if_missing",
1409
+ "runArgs": {
1410
+ "runNonMeasured": true,
1411
+ "runNonAddedTerm": true
1412
+ },
1413
+ "mergeStrategy": "list",
1414
+ "mergeArgs": {
1415
+ "replaceThreshold": ["value", 0.01]
1416
+ },
1417
+ "stage": 2
1356
1418
  }
1357
1419
  ],
1358
1420
  [
@@ -1831,6 +1893,111 @@
1831
1893
  },
1832
1894
  "stage": 2
1833
1895
  },
1896
+ {
1897
+ "key": "emissions",
1898
+ "model": "emepEea2019",
1899
+ "value": "coToAirFuelCombustion",
1900
+ "runStrategy": "add_blank_node_if_missing",
1901
+ "runArgs": {
1902
+ "runNonMeasured": true,
1903
+ "runNonAddedTerm": true
1904
+ },
1905
+ "mergeStrategy": "list",
1906
+ "mergeArgs": {
1907
+ "replaceThreshold": ["value", 0.01]
1908
+ },
1909
+ "stage": 2
1910
+ },
1911
+ {
1912
+ "key": "emissions",
1913
+ "model": "emepEea2019",
1914
+ "value": "blackCarbonToAirFuelCombustion",
1915
+ "runStrategy": "add_blank_node_if_missing",
1916
+ "runArgs": {
1917
+ "runNonMeasured": true,
1918
+ "runNonAddedTerm": true
1919
+ },
1920
+ "mergeStrategy": "list",
1921
+ "mergeArgs": {
1922
+ "replaceThreshold": ["value", 0.01]
1923
+ },
1924
+ "stage": 2
1925
+ },
1926
+ {
1927
+ "key": "emissions",
1928
+ "model": "emepEea2019",
1929
+ "value": "nmvocToAirFuelCombustion",
1930
+ "runStrategy": "add_blank_node_if_missing",
1931
+ "runArgs": {
1932
+ "runNonMeasured": true,
1933
+ "runNonAddedTerm": true
1934
+ },
1935
+ "mergeStrategy": "list",
1936
+ "mergeArgs": {
1937
+ "replaceThreshold": ["value", 0.01]
1938
+ },
1939
+ "stage": 2
1940
+ },
1941
+ {
1942
+ "key": "emissions",
1943
+ "model": "emepEea2019",
1944
+ "value": "pm10ToAirFuelCombustion",
1945
+ "runStrategy": "add_blank_node_if_missing",
1946
+ "runArgs": {
1947
+ "runNonMeasured": true,
1948
+ "runNonAddedTerm": true
1949
+ },
1950
+ "mergeStrategy": "list",
1951
+ "mergeArgs": {
1952
+ "replaceThreshold": ["value", 0.01]
1953
+ },
1954
+ "stage": 2
1955
+ },
1956
+ {
1957
+ "key": "emissions",
1958
+ "model": "emepEea2019",
1959
+ "value": "pm25ToAirFuelCombustion",
1960
+ "runStrategy": "add_blank_node_if_missing",
1961
+ "runArgs": {
1962
+ "runNonMeasured": true,
1963
+ "runNonAddedTerm": true
1964
+ },
1965
+ "mergeStrategy": "list",
1966
+ "mergeArgs": {
1967
+ "replaceThreshold": ["value", 0.01]
1968
+ },
1969
+ "stage": 2
1970
+ },
1971
+ {
1972
+ "key": "emissions",
1973
+ "model": "emepEea2019",
1974
+ "value": "tspToAirFuelCombustion",
1975
+ "runStrategy": "add_blank_node_if_missing",
1976
+ "runArgs": {
1977
+ "runNonMeasured": true,
1978
+ "runNonAddedTerm": true
1979
+ },
1980
+ "mergeStrategy": "list",
1981
+ "mergeArgs": {
1982
+ "replaceThreshold": ["value", 0.01]
1983
+ },
1984
+ "stage": 2
1985
+ },
1986
+ {
1987
+ "key": "emissions",
1988
+ "model": "emepEea2019",
1989
+ "value": "ch4ToAirFuelCombustion",
1990
+ "runStrategy": "add_blank_node_if_missing",
1991
+ "runArgs": {
1992
+ "runNonMeasured": true,
1993
+ "runNonAddedTerm": true
1994
+ },
1995
+ "mergeStrategy": "list",
1996
+ "mergeArgs": {
1997
+ "replaceThreshold": ["value", 0.01]
1998
+ },
1999
+ "stage": 2
2000
+ },
1834
2001
  {
1835
2002
  "key": "emissions",
1836
2003
  "model": "ipcc2019",
@@ -1,5 +1,5 @@
1
1
  from hestia_earth.utils.model import find_term_match
2
- from hestia_earth.utils.tools import list_sum
2
+ from hestia_earth.utils.tools import list_sum, to_precision
3
3
 
4
4
  from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
5
5
  from hestia_earth.models.utils.term import get_lookup_value
@@ -43,7 +43,7 @@ MIN_COMPLETE_VALUE = 80 # when the products are complete lower the min threshol
43
43
 
44
44
 
45
45
  def _product(product: dict, value: float):
46
- return product | {MODEL_KEY: value}
46
+ return product | {MODEL_KEY: to_precision(value, 2 if value < 1 else 3 if value < 10 else 4)}
47
47
 
48
48
 
49
49
  def _is_complete(cycle: dict): return cycle.get('completeness', {}).get('product', False)
@@ -57,11 +57,11 @@ def _total_evs(products: list): return sum([p.get(MODEL_KEY, 0) for p in product
57
57
 
58
58
  def _product_with_value(product: dict):
59
59
  value = product.get(MODEL_KEY, lookup_share(MODEL_KEY, product))
60
- return product | {MODEL_KEY: value} if value is not None else product
60
+ return _product(product, value) if value is not None else product
61
61
 
62
62
 
63
63
  def _rescale_value(products: list, total: float):
64
- return list(map(lambda p: {**p, MODEL_KEY: p.get(MODEL_KEY) * 100 / total}, products))
64
+ return list(map(lambda p: _product(p, p.get(MODEL_KEY) * 100 / total), products))
65
65
 
66
66
 
67
67
  def _should_run_by_default(cycle: dict, products: list):
@@ -0,0 +1,33 @@
1
+ from hestia_earth.schema import EmissionMethodTier
2
+
3
+ from .fuelCombustion_utils import run as run_fuelCombustion
4
+
5
+ REQUIREMENTS = {
6
+ "Cycle": {
7
+ "or": {
8
+ "inputs": [
9
+ {"@type": "Input", "value": "", "term.termType": "fuel", "optional": {
10
+ "operation": ""
11
+ }}
12
+ ],
13
+ "completeness.electricityFuel": "True"
14
+ }
15
+ }
16
+ }
17
+ RETURNS = {
18
+ "Emission": [{
19
+ "value": "",
20
+ "inputs": "",
21
+ "operation": "",
22
+ "methodTier": "tier 1"
23
+ }]
24
+ }
25
+ LOOKUPS = {
26
+ "fuel": "blackCarbonToAirFuelCombustionEmepEea2019",
27
+ "operation": "blackCarbonToAirFuelCombustionEmepEea2019"
28
+ }
29
+ TERM_ID = 'blackCarbonToAirFuelCombustion'
30
+ TIER = EmissionMethodTier.TIER_1.value
31
+
32
+
33
+ def run(cycle: dict): return run_fuelCombustion(cycle, term_id=TERM_ID)
@@ -0,0 +1,33 @@
1
+ from hestia_earth.schema import EmissionMethodTier
2
+
3
+ from .fuelCombustion_utils import run as run_fuelCombustion
4
+
5
+ REQUIREMENTS = {
6
+ "Cycle": {
7
+ "or": {
8
+ "inputs": [
9
+ {"@type": "Input", "value": "", "term.termType": "fuel", "optional": {
10
+ "operation": ""
11
+ }}
12
+ ],
13
+ "completeness.electricityFuel": "True"
14
+ }
15
+ }
16
+ }
17
+ RETURNS = {
18
+ "Emission": [{
19
+ "value": "",
20
+ "inputs": "",
21
+ "operation": "",
22
+ "methodTier": "tier 1"
23
+ }]
24
+ }
25
+ LOOKUPS = {
26
+ "fuel": "ch4ToAirFuelCombustionEmepEea2019",
27
+ "operation": "ch4ToAirFuelCombustionEmepEea2019"
28
+ }
29
+ TERM_ID = 'ch4ToAirFuelCombustion'
30
+ TIER = EmissionMethodTier.TIER_1.value
31
+
32
+
33
+ def run(cycle: dict): return run_fuelCombustion(cycle, term_id=TERM_ID)
@@ -0,0 +1,33 @@
1
+ from hestia_earth.schema import EmissionMethodTier
2
+
3
+ from .fuelCombustion_utils import run as run_fuelCombustion
4
+
5
+ REQUIREMENTS = {
6
+ "Cycle": {
7
+ "or": {
8
+ "inputs": [
9
+ {"@type": "Input", "value": "", "term.termType": "fuel", "optional": {
10
+ "operation": ""
11
+ }}
12
+ ],
13
+ "completeness.electricityFuel": "True"
14
+ }
15
+ }
16
+ }
17
+ RETURNS = {
18
+ "Emission": [{
19
+ "value": "",
20
+ "inputs": "",
21
+ "operation": "",
22
+ "methodTier": "tier 1"
23
+ }]
24
+ }
25
+ LOOKUPS = {
26
+ "fuel": "coToAirFuelCombustionEmepEea2019",
27
+ "operation": "coToAirFuelCombustionEmepEea2019"
28
+ }
29
+ TERM_ID = 'coToAirFuelCombustion'
30
+ TIER = EmissionMethodTier.TIER_1.value
31
+
32
+
33
+ def run(cycle: dict): return run_fuelCombustion(cycle, term_id=TERM_ID)
@@ -0,0 +1,33 @@
1
+ from hestia_earth.schema import EmissionMethodTier
2
+
3
+ from .fuelCombustion_utils import run as run_fuelCombustion
4
+
5
+ REQUIREMENTS = {
6
+ "Cycle": {
7
+ "or": {
8
+ "inputs": [
9
+ {"@type": "Input", "value": "", "term.termType": "fuel", "optional": {
10
+ "operation": ""
11
+ }}
12
+ ],
13
+ "completeness.electricityFuel": "True"
14
+ }
15
+ }
16
+ }
17
+ RETURNS = {
18
+ "Emission": [{
19
+ "value": "",
20
+ "inputs": "",
21
+ "operation": "",
22
+ "methodTier": "tier 1"
23
+ }]
24
+ }
25
+ LOOKUPS = {
26
+ "fuel": "nmvocToAirFuelCombustionEmepEea2019",
27
+ "operation": "nmvocToAirFuelCombustionEmepEea2019"
28
+ }
29
+ TERM_ID = 'nmvocToAirFuelCombustion'
30
+ TIER = EmissionMethodTier.TIER_1.value
31
+
32
+
33
+ def run(cycle: dict): return run_fuelCombustion(cycle, term_id=TERM_ID)
@@ -0,0 +1,33 @@
1
+ from hestia_earth.schema import EmissionMethodTier
2
+
3
+ from .fuelCombustion_utils import run as run_fuelCombustion
4
+
5
+ REQUIREMENTS = {
6
+ "Cycle": {
7
+ "or": {
8
+ "inputs": [
9
+ {"@type": "Input", "value": "", "term.termType": "fuel", "optional": {
10
+ "operation": ""
11
+ }}
12
+ ],
13
+ "completeness.electricityFuel": "True"
14
+ }
15
+ }
16
+ }
17
+ RETURNS = {
18
+ "Emission": [{
19
+ "value": "",
20
+ "inputs": "",
21
+ "operation": "",
22
+ "methodTier": "tier 1"
23
+ }]
24
+ }
25
+ LOOKUPS = {
26
+ "fuel": "pm10ToAirFuelCombustionEmepEea2019",
27
+ "operation": "pm10ToAirFuelCombustionEmepEea2019"
28
+ }
29
+ TERM_ID = 'pm10ToAirFuelCombustion'
30
+ TIER = EmissionMethodTier.TIER_1.value
31
+
32
+
33
+ def run(cycle: dict): return run_fuelCombustion(cycle, term_id=TERM_ID)
@@ -0,0 +1,33 @@
1
+ from hestia_earth.schema import EmissionMethodTier
2
+
3
+ from .fuelCombustion_utils import run as run_fuelCombustion
4
+
5
+ REQUIREMENTS = {
6
+ "Cycle": {
7
+ "or": {
8
+ "inputs": [
9
+ {"@type": "Input", "value": "", "term.termType": "fuel", "optional": {
10
+ "operation": ""
11
+ }}
12
+ ],
13
+ "completeness.electricityFuel": "True"
14
+ }
15
+ }
16
+ }
17
+ RETURNS = {
18
+ "Emission": [{
19
+ "value": "",
20
+ "inputs": "",
21
+ "operation": "",
22
+ "methodTier": "tier 1"
23
+ }]
24
+ }
25
+ LOOKUPS = {
26
+ "fuel": "pm25ToAirFuelCombustionEmepEea2019",
27
+ "operation": "pm25ToAirFuelCombustionEmepEea2019"
28
+ }
29
+ TERM_ID = 'pm25ToAirFuelCombustion'
30
+ TIER = EmissionMethodTier.TIER_1.value
31
+
32
+
33
+ def run(cycle: dict): return run_fuelCombustion(cycle, term_id=TERM_ID)
@@ -0,0 +1,33 @@
1
+ from hestia_earth.schema import EmissionMethodTier
2
+
3
+ from .fuelCombustion_utils import run as run_fuelCombustion
4
+
5
+ REQUIREMENTS = {
6
+ "Cycle": {
7
+ "or": {
8
+ "inputs": [
9
+ {"@type": "Input", "value": "", "term.termType": "fuel", "optional": {
10
+ "operation": ""
11
+ }}
12
+ ],
13
+ "completeness.electricityFuel": "True"
14
+ }
15
+ }
16
+ }
17
+ RETURNS = {
18
+ "Emission": [{
19
+ "value": "",
20
+ "inputs": "",
21
+ "operation": "",
22
+ "methodTier": "tier 1"
23
+ }]
24
+ }
25
+ LOOKUPS = {
26
+ "fuel": "tspToAirFuelCombustionEmepEea2019",
27
+ "operation": "tspToAirFuelCombustionEmepEea2019"
28
+ }
29
+ TERM_ID = 'tspToAirFuelCombustion'
30
+ TIER = EmissionMethodTier.TIER_1.value
31
+
32
+
33
+ def run(cycle: dict): return run_fuelCombustion(cycle, term_id=TERM_ID)
@@ -15,7 +15,7 @@ REQUIREMENTS = {
15
15
  "term.termType": "crop",
16
16
  "value": "> 0"
17
17
  }],
18
- "completeness.other": "False"
18
+ "completeness.seed": "False"
19
19
  }
20
20
  }
21
21
  LOOKUPS = {
@@ -34,17 +34,18 @@ TERM_ID = 'seed'
34
34
  def _run_product(product: dict):
35
35
  term = product.get('term', {})
36
36
  product_value = list_sum(product.get('value', []))
37
- value = safe_parse_float(
38
- get_lookup_value(term, LOOKUPS['crop'][0], model=MODEL, term=TERM_ID), default=0) * product_value
39
- sd = safe_parse_float(get_lookup_value(term, LOOKUPS['crop'][1], model=MODEL, term=TERM_ID), default=0)
40
- return value, sd
37
+ value, sd = [
38
+ safe_parse_float(get_lookup_value(term, lookup, model=MODEL, term=TERM_ID), default=0)
39
+ for lookup in LOOKUPS['crop']
40
+ ]
41
+ return value * product_value, sd
41
42
 
42
43
 
43
44
  def _run(products: list):
44
45
  values = list(map(_run_product, products))
45
46
  total_value = list_sum([value for value, _ in values])
46
47
  # TODO: we only fill-in sd for single values as the total value is complicated to calculate
47
- total_sd = values[0][1] if len(values) == 1 else 0
48
+ total_sd = values[0][1] if len(values) == 1 else None
48
49
  return [
49
50
  _new_input(term=TERM_ID, model=MODEL, value=total_value, sd=total_sd)
50
51
  ] if total_value > 0 else []
@@ -53,8 +54,8 @@ def _run(products: list):
53
54
  def _should_run_product(product: dict):
54
55
  term = product.get('term', {})
55
56
  product_value = list_sum(product.get('value', []))
56
- has_all_lookups = all([get_lookup_value(term, col, model=MODEL, term=TERM_ID) for col in LOOKUPS['crop']])
57
- return all([has_all_lookups, product_value > 0])
57
+ has_lookup = get_lookup_value(term, LOOKUPS['crop'][0], model=MODEL, term=TERM_ID)
58
+ return all([has_lookup, product_value > 0])
58
59
 
59
60
 
60
61
  def _should_run(cycle: dict):
@@ -1,7 +1,10 @@
1
- from hestia_earth.schema import MeasurementMethodClassification
1
+ from hestia_earth.schema import MeasurementMethodClassification, TermTermType
2
+ from hestia_earth.utils.model import filter_list_term_type
3
+ from hestia_earth.utils.blank_node import get_node_value
4
+ from hestia_earth.utils.tools import pick
2
5
 
3
- from hestia_earth.models.log import logRequirements, logShouldRun
4
- from hestia_earth.models.utils.measurement import _new_measurement, total_other_soilType_value
6
+ from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
7
+ from hestia_earth.models.utils.measurement import _new_measurement
5
8
  from hestia_earth.models.utils.source import get_source
6
9
  from .utils import download, has_geospatial_data, should_download
7
10
  from . import MODEL
@@ -16,10 +19,10 @@ REQUIREMENTS = {
16
19
  "none": {
17
20
  "measurements": [{
18
21
  "@type": "Measurement",
19
- "value": "100",
22
+ "value": "> 0",
20
23
  "depthUpper": "0",
21
24
  "depthLower": "30",
22
- "term.termType": "soilType"
25
+ "term.termType": ["soilType", "usdaSoilType"]
23
26
  }]
24
27
  }
25
28
  }
@@ -39,12 +42,14 @@ EE_PARAMS = {
39
42
  'reducer': 'mean'
40
43
  }
41
44
  BIBLIO_TITLE = 'Harmonized World Soil Database Version 1.2. Food and Agriculture Organization of the United Nations (FAO).' # noqa: E501
45
+ _DEPTH_UPPER = 0
46
+ _DEPTH_LOWER = 30
42
47
 
43
48
 
44
49
  def _measurement(site: dict, value: float):
45
50
  measurement = _new_measurement(term=TERM_ID, value=value)
46
- measurement['depthUpper'] = 0
47
- measurement['depthLower'] = 30
51
+ measurement['depthUpper'] = _DEPTH_UPPER
52
+ measurement['depthLower'] = _DEPTH_LOWER
48
53
  measurement['methodClassification'] = MeasurementMethodClassification.GEOSPATIAL_DATASET.value
49
54
  return measurement | get_source(site, BIBLIO_TITLE)
50
55
 
@@ -58,15 +63,30 @@ def _should_run(site: dict):
58
63
  contains_geospatial_data = has_geospatial_data(site)
59
64
  below_max_area_size = should_download(TERM_ID, site)
60
65
 
61
- total_measurements_value = total_other_soilType_value(site.get('measurements', []), TERM_ID)
66
+ measurements = filter_list_term_type(site.get('measurements', []), [
67
+ TermTermType.SOILTYPE,
68
+ TermTermType.USDASOILTYPE
69
+ ])
70
+ measurements = [m for m in measurements if all([
71
+ m.get('depthUpper', -1) == _DEPTH_UPPER,
72
+ m.get('depthLower', 0) == _DEPTH_LOWER,
73
+ get_node_value(m) > 0
74
+ ])]
75
+ has_soil_type_measurements = len(measurements) > 0
62
76
 
63
77
  logRequirements(site, model=MODEL, term=TERM_ID,
64
78
  contains_geospatial_data=contains_geospatial_data,
65
79
  below_max_area_size=below_max_area_size,
66
- total_soilType_measurements_value=total_measurements_value,
67
- total_soilType_measurements_value_is_0=total_measurements_value == 0)
80
+ has_soil_type_measurements=has_soil_type_measurements,
81
+ soil_type_measurements=log_as_table([
82
+ {
83
+ 'id': m.get('term', {}).get('@id'),
84
+ 'termType': m.get('term', {}).get('termType'),
85
+ 'value': get_node_value(m)
86
+ } | pick(m, ['depthUpper', 'depthLower']) for m in measurements
87
+ ]))
68
88
 
69
- should_run = all([contains_geospatial_data, below_max_area_size, total_measurements_value == 0])
89
+ should_run = all([contains_geospatial_data, below_max_area_size, not has_soil_type_measurements])
70
90
  logShouldRun(site, MODEL, TERM_ID, should_run)
71
91
  return should_run
72
92
 
@@ -9,8 +9,8 @@ from . import MODEL
9
9
 
10
10
  REQUIREMENTS = {
11
11
  "Cycle": {
12
- "practices": [{"@type": "Practice", "value": "", "term.termType": "cropResidue"}],
13
- "products": [{"@type": "Product", "value": "", "term.termType": "cropResidueManagement"}]
12
+ "practices": [{"@type": "Practice", "value": "", "term.termType": "cropResidueManagement"}],
13
+ "products": [{"@type": "Product", "value": "", "term.termType": "cropResidue"}]
14
14
  }
15
15
  }
16
16
  RETURNS = {
@@ -206,7 +206,7 @@ def _get_relevant_items(cycle: dict, item_name: str, term_types: List[TermTermTy
206
206
 
207
207
 
208
208
  def _input_gap_fill_term_id(input: dict):
209
- return get_lookup_value(input.get('term'), 'inputGapFillManagementTermId')
209
+ return get_lookup_value(input.get('term'), 'inputGapFillManagementTermId', skip_debug=True)
210
210
 
211
211
 
212
212
  def _input_value_valid(input: dict):
@@ -242,9 +242,10 @@ def _cycle_has_existing_non_cover_land_cover_nodes(cycle: dict) -> bool:
242
242
  # blankNodesGroup = Cover crops lookup, return True, else False
243
243
  return any([
244
244
  practice for practice in cycle.get("practices", [])
245
- if practice.get("term", {}).get("termType") == TermTermType.LANDCOVER.value
246
- and not any(prop for prop in practice.get("properties", [])
247
- if _is_cover_crop(prop.get("term", {}).get("@id")))
245
+ if practice.get("term", {}).get("termType") == TermTermType.LANDCOVER.value and not any(
246
+ prop for prop in practice.get("properties", [])
247
+ if _is_cover_crop(prop.get("term", {}).get("@id"))
248
+ )
248
249
  ])
249
250
 
250
251