hestia-earth-models 0.69.1__py3-none-any.whl → 0.70.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.
- hestia_earth/models/cache_sites.py +3 -2
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +2 -1
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +3 -2
- hestia_earth/models/config/Cycle.json +35 -1
- hestia_earth/models/{koble2014 → cycle}/aboveGroundCropResidue.py +1 -3
- hestia_earth/models/cycle/aboveGroundCropResidueTotal.py +1 -1
- hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +1 -1
- hestia_earth/models/cycle/animal/input/properties.py +1 -1
- hestia_earth/models/cycle/cycleDuration.py +2 -2
- hestia_earth/models/cycle/energyContentLowerHeatingValue.py +1 -1
- hestia_earth/models/cycle/input/hestiaAggregatedData.py +12 -14
- hestia_earth/models/cycle/input/properties.py +1 -1
- hestia_earth/models/cycle/siteDuration.py +3 -3
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +1 -1
- hestia_earth/models/geospatialDatabase/croppingIntensity.py +4 -4
- hestia_earth/models/geospatialDatabase/longFallowRatio.py +4 -4
- hestia_earth/models/geospatialDatabase/region.py +3 -2
- hestia_earth/models/geospatialDatabase/utils.py +6 -5
- hestia_earth/models/haversineFormula/transport/distance.py +5 -4
- hestia_earth/models/hestia/landCover.py +1 -5
- hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +2 -1
- hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +2 -1
- hestia_earth/models/hestia/seed_emissions.py +1 -1
- hestia_earth/models/impact_assessment/emissions.py +1 -1
- hestia_earth/models/impact_assessment/product/economicValueShare.py +1 -1
- hestia_earth/models/impact_assessment/product/value.py +1 -1
- hestia_earth/models/ipcc2019/animal/fatContent.py +2 -2
- hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +2 -2
- hestia_earth/models/ipcc2019/animal/trueProteinContent.py +2 -2
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +7 -2
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +1 -0
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +2 -1
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +2 -1
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +1 -0
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +8 -8
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py +40 -12
- hestia_earth/models/koble2014/cropResidueManagement.py +1 -1
- hestia_earth/models/koble2014/residueBurnt.py +1 -1
- hestia_earth/models/koble2014/residueRemoved.py +1 -1
- hestia_earth/models/koble2014/utils.py +3 -3
- hestia_earth/models/mocking/search-results.json +952 -910
- hestia_earth/models/pooreNemecek2018/excretaKgN.py +1 -1
- hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py +1 -1
- hestia_earth/models/pooreNemecek2018/utils.py +4 -1
- hestia_earth/models/schmidt2007/ch4ToAirWasteTreatment.py +1 -3
- hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +1 -3
- hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +1 -3
- hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +1 -3
- hestia_earth/models/site/management.py +5 -3
- hestia_earth/models/site/pre_checks/country.py +4 -2
- hestia_earth/models/transformation/input/excreta.py +1 -1
- hestia_earth/models/utils/aggregated.py +12 -15
- hestia_earth/models/utils/blank_node.py +15 -1
- hestia_earth/models/utils/product.py +1 -1
- hestia_earth/models/utils/source.py +2 -1
- hestia_earth/models/utils/term.py +26 -1
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.0.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.0.dist-info}/RECORD +75 -75
- tests/models/cycle/input/test_hestiaAggregatedData.py +18 -16
- tests/models/{koble2014 → cycle}/test_aboveGroundCropResidue.py +3 -3
- tests/models/geospatialDatabase/test_region.py +1 -1
- tests/models/geospatialDatabase/test_utils.py +1 -1
- tests/models/haversineFormula/transport/test_distance.py +2 -2
- tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +11 -0
- tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +19 -6
- tests/models/ipcc2019/test_organicCarbonPerHa.py +4 -2
- tests/models/pooreNemecek2018/test_landOccupationDuringCycle.py +3 -0
- tests/models/site/pre_checks/test_country.py +4 -3
- tests/models/test_ecoinventV3.py +2 -2
- tests/models/utils/test_source.py +15 -5
- tests/orchestrator/test_models.py +1 -0
- {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.0.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.0.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.69.1.dist-info → hestia_earth_models-0.70.0.dist-info}/top_level.txt +0 -0
@@ -31,7 +31,7 @@ from .organicCarbonPerHa_utils import (
|
|
31
31
|
)
|
32
32
|
from . import MODEL
|
33
33
|
|
34
|
-
|
34
|
+
LOOKUPS = {
|
35
35
|
"crop": "IPCC_LAND_USE_CATEGORY",
|
36
36
|
"landCover": [
|
37
37
|
"IPCC_LAND_USE_CATEGORY",
|
@@ -992,8 +992,8 @@ def _check_soil_category(
|
|
992
992
|
bool
|
993
993
|
`True` if the soil category matches, `False` otherwise.
|
994
994
|
"""
|
995
|
-
SOIL_TYPE_LOOKUP =
|
996
|
-
USDA_SOIL_TYPE_LOOKUP =
|
995
|
+
SOIL_TYPE_LOOKUP = LOOKUPS["soilType"]
|
996
|
+
USDA_SOIL_TYPE_LOOKUP = LOOKUPS["usdaSoilType"]
|
997
997
|
|
998
998
|
target_lookup_values = IPCC_SOIL_CATEGORY_TO_SOIL_TYPE_LOOKUP_VALUE.get(key, None)
|
999
999
|
|
@@ -1183,7 +1183,7 @@ def _check_ipcc_land_use_category(*, key: IpccLandUseCategory, land_cover_nodes:
|
|
1183
1183
|
bool
|
1184
1184
|
`True` if the conditions match the specified land use category, `False` otherwise.
|
1185
1185
|
"""
|
1186
|
-
LOOKUP =
|
1186
|
+
LOOKUP = LOOKUPS["landCover"][0]
|
1187
1187
|
target_lookup_values = IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE.get(key, None)
|
1188
1188
|
valid_lookup = cumulative_nodes_lookup_match(
|
1189
1189
|
land_cover_nodes,
|
@@ -1340,7 +1340,7 @@ def _check_tillage_ipcc_management_category(
|
|
1340
1340
|
bool
|
1341
1341
|
`True` if the conditions match the specified management category, `False` otherwise.
|
1342
1342
|
"""
|
1343
|
-
LOOKUP =
|
1343
|
+
LOOKUP = LOOKUPS["tillage"]
|
1344
1344
|
target_lookup_values = IPCC_MANAGEMENT_CATEGORY_TO_TILLAGE_MANAGEMENT_LOOKUP_VALUE.get(key, None)
|
1345
1345
|
return cumulative_nodes_lookup_match(
|
1346
1346
|
tillage_nodes,
|
@@ -1798,9 +1798,9 @@ def _get_carbon_input_kwargs(
|
|
1798
1798
|
The carbon input keyword arguments.
|
1799
1799
|
"""
|
1800
1800
|
|
1801
|
-
PRACTICE_INCREASING_C_INPUT_LOOKUP =
|
1802
|
-
LOW_RESIDUE_PRODUCING_CROP_LOOKUP =
|
1803
|
-
N_FIXING_CROP_LOOKUP =
|
1801
|
+
PRACTICE_INCREASING_C_INPUT_LOOKUP = LOOKUPS["landUseManagement"]
|
1802
|
+
LOW_RESIDUE_PRODUCING_CROP_LOOKUP = LOOKUPS["landCover"][1]
|
1803
|
+
N_FIXING_CROP_LOOKUP = LOOKUPS["landCover"][2]
|
1804
1804
|
|
1805
1805
|
# To prevent double counting already explicitly checked practices.
|
1806
1806
|
EXCLUDED_PRACTICE_TERM_IDS = {
|
@@ -33,7 +33,7 @@ from .organicCarbonPerHa_utils import (
|
|
33
33
|
)
|
34
34
|
from . import MODEL
|
35
35
|
|
36
|
-
|
36
|
+
LOOKUPS = {
|
37
37
|
"crop": "IPCC_LAND_USE_CATEGORY",
|
38
38
|
"landCover": "IPCC_LAND_USE_CATEGORY",
|
39
39
|
"tillage": "IPCC_TILLAGE_MANAGEMENT_CATEGORY"
|
@@ -1173,7 +1173,7 @@ def _compile_inventory(
|
|
1173
1173
|
TODO: implement long-term average climate data and annual climate data as back ups for monthly data
|
1174
1174
|
TODO: implement randomisation for `irrigationMonthly` if `startDate` and `endDate` are not provided
|
1175
1175
|
"""
|
1176
|
-
grouped_cycles = group_nodes_by_year(cycles)
|
1176
|
+
grouped_cycles = group_nodes_by_year(cycles, include_spillovers=True)
|
1177
1177
|
grouped_measurements = group_nodes_by_year(measurement_nodes, mode=GroupNodesByYearMode.DATES)
|
1178
1178
|
|
1179
1179
|
grouped_climate_data = _get_grouped_climate_measurements(grouped_measurements)
|
@@ -1322,9 +1322,23 @@ def _get_carbon_sources(cycle: dict) -> list[CarbonSource]:
|
|
1322
1322
|
A formatted list of `CarbonSource`s.
|
1323
1323
|
"""
|
1324
1324
|
inputs_and_products = cycle.get("inputs", []) + cycle.get("products", [])
|
1325
|
+
|
1326
|
+
group_fac = cycle.get('fraction_of_group_duration')
|
1327
|
+
node_fac = cycle.get('fraction_of_node_duration')
|
1328
|
+
|
1329
|
+
scaling_fac = group_fac if round(group_fac * 100) >= round(node_fac * 100) else 1
|
1330
|
+
|
1331
|
+
kwargs = {
|
1332
|
+
"cycle": cycle,
|
1333
|
+
"scaling_factor": scaling_fac
|
1334
|
+
}
|
1335
|
+
|
1325
1336
|
return non_empty_list([
|
1326
1337
|
next(
|
1327
|
-
(
|
1338
|
+
(
|
1339
|
+
_func(node, **kwargs) for validator, _func in _CARBON_SOURCE_DECISION_TREE.items()
|
1340
|
+
if validator(node)
|
1341
|
+
),
|
1328
1342
|
None
|
1329
1343
|
) for node in inputs_and_products
|
1330
1344
|
])
|
@@ -1348,7 +1362,9 @@ def _should_run_carbon_source_ag_residue(node: dict) -> bool:
|
|
1348
1362
|
return node.get("term", {}).get("@id") == _ABOVE_GROUND_CROP_RESIDUE_TOTAL_TERM_ID
|
1349
1363
|
|
1350
1364
|
|
1351
|
-
def _calc_carbon_source_ag_crop_residue(
|
1365
|
+
def _calc_carbon_source_ag_crop_residue(
|
1366
|
+
node: dict, *, cycle: dict, scaling_factor: float, **_
|
1367
|
+
) -> Union[CarbonSource, None]:
|
1352
1368
|
"""
|
1353
1369
|
Extract and format the carbon source data for above-ground crop residues.
|
1354
1370
|
|
@@ -1360,6 +1376,11 @@ def _calc_carbon_source_ag_crop_residue(node: dict, cycle: dict) -> Union[Carbon
|
|
1360
1376
|
----------
|
1361
1377
|
node : dict
|
1362
1378
|
A HESTIA [Product](https://www.hestia.earth/schema/Product) node with `term.termType` == `landCover`.
|
1379
|
+
cycle : dict
|
1380
|
+
The HESTIA [Cycle](https://www.hestia.earth/schema/Cycle) that produces the crop residue.
|
1381
|
+
scaling_factor : float
|
1382
|
+
The scaling factor for the mass of carbon input, calculated by estimating how much the cycle overlaps
|
1383
|
+
with the current inventory year.
|
1363
1384
|
|
1364
1385
|
Returns
|
1365
1386
|
-------
|
@@ -1371,7 +1392,7 @@ def _calc_carbon_source_ag_crop_residue(node: dict, cycle: dict) -> Union[Carbon
|
|
1371
1392
|
get_node_value(practice) for practice in cycle.get("practices", [])
|
1372
1393
|
if node_term_match(practice, _CROP_RESIDUE_MANAGEMENT_TERM_IDS)
|
1373
1394
|
])
|
1374
|
-
mass = value * max(residue_left_on_field, _MIN_RESIDUE_LEFT_ON_FIELD) / 100
|
1395
|
+
mass = value * max(residue_left_on_field, _MIN_RESIDUE_LEFT_ON_FIELD) * scaling_factor / 100
|
1375
1396
|
|
1376
1397
|
carbon_content, nitrogen_content, lignin_content, dry_matter = _retrieve_carbon_source_properties(node)
|
1377
1398
|
|
@@ -1400,7 +1421,7 @@ def _should_run_carbon_source_cover_crop(node: dict) -> bool:
|
|
1400
1421
|
bool
|
1401
1422
|
Whether the node satisfies the critera.
|
1402
1423
|
"""
|
1403
|
-
LOOKUP =
|
1424
|
+
LOOKUP = LOOKUPS["landCover"]
|
1404
1425
|
TARGET_LOOKUP_VALUES = IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE[IpccLandUseCategory.ANNUAL_CROPS]
|
1405
1426
|
|
1406
1427
|
return (
|
@@ -1410,7 +1431,7 @@ def _should_run_carbon_source_cover_crop(node: dict) -> bool:
|
|
1410
1431
|
)
|
1411
1432
|
|
1412
1433
|
|
1413
|
-
def _calc_carbon_source_cover_crop(node: dict,
|
1434
|
+
def _calc_carbon_source_cover_crop(node: dict, *, scaling_factor: float, **_) -> Union[CarbonSource, None]:
|
1414
1435
|
"""
|
1415
1436
|
Extract and format the carbon source data for an annual cover crop.
|
1416
1437
|
|
@@ -1420,6 +1441,9 @@ def _calc_carbon_source_cover_crop(node: dict, *_) -> Union[CarbonSource, None]:
|
|
1420
1441
|
----------
|
1421
1442
|
node : dict
|
1422
1443
|
A HESTIA [Product](https://www.hestia.earth/schema/Product) node with `term.termType` == `landCover`.
|
1444
|
+
scaling_factor : float
|
1445
|
+
The scaling factor for the mass of carbon input, calculated by estimating how much the cycle overlaps
|
1446
|
+
with the current inventory year.
|
1423
1447
|
|
1424
1448
|
Returns
|
1425
1449
|
-------
|
@@ -1428,7 +1452,7 @@ def _calc_carbon_source_cover_crop(node: dict, *_) -> Union[CarbonSource, None]:
|
|
1428
1452
|
"""
|
1429
1453
|
value = get_node_value(node)
|
1430
1454
|
carbon_source = CarbonSource(
|
1431
|
-
_DEFAULT_COVER_CROP_BIOMASS * value / 100,
|
1455
|
+
_DEFAULT_COVER_CROP_BIOMASS * value * scaling_factor / 100,
|
1432
1456
|
_Parameter.DEFAULT_CARBON_CONTENT.value.get("value"),
|
1433
1457
|
_Parameter.DEFAULT_NITROGEN_CONTENT.value.get("value"),
|
1434
1458
|
_Parameter.DEFAULT_NITROGEN_CONTENT.value.get("value")
|
@@ -1457,7 +1481,7 @@ def _should_run_carbon_source(node: dict) -> bool:
|
|
1457
1481
|
])
|
1458
1482
|
|
1459
1483
|
|
1460
|
-
def _calc_carbon_source(node: dict,
|
1484
|
+
def _calc_carbon_source(node: dict, *, scaling_factor: float, **_) -> Union[CarbonSource, None]:
|
1461
1485
|
"""
|
1462
1486
|
Extract and format the carbon source data for an input or product.
|
1463
1487
|
|
@@ -1466,13 +1490,17 @@ def _calc_carbon_source(node: dict, *_) -> Union[CarbonSource, None]:
|
|
1466
1490
|
node : dict
|
1467
1491
|
A HESTIA [Input](https://www.hestia.earth/schema/Input) or [Product](https://www.hestia.earth/schema/Product)
|
1468
1492
|
node.
|
1493
|
+
scaling_factor : float
|
1494
|
+
The scaling factor for the mass of carbon input, calculated by estimating how much the cycle overlaps
|
1495
|
+
with the current inventory year.
|
1496
|
+
|
1469
1497
|
|
1470
1498
|
Returns
|
1471
1499
|
-------
|
1472
1500
|
CarbonSource | None
|
1473
1501
|
The carbon source data of the cover crop, or `None` if carbon source data incomplete.
|
1474
1502
|
"""
|
1475
|
-
mass = get_node_value(node)
|
1503
|
+
mass = get_node_value(node) * scaling_factor
|
1476
1504
|
carbon_content, nitrogen_content, lignin_content, dry_matter = _retrieve_carbon_source_properties(node)
|
1477
1505
|
|
1478
1506
|
carbon_source = CarbonSource(
|
@@ -1673,7 +1701,7 @@ def _check_cycle_tillage_management_category(
|
|
1673
1701
|
bool
|
1674
1702
|
Whether or not the cycle meets the requirements for the category.
|
1675
1703
|
"""
|
1676
|
-
LOOKUP =
|
1704
|
+
LOOKUP = LOOKUPS["tillage"]
|
1677
1705
|
target_lookup_values = IPCC_MANAGEMENT_CATEGORY_TO_TILLAGE_MANAGEMENT_LOOKUP_VALUE.get(key, None)
|
1678
1706
|
|
1679
1707
|
practices = cycle.get("practices", [])
|
@@ -1720,7 +1748,7 @@ def _get_grouped_is_paddy_rice(grouped_cycles: dict) -> dict:
|
|
1720
1748
|
|
1721
1749
|
|
1722
1750
|
def _check_is_paddy_rice(cycles: list[dict]) -> bool:
|
1723
|
-
LOOKUP =
|
1751
|
+
LOOKUP = LOOKUPS["crop"]
|
1724
1752
|
TARGET_LOOKUP_VALUES = IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE.get(
|
1725
1753
|
IpccLandUseCategory.PADDY_RICE_CULTIVATION, None
|
1726
1754
|
)
|
@@ -39,7 +39,7 @@ def _run_practice(cycle: dict, ratio: float, practice: dict):
|
|
39
39
|
rescale_ratio=ratio,
|
40
40
|
value_before_rescale=value)
|
41
41
|
logShouldRun(cycle, MODEL, term.get('@id'), True)
|
42
|
-
return _practice(term, round(value * ratio,
|
42
|
+
return _practice(term, round(value * ratio, 7))
|
43
43
|
|
44
44
|
|
45
45
|
def _run(cycle: dict):
|
@@ -45,7 +45,7 @@ def _get_default_percent(cycle: dict, term: dict, country_id: str):
|
|
45
45
|
def _run(cycle: dict, remaining_value: float, primary_product: dict, country_id: str):
|
46
46
|
term = primary_product.get('term', {})
|
47
47
|
value = _get_default_percent(cycle, term, country_id)
|
48
|
-
return [] if value is None else [_practice(TERM_ID, min(round(value * 100,
|
48
|
+
return [] if value is None else [_practice(TERM_ID, min(round(value * 100, 7), remaining_value))]
|
49
49
|
|
50
50
|
|
51
51
|
def run(cycle: dict):
|
@@ -43,7 +43,7 @@ def _get_default_percent(cycle: dict, term: dict, country_id: str):
|
|
43
43
|
def _run(cycle: dict, remaining_value: float, primary_product: dict, country_id: str):
|
44
44
|
term = primary_product.get('term', {})
|
45
45
|
value = _get_default_percent(cycle, term, country_id)
|
46
|
-
return [] if value is None else [_practice(TERM_ID, min(round(value * 100,
|
46
|
+
return [] if value is None else [_practice(TERM_ID, min(round(value * 100, 7), remaining_value))]
|
47
47
|
|
48
48
|
|
49
49
|
def run(cycle: dict):
|
@@ -43,7 +43,7 @@ def _should_run(term_id: str, cycle: dict, require_country: bool = False):
|
|
43
43
|
not is_from_model(p)
|
44
44
|
])
|
45
45
|
]
|
46
|
-
|
46
|
+
no_provided_cropResidue_products = len(provided_cropResidue_products) == 0
|
47
47
|
|
48
48
|
country_id = cycle.get('site', {}).get('country', {}).get('@id')
|
49
49
|
|
@@ -53,13 +53,13 @@ def _should_run(term_id: str, cycle: dict, require_country: bool = False):
|
|
53
53
|
has_remaining_value=has_remaining_value,
|
54
54
|
crop_residue_values=residue_values,
|
55
55
|
country_id=country_id,
|
56
|
-
|
56
|
+
no_provided_cropResidue_products=no_provided_cropResidue_products,
|
57
57
|
provided_cropResidue_product_ids=log_blank_nodes_id(provided_cropResidue_products))
|
58
58
|
|
59
59
|
should_run = all([
|
60
60
|
has_primary_product, crop_residue_incomplete, has_remaining_value,
|
61
61
|
not require_country or country_id,
|
62
|
-
|
62
|
+
no_provided_cropResidue_products
|
63
63
|
])
|
64
64
|
logShouldRun(cycle, MODEL, term_id, should_run)
|
65
65
|
return should_run, remaining_value, primary_product, country_id
|