hestia-earth-models 0.74.3__py3-none-any.whl → 0.74.5__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/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +0 -1
- hestia_earth/models/config/Cycle.json +15 -0
- hestia_earth/models/config/ImpactAssessment.json +30 -11
- hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +3 -3
- hestia_earth/models/cycle/completeness/seed.py +1 -1
- hestia_earth/models/cycle/input/hestiaAggregatedData.py +25 -16
- hestia_earth/models/data/hestiaAggregatedData/__init__.py +73 -0
- hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +1 -1
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +5 -6
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +10 -13
- hestia_earth/models/fantkeEtAl2016/damageToHumanHealthParticulateMatterFormation.py +1 -1
- hestia_earth/models/hestia/landCover.py +24 -0
- hestia_earth/models/hestia/landOccupationDuringCycle.py +80 -51
- hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +7 -1
- hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +7 -1
- hestia_earth/models/hestia/resourceUse_utils.py +58 -119
- hestia_earth/models/hestia/waterSalinity.py +57 -12
- hestia_earth/models/impact_assessment/post_checks/__init__.py +3 -2
- hestia_earth/models/impact_assessment/post_checks/remove_cache_fields.py +9 -0
- hestia_earth/models/impact_assessment/pre_checks/cache_emissionsResourceUse.py +21 -0
- hestia_earth/models/impact_assessment/pre_checks/cycle.py +5 -0
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +6 -64
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +9 -87
- hestia_earth/models/ipcc2019/co2ToAirBiocharStockChange.py +140 -0
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +329 -217
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +10 -87
- hestia_earth/models/mocking/__init__.py +2 -2
- hestia_earth/models/mocking/mock_search.py +20 -10
- hestia_earth/models/mocking/search-results.json +1 -7679
- hestia_earth/models/pooreNemecek2018/landOccupationDuringCycle.py +8 -7
- hestia_earth/models/poschEtAl2008/terrestrialAcidificationPotentialAccumulatedExceedance.py +1 -1
- hestia_earth/models/poschEtAl2008/terrestrialEutrophicationPotentialAccumulatedExceedance.py +1 -1
- hestia_earth/models/preload_requests.py +18 -4
- hestia_earth/models/schmidt2007/utils.py +3 -3
- hestia_earth/models/utils/__init__.py +4 -1
- hestia_earth/models/utils/aggregated.py +21 -68
- hestia_earth/models/utils/cycle.py +3 -3
- hestia_earth/models/utils/impact_assessment.py +45 -41
- hestia_earth/models/utils/lookup.py +92 -67
- hestia_earth/models/version.py +1 -1
- hestia_earth/orchestrator/models/__init__.py +47 -10
- hestia_earth/orchestrator/models/transformations.py +3 -1
- hestia_earth/orchestrator/strategies/merge/__init__.py +1 -2
- hestia_earth/orchestrator/strategies/merge/merge_list.py +31 -8
- hestia_earth/orchestrator/utils.py +29 -0
- {hestia_earth_models-0.74.3.dist-info → hestia_earth_models-0.74.5.dist-info}/METADATA +2 -3
- {hestia_earth_models-0.74.3.dist-info → hestia_earth_models-0.74.5.dist-info}/RECORD +62 -55
- tests/models/cycle/animal/input/test_hestiaAggregatedData.py +3 -3
- tests/models/cycle/input/test_hestiaAggregatedData.py +9 -18
- tests/models/data/__init__.py +0 -0
- tests/models/data/test_hestiaAggregatedData.py +32 -0
- tests/models/hestia/test_landCover.py +32 -1
- tests/models/hestia/test_waterSalinity.py +16 -4
- tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +1 -6
- tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +1 -6
- tests/models/ipcc2019/test_co2ToAirBiocharStockChange.py +90 -0
- tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +1 -6
- tests/models/pooreNemecek2018/test_landOccupationDuringCycle.py +1 -0
- tests/orchestrator/strategies/merge/test_merge_list.py +5 -0
- {hestia_earth_models-0.74.3.dist-info → hestia_earth_models-0.74.5.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.74.3.dist-info → hestia_earth_models-0.74.5.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.74.3.dist-info → hestia_earth_models-0.74.5.dist-info}/top_level.txt +0 -0
|
@@ -11,7 +11,7 @@ from numpy.typing import NDArray
|
|
|
11
11
|
from pydash.objects import merge
|
|
12
12
|
from typing import Any, Callable, NamedTuple, Optional, Union
|
|
13
13
|
from hestia_earth.schema import (
|
|
14
|
-
EmissionMethodTier, EmissionStatsDefinition, MeasurementMethodClassification
|
|
14
|
+
CycleFunctionalUnit, EmissionMethodTier, EmissionStatsDefinition, MeasurementMethodClassification, SiteSiteType
|
|
15
15
|
)
|
|
16
16
|
from hestia_earth.utils.date import diff_in_days, YEAR
|
|
17
17
|
from hestia_earth.utils.tools import flatten, non_empty_list, safe_parse_date
|
|
@@ -21,8 +21,8 @@ from hestia_earth.utils.descriptive_stats import calc_descriptive_stats
|
|
|
21
21
|
from hestia_earth.models.log import log_as_table
|
|
22
22
|
from hestia_earth.models.utils import pairwise
|
|
23
23
|
from hestia_earth.models.utils.blank_node import (
|
|
24
|
-
_gapfill_datestr, _get_datestr_format, DatestrGapfillMode, DatestrFormat,
|
|
25
|
-
split_node_by_dates
|
|
24
|
+
_gapfill_datestr, _get_datestr_format, cumulative_nodes_term_match, DatestrGapfillMode, DatestrFormat,
|
|
25
|
+
group_nodes_by_year, node_term_match, split_node_by_dates
|
|
26
26
|
)
|
|
27
27
|
from hestia_earth.models.utils.constant import Units, get_atomic_conversion
|
|
28
28
|
from hestia_earth.models.utils.emission import min_emission_method_tier
|
|
@@ -47,7 +47,7 @@ Carbon stock measurements without an associated `sd` should be assigned a nomina
|
|
|
47
47
|
the mean).
|
|
48
48
|
"""
|
|
49
49
|
_TRANSITION_PERIOD_YEARS = 20
|
|
50
|
-
_TRANSITION_PERIOD_DAYS =
|
|
50
|
+
_TRANSITION_PERIOD_DAYS = _TRANSITION_PERIOD_YEARS * YEAR # 20 years in days
|
|
51
51
|
_VALID_DATE_FORMATS = {
|
|
52
52
|
DatestrFormat.YEAR,
|
|
53
53
|
DatestrFormat.YEAR_MONTH,
|
|
@@ -81,6 +81,14 @@ Any `MeasurementMethodClassification` not in the mapping should be assigned `DEF
|
|
|
81
81
|
"""
|
|
82
82
|
|
|
83
83
|
|
|
84
|
+
_SITE_TYPE_SYSTEMS_MAPPING = {
|
|
85
|
+
SiteSiteType.GLASS_OR_HIGH_ACCESSIBLE_COVER.value: [
|
|
86
|
+
"protectedCroppingSystemSoilBased",
|
|
87
|
+
"protectedCroppingSystemSoilAndSubstrateBased"
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
84
92
|
class _InventoryKey(Enum):
|
|
85
93
|
"""
|
|
86
94
|
The inner keys of the annualised inventory created by the `_compile_inventory` function.
|
|
@@ -329,70 +337,87 @@ def _add_carbon_stock_change_emissions(
|
|
|
329
337
|
|
|
330
338
|
|
|
331
339
|
def create_should_run_function(
|
|
332
|
-
*,
|
|
333
340
|
carbon_stock_term_id: str,
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
341
|
+
*,
|
|
342
|
+
depth_upper: Optional[float] = None,
|
|
343
|
+
depth_lower: Optional[float] = None,
|
|
344
|
+
measurements_mandatory: bool = True,
|
|
345
|
+
measurement_method_ranking: list[MeasurementMethodClassification] = DEFAULT_MEASUREMENT_METHOD_RANKING,
|
|
346
|
+
transition_period: float = _TRANSITION_PERIOD_DAYS,
|
|
347
|
+
get_valid_management_nodes_func: Callable[[dict], list[dict]] = lambda *_: [],
|
|
348
|
+
summarise_land_use_func: Callable[[list[dict]], Any] = lambda *_: None,
|
|
349
|
+
detect_land_use_change_func: Callable[[Any, Any], bool] = lambda *_: False
|
|
340
350
|
) -> Callable[[dict], tuple[bool, str, dict, dict]]:
|
|
341
351
|
"""
|
|
342
|
-
Create a
|
|
352
|
+
Create a `should_run` function for a carbon stock change model.
|
|
343
353
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
354
|
+
This higher-order function constructs a custom decision function that determines:
|
|
355
|
+
1. Whether a given cycle has sufficient valid carbon stock measurements and land use information
|
|
356
|
+
to compile an inventory.
|
|
357
|
+
2. Which measurements are included in the inventory based on depth, method ranking, and other criteria.
|
|
347
358
|
|
|
348
359
|
Parameters
|
|
349
360
|
----------
|
|
350
361
|
carbon_stock_term_id : str
|
|
351
362
|
The `term.@id` of the carbon stock measurement (e.g., `aboveGroundBiomass`, `belowGroundBiomass`,
|
|
352
|
-
`organicCarbonPerHa
|
|
363
|
+
`organicCarbonPerHa`).
|
|
353
364
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
determine whether there is enough site and cycles data available to compile the carbon stock change inventory.
|
|
365
|
+
depth_upper : float, optional
|
|
366
|
+
The upper bound of the measurement depth (e.g., 0 cm). If provided, only measurements matching this bound are
|
|
367
|
+
included.
|
|
358
368
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
369
|
+
depth_lower : float, optional
|
|
370
|
+
The lower bound of the measurement depth (e.g., 30 cm). If provided, only measurements matching this bound are
|
|
371
|
+
included.
|
|
362
372
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
with other summaries to determine whether land use change events have occured.
|
|
367
|
-
|
|
368
|
-
detect_land_use_change_func: Callable[[Any, Any], bool]
|
|
369
|
-
A function with the signature `(summary_a: Any, summary_b: Any) -> bool`, to determine whether a land use
|
|
370
|
-
change event has occured.
|
|
371
|
-
|
|
372
|
-
should_run_measurement_func : Callable[[dict], bool], optional.
|
|
373
|
-
An optional measurement validation function, with the signature `(measurement: dict) -> bool`, that can be used
|
|
374
|
-
to add in additional criteria (`depthUpper`, `depthLower`, etc.) for the inclusion of a measurement in the
|
|
375
|
-
inventory.
|
|
373
|
+
measurements_mandatory : bool, default=True
|
|
374
|
+
If `True`, at least two valid measurement must be present for the cycle to be included in the inventory. If
|
|
375
|
+
`False`, the function may allow an inventory to be generated without direct measurements.
|
|
376
376
|
|
|
377
377
|
measurement_method_ranking : list[MeasurementMethodClassification], optional
|
|
378
|
-
The order
|
|
379
|
-
single method per year. Defaults to:
|
|
378
|
+
The priority order for selecting among multiple measurement methods. Defaults to:
|
|
380
379
|
```
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
380
|
+
[
|
|
381
|
+
MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT,
|
|
382
|
+
MeasurementMethodClassification.MODELLED_USING_OTHER_MEASUREMENTS,
|
|
383
|
+
MeasurementMethodClassification.TIER_3_MODEL,
|
|
384
|
+
MeasurementMethodClassification.TIER_2_MODEL,
|
|
385
|
+
MeasurementMethodClassification.TIER_1_MODEL,
|
|
386
|
+
]
|
|
386
387
|
```
|
|
387
|
-
|
|
388
|
+
Measurements using methods not in this ranking are excluded.
|
|
389
|
+
|
|
390
|
+
transition_period : float, default=_TRANSITION_PERIOD_DAYS
|
|
391
|
+
The transition period (in days) over which management changes are assumed to take effect. Used to generate a
|
|
392
|
+
correlation matrix for multivariate sampling of carbon stock values.
|
|
393
|
+
|
|
394
|
+
get_valid_management_nodes_func : Callable[[dict], list[dict]], optional
|
|
395
|
+
Function with signature `(site: dict) -> list[dict]`.
|
|
396
|
+
|
|
397
|
+
Extracts valid management nodes from the site for building the land use inventory.
|
|
398
|
+
|
|
399
|
+
summarise_land_use_func : Callable[[list[dict]], Any], optional
|
|
400
|
+
Function with signature `(nodes: list[dict]) -> Any`.
|
|
401
|
+
|
|
402
|
+
Summarises a list of `landCover` [Management](https://www.hestia.earth/schema/Management) nodes into a
|
|
403
|
+
comparable representation for detecting land use changes.
|
|
404
|
+
|
|
405
|
+
detect_land_use_change_func : Callable[[Any, Any], bool], optional
|
|
406
|
+
Function with signature `(summary_a: Any, summary_b: Any) -> bool`.
|
|
407
|
+
|
|
408
|
+
Detects whether a land use change event has occurred between two summaries.
|
|
388
409
|
|
|
389
410
|
Returns
|
|
390
411
|
-------
|
|
391
|
-
Callable[[dict], tuple[bool, str, dict, dict]]
|
|
392
|
-
|
|
393
|
-
`(cycle: dict) -> (
|
|
412
|
+
should_run_func : Callable[[dict], tuple[bool, str, dict, dict]]
|
|
413
|
+
A function with the signature:
|
|
414
|
+
`(cycle: dict) -> (should_run: bool, cycle_id: str, inventory: dict, logs: dict)`
|
|
415
|
+
|
|
416
|
+
- `should_run` : Whether the model should run for the cycle.
|
|
417
|
+
- `cycle_id` : Identifier of the cycle.
|
|
418
|
+
- `inventory` : The constructed carbon stock inventory for the cycle.
|
|
419
|
+
- `logs` : Diagnostic logs describing validation and filtering decisions.
|
|
394
420
|
"""
|
|
395
|
-
|
|
396
421
|
def should_run(cycle: dict) -> tuple[bool, str, dict, dict]:
|
|
397
422
|
"""
|
|
398
423
|
Determine if calculations should run for a given [Cycle](https://www.hestia.earth/schema/Cycle) based on
|
|
@@ -410,21 +435,24 @@ def create_should_run_function(
|
|
|
410
435
|
`(should_run, cycle_id, inventory, logs)`
|
|
411
436
|
"""
|
|
412
437
|
cycle_id = cycle.get("@id")
|
|
413
|
-
cycle_start_date = cycle.get("startDate")
|
|
414
|
-
cycle_end_date = cycle.get("endDate")
|
|
415
438
|
|
|
416
|
-
site =
|
|
439
|
+
site = cycle.get("site", {})
|
|
440
|
+
site_type = site.get("siteType")
|
|
441
|
+
|
|
417
442
|
cycles = related_cycles(site, cycles_mapping={cycle_id: cycle})
|
|
418
443
|
|
|
419
444
|
carbon_stock_measurements = [
|
|
420
445
|
node for node in site.get("measurements", [])
|
|
421
|
-
if
|
|
422
|
-
node_term_match(node, carbon_stock_term_id)
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
446
|
+
if (
|
|
447
|
+
node_term_match(node, carbon_stock_term_id)
|
|
448
|
+
and all([
|
|
449
|
+
_has_valid_array_fields(node),
|
|
450
|
+
_has_valid_dates(node),
|
|
451
|
+
node.get("methodClassification") in (m.value for m in measurement_method_ranking),
|
|
452
|
+
depth_upper is None or node.get("depthUpper") == depth_upper,
|
|
453
|
+
depth_lower is None or node.get("depthLower") == depth_lower
|
|
454
|
+
])
|
|
455
|
+
)
|
|
428
456
|
]
|
|
429
457
|
|
|
430
458
|
land_cover_nodes = get_valid_management_nodes_func(site)
|
|
@@ -432,16 +460,27 @@ def create_should_run_function(
|
|
|
432
460
|
seed = gen_seed(site, MODEL, carbon_stock_term_id) # All cycles linked to the same site should be consistent
|
|
433
461
|
rng = random.default_rng(seed)
|
|
434
462
|
|
|
435
|
-
|
|
436
|
-
|
|
463
|
+
has_soil = is_soil_based_system(cycles, site_type)
|
|
464
|
+
has_cycles = len(cycles) > 0
|
|
465
|
+
has_functional_unit_1_ha = all(
|
|
466
|
+
cycle.get('functionalUnit') == CycleFunctionalUnit._1_HA.value for cycle in cycles
|
|
467
|
+
)
|
|
468
|
+
has_stock_measurements = bool(carbon_stock_measurements)
|
|
469
|
+
|
|
470
|
+
should_compile_inventory = (
|
|
471
|
+
has_soil
|
|
472
|
+
and has_cycles
|
|
473
|
+
and has_functional_unit_1_ha
|
|
474
|
+
and (has_stock_measurements or not measurements_mandatory)
|
|
437
475
|
)
|
|
438
476
|
|
|
439
477
|
compile_inventory_func = _create_compile_inventory_function(
|
|
478
|
+
transition_period=transition_period,
|
|
479
|
+
seed=rng,
|
|
480
|
+
iterations=_ITERATIONS,
|
|
481
|
+
measurement_method_ranking=measurement_method_ranking,
|
|
440
482
|
summarise_land_use_func=summarise_land_use_func,
|
|
441
483
|
detect_land_use_change_func=detect_land_use_change_func,
|
|
442
|
-
iterations=_ITERATIONS,
|
|
443
|
-
seed=rng,
|
|
444
|
-
measurement_method_ranking=measurement_method_ranking
|
|
445
484
|
)
|
|
446
485
|
|
|
447
486
|
inventory, inventory_logs = (
|
|
@@ -457,21 +496,20 @@ def create_should_run_function(
|
|
|
457
496
|
|
|
458
497
|
should_run_ = all([has_valid_inventory, has_consecutive_years])
|
|
459
498
|
|
|
460
|
-
|
|
461
|
-
"
|
|
462
|
-
"cycle_start_date": cycle_start_date,
|
|
463
|
-
"cycle_end_date": cycle_end_date,
|
|
464
|
-
"inventory": inventory
|
|
465
|
-
}
|
|
466
|
-
|
|
467
|
-
logs = should_compile_logs | inventory_logs | {
|
|
499
|
+
logs = inventory_logs | {
|
|
500
|
+
"carbon_stock_term": carbon_stock_term_id,
|
|
468
501
|
"seed": seed,
|
|
502
|
+
"site_type": site_type,
|
|
503
|
+
"has_soil": has_soil,
|
|
504
|
+
"has_cycles": has_cycles,
|
|
505
|
+
"has_functional_unit_1_ha": has_functional_unit_1_ha,
|
|
469
506
|
"has_valid_inventory": has_valid_inventory,
|
|
470
507
|
"has_consecutive_years": has_consecutive_years,
|
|
471
|
-
"has_stock_measurements":
|
|
508
|
+
"has_stock_measurements": has_stock_measurements,
|
|
509
|
+
"measurements_mandatory": measurements_mandatory
|
|
472
510
|
}
|
|
473
511
|
|
|
474
|
-
return should_run_,
|
|
512
|
+
return should_run_, cycle_id, inventory, logs
|
|
475
513
|
|
|
476
514
|
return should_run
|
|
477
515
|
|
|
@@ -493,69 +531,62 @@ def _has_valid_dates(node: dict) -> bool:
|
|
|
493
531
|
return all(_get_datestr_format(datestr) in _VALID_DATE_FORMATS for datestr in node.get("dates", []))
|
|
494
532
|
|
|
495
533
|
|
|
496
|
-
def _get_site(cycle: dict) -> dict:
|
|
497
|
-
"""
|
|
498
|
-
Get the [Site](https://www.hestia.earth/schema/Site) data from a [Cycle](https://www.hestia.earth/schema/Cycle).
|
|
499
|
-
|
|
500
|
-
Parameters
|
|
501
|
-
----------
|
|
502
|
-
cycle : dict
|
|
503
|
-
|
|
504
|
-
Returns
|
|
505
|
-
-------
|
|
506
|
-
str
|
|
507
|
-
"""
|
|
508
|
-
return cycle.get("site", {})
|
|
509
|
-
|
|
510
|
-
|
|
511
534
|
def _create_compile_inventory_function(
|
|
512
535
|
*,
|
|
513
|
-
|
|
514
|
-
detect_land_use_change_func: Callable[[Any, Any], bool],
|
|
515
|
-
iterations: int = 10000,
|
|
536
|
+
transition_period: float,
|
|
516
537
|
seed: Union[int, random.Generator, None] = None,
|
|
517
|
-
|
|
538
|
+
iterations: int = 10000,
|
|
539
|
+
measurement_method_ranking: list[MeasurementMethodClassification] = DEFAULT_MEASUREMENT_METHOD_RANKING,
|
|
540
|
+
summarise_land_use_func: Callable[[list[dict]], Any],
|
|
541
|
+
detect_land_use_change_func: Callable[[Any, Any], bool]
|
|
518
542
|
) -> Callable:
|
|
519
543
|
"""
|
|
520
|
-
Create a
|
|
544
|
+
Create a `compile_inventory` function for a carbon stock change model.
|
|
521
545
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
546
|
+
This higher-order function produces a callable that generates annual inventories of carbon stock, carbon stock
|
|
547
|
+
change, emissions, and land-use-related events. It combines data from cycles, measurements, and land cover to build
|
|
548
|
+
a unified inventory.
|
|
525
549
|
|
|
526
550
|
Parameters
|
|
527
551
|
----------
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
with other summaries to determine whether land use change events have occured.
|
|
532
|
-
|
|
533
|
-
detect_land_use_change_func: Callable[[Any, Any], bool]
|
|
534
|
-
A function with the signature `(summary_a: Any, summary_b: Any) -> bool`, to determine whether a land use
|
|
535
|
-
change event has occured.
|
|
536
|
-
|
|
537
|
-
iterations : int, optional
|
|
538
|
-
The number of iterations for stochastic processing (default is 10,000).
|
|
552
|
+
transition_period : float, default=_TRANSITION_PERIOD_DAYS
|
|
553
|
+
The transition period (in days) over which management changes are assumed to take effect. Used to generate a
|
|
554
|
+
correlation matrix for multivariate sampling of carbon stock values.
|
|
539
555
|
|
|
540
556
|
seed : int, random.Generator, or None, optional
|
|
541
|
-
Seed for random number generation to ensure reproducibility.
|
|
557
|
+
Seed for random number generation to ensure reproducibility.
|
|
558
|
+
|
|
559
|
+
iterations : int, optional, default=`10000`
|
|
560
|
+
The number of iterations for the Monte Carlo simualation.
|
|
542
561
|
|
|
543
562
|
measurement_method_ranking : list[MeasurementMethodClassification], optional
|
|
544
|
-
The order
|
|
545
|
-
single method per year. Defaults to:
|
|
563
|
+
The priority order for selecting among multiple measurement methods. Defaults to:
|
|
546
564
|
```
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
565
|
+
[
|
|
566
|
+
MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT,
|
|
567
|
+
MeasurementMethodClassification.MODELLED_USING_OTHER_MEASUREMENTS,
|
|
568
|
+
MeasurementMethodClassification.TIER_3_MODEL,
|
|
569
|
+
MeasurementMethodClassification.TIER_2_MODEL,
|
|
570
|
+
MeasurementMethodClassification.TIER_1_MODEL,
|
|
571
|
+
]
|
|
552
572
|
```
|
|
553
|
-
|
|
573
|
+
Measurements using methods not in this ranking are excluded.
|
|
574
|
+
|
|
575
|
+
summarise_land_use_func : Callable[[list[dict]], Any], optional
|
|
576
|
+
Function with signature `(nodes: list[dict]) -> Any`.
|
|
577
|
+
|
|
578
|
+
Summarises a list of `landCover` [Management](https://www.hestia.earth/schema/Management) nodes into a
|
|
579
|
+
comparable representation for detecting land use changes.
|
|
580
|
+
|
|
581
|
+
detect_land_use_change_func : Callable[[Any, Any], bool], optional
|
|
582
|
+
Function with signature `(summary_a: Any, summary_b: Any) -> bool`.
|
|
583
|
+
|
|
584
|
+
Detects whether a land use change event has occurred between two summaries.
|
|
554
585
|
|
|
555
586
|
Returns
|
|
556
587
|
----------
|
|
557
|
-
Callable
|
|
558
|
-
|
|
588
|
+
compile_inventory : Callable[[list[dict], list[dict], list[dict]], tuple[dict, dict]]
|
|
589
|
+
A function that compiles an annual inventory given cycles, carbon stock measurements, and land cover nodes.
|
|
559
590
|
"""
|
|
560
591
|
def compile_inventory(
|
|
561
592
|
cycles: list[dict],
|
|
@@ -563,52 +594,60 @@ def _create_compile_inventory_function(
|
|
|
563
594
|
land_cover_nodes: list[dict]
|
|
564
595
|
) -> tuple[dict, dict]:
|
|
565
596
|
"""
|
|
566
|
-
Compile an annual inventory of carbon stocks, changes
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
_InventoryKey.SHARE_OF_EMISSION: {
|
|
581
|
-
cycle_id (str): value (float),
|
|
582
|
-
...cycle_ids
|
|
583
|
-
},
|
|
584
|
-
_InventoryKey.YEARS_SINCE_LUC_EVENT: value (int)
|
|
585
|
-
},
|
|
586
|
-
...years
|
|
587
|
-
}
|
|
597
|
+
Compile an annual inventory of carbon stocks, stock changes, emissions, and land
|
|
598
|
+
use events.
|
|
599
|
+
|
|
600
|
+
The function integrates data from cycles, carbon stock measurements, and land cover management nodes. For each
|
|
601
|
+
year, the inventory includes:
|
|
602
|
+
- carbon stock values,
|
|
603
|
+
- carbon stock changes,
|
|
604
|
+
- CO₂ emissions,
|
|
605
|
+
- attribution of emissions to cycles,
|
|
606
|
+
- and time since land use change (LUC) events.
|
|
607
|
+
|
|
608
|
+
A separate inventory is compiled for each valid measurement method present in the data. The best available
|
|
609
|
+
method per year (according to `measurement_method_ranking`) is chosen, and inventories are merged into the
|
|
610
|
+
final result.
|
|
588
611
|
```
|
|
589
612
|
|
|
590
613
|
Parameters
|
|
591
614
|
----------
|
|
592
|
-
cycle_id : str
|
|
593
|
-
The unique identifier of the cycle being processed.
|
|
594
615
|
cycles : list[dict]
|
|
595
616
|
A list of [Cycle](https://www.hestia.earth/schema/Cycles) nodes related to the site.
|
|
617
|
+
|
|
596
618
|
carbon_stock_measurements : list[dict]
|
|
597
619
|
A list of [Measurement](https://www.hestia.earth/schema/Measurement) nodes, representing carbon stock
|
|
598
620
|
measurements across time and methods.
|
|
621
|
+
|
|
599
622
|
land_cover_nodes : list[dict]
|
|
600
|
-
A list of `landCover
|
|
623
|
+
A list of `landCover` [Management](https://www.hestia.earth/schema/Management) nodes, representing the
|
|
601
624
|
site's land cover over time.
|
|
602
625
|
|
|
603
626
|
|
|
604
627
|
Returns
|
|
605
628
|
-------
|
|
606
|
-
|
|
607
|
-
|
|
629
|
+
inventory : dict
|
|
630
|
+
Annual inventory of carbon stock, carbon stock change, emissions, and land use
|
|
631
|
+
change information. Structure:
|
|
632
|
+
```
|
|
633
|
+
{
|
|
634
|
+
year (int): {
|
|
635
|
+
_InventoryKey.CARBON_STOCK: CarbonStock,
|
|
636
|
+
_InventoryKey.CARBON_STOCK_CHANGE: CarbonStockChange,
|
|
637
|
+
_InventoryKey.CO2_EMISSION: CarbonStockChangeEmission,
|
|
638
|
+
_InventoryKey.SHARE_OF_EMISSION: {cycle_id (str): float, ...},
|
|
639
|
+
_InventoryKey.YEARS_SINCE_LUC_EVENT: int
|
|
640
|
+
},
|
|
641
|
+
...years
|
|
642
|
+
}
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
logs : dict
|
|
646
|
+
Diagnostic logs describing intermediate steps and validation decisions.
|
|
608
647
|
"""
|
|
609
648
|
cycle_inventory = _compile_cycle_inventory(cycles)
|
|
610
649
|
carbon_stock_inventory = _compile_carbon_stock_inventory(
|
|
611
|
-
carbon_stock_measurements, iterations=iterations, seed=seed
|
|
650
|
+
carbon_stock_measurements, transition_period=transition_period, iterations=iterations, seed=seed
|
|
612
651
|
)
|
|
613
652
|
land_use_inventory = _compile_land_use_inventory(
|
|
614
653
|
land_cover_nodes, summarise_land_use_func, detect_land_use_change_func
|
|
@@ -630,20 +669,19 @@ def _create_compile_inventory_function(
|
|
|
630
669
|
|
|
631
670
|
def _compile_cycle_inventory(cycles: list[dict]) -> dict:
|
|
632
671
|
"""
|
|
633
|
-
|
|
634
|
-
of an inventory year.
|
|
672
|
+
Compile the share of emissions for each cycle, grouped by inventory year.
|
|
635
673
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
674
|
+
Each cycle is assumed to occupy a fraction of its group's duration (given by the `"fraction_of_group_duration"`
|
|
675
|
+
key). For each year, this function normalizes those fractions so that the shares of emissions across all cycles in
|
|
676
|
+
that year sum to 1.0.
|
|
639
677
|
|
|
640
|
-
The returned inventory has the
|
|
678
|
+
The returned inventory has the structure:
|
|
641
679
|
```
|
|
642
680
|
{
|
|
643
681
|
year (int): {
|
|
644
682
|
_InventoryKey.SHARE_OF_EMISSION: {
|
|
645
|
-
cycle_id (str):
|
|
646
|
-
...cycle_ids
|
|
683
|
+
cycle_id (str): float, # share of emissions attributed to this cycle
|
|
684
|
+
...more cycle_ids
|
|
647
685
|
}
|
|
648
686
|
},
|
|
649
687
|
...more years
|
|
@@ -653,17 +691,17 @@ def _compile_cycle_inventory(cycles: list[dict]) -> dict:
|
|
|
653
691
|
Parameters
|
|
654
692
|
----------
|
|
655
693
|
cycles : list[dict]
|
|
656
|
-
List of [Cycle
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
694
|
+
List of [Cycle](https://www.hestia.earth/schema/Cycle) nodes.
|
|
695
|
+
|
|
696
|
+
Each cycle dictionary must include:
|
|
697
|
+
- `@id` : str, unique identifier for the cycle
|
|
698
|
+
- `fraction_of_group_duration` : float, the fraction of the year this cycle contributes, typically added by
|
|
699
|
+
`group_nodes_by_year`.
|
|
662
700
|
|
|
663
701
|
Returns
|
|
664
702
|
-------
|
|
665
703
|
dict
|
|
666
|
-
A dictionary
|
|
704
|
+
A dictionary mapping each year to its inventory of emission shares per cycle.
|
|
667
705
|
"""
|
|
668
706
|
grouped_cycles = group_nodes_by_year(cycles)
|
|
669
707
|
|
|
@@ -682,27 +720,30 @@ def _compile_cycle_inventory(cycles: list[dict]) -> dict:
|
|
|
682
720
|
|
|
683
721
|
def _compile_carbon_stock_inventory(
|
|
684
722
|
carbon_stock_measurements: list[dict],
|
|
723
|
+
transition_period: float,
|
|
685
724
|
iterations: int = 10000,
|
|
686
725
|
seed: Union[int, random.Generator, None] = None
|
|
687
726
|
) -> dict:
|
|
688
727
|
"""
|
|
689
|
-
Compile an annual inventory of carbon stock
|
|
728
|
+
Compile an annual inventory of carbon stock, stock change, and associated CO₂ emissions.
|
|
690
729
|
|
|
691
|
-
Carbon stock measurements are grouped by
|
|
692
|
-
|
|
693
|
-
|
|
730
|
+
Carbon stock measurements are grouped by their measurement method (`MeasurementMethodClassification`). For each
|
|
731
|
+
method:
|
|
732
|
+
- Annual carbon stock values are estimated.
|
|
733
|
+
- Year-to-year changes in carbon stocks are calculated.
|
|
734
|
+
- CO₂ emissions are derived from the changes.
|
|
694
735
|
|
|
695
|
-
The returned inventory has the
|
|
736
|
+
The returned inventory has the structure:
|
|
696
737
|
```
|
|
697
738
|
{
|
|
698
739
|
method (MeasurementMethodClassification): {
|
|
699
740
|
year (int): {
|
|
700
|
-
_InventoryKey.CARBON_STOCK:
|
|
701
|
-
_InventoryKey.CARBON_STOCK_CHANGE:
|
|
702
|
-
_InventoryKey.CO2_EMISSION:
|
|
741
|
+
_InventoryKey.CARBON_STOCK: CarbonStock,
|
|
742
|
+
_InventoryKey.CARBON_STOCK_CHANGE: CarbonStockChange,
|
|
743
|
+
_InventoryKey.CO2_EMISSION: CarbonStockChangeEmission
|
|
703
744
|
},
|
|
704
745
|
...more years
|
|
705
|
-
}
|
|
746
|
+
},
|
|
706
747
|
...more methods
|
|
707
748
|
}
|
|
708
749
|
```
|
|
@@ -710,41 +751,60 @@ def _compile_carbon_stock_inventory(
|
|
|
710
751
|
Parameters
|
|
711
752
|
----------
|
|
712
753
|
carbon_stock_measurements : list[dict]
|
|
713
|
-
List of
|
|
714
|
-
|
|
715
|
-
|
|
754
|
+
List of [Measurement](https://www.hestia.earth/schema/Measurement) nodes representing
|
|
755
|
+
carbon stock observations. Each measurement should include:
|
|
756
|
+
- `@id` : str, unique measurement identifier
|
|
757
|
+
- `measurementMethod` : MeasurementMethodClassification
|
|
758
|
+
- `value` : float
|
|
759
|
+
- `timestamp` or `year` : temporal reference
|
|
760
|
+
|
|
761
|
+
transition_period : float, default=_TRANSITION_PERIOD_DAYS
|
|
762
|
+
The transition period (in days) over which management changes are assumed to take effect. Used to generate a
|
|
763
|
+
correlation matrix for multivariate sampling of carbon stock values.
|
|
764
|
+
|
|
765
|
+
iterations : int, default=10000
|
|
766
|
+
Number of iterations for stochastic sampling when estimating carbon stock values.
|
|
767
|
+
|
|
716
768
|
seed : int, random.Generator, or None, optional
|
|
717
|
-
Seed for random number generation
|
|
769
|
+
Seed for random number generation. Default is `None`.
|
|
718
770
|
|
|
719
771
|
Returns
|
|
720
772
|
-------
|
|
721
773
|
dict
|
|
722
|
-
|
|
774
|
+
Nested dictionary of annual inventories, grouped by measurement method classification.
|
|
723
775
|
"""
|
|
724
776
|
carbon_stock_measurements_by_method = group_measurements_by_method_classification(carbon_stock_measurements)
|
|
725
777
|
|
|
726
778
|
return {
|
|
727
|
-
method: _process_carbon_stock_measurements(measurements, iterations
|
|
779
|
+
method: _process_carbon_stock_measurements(measurements, transition_period, iterations, seed)
|
|
728
780
|
for method, measurements in carbon_stock_measurements_by_method.items()
|
|
729
781
|
}
|
|
730
782
|
|
|
731
783
|
|
|
732
784
|
def _process_carbon_stock_measurements(
|
|
733
785
|
carbon_stock_measurements: list[dict],
|
|
786
|
+
transition_period: float,
|
|
734
787
|
iterations: int = 10000,
|
|
735
788
|
seed: Union[int, random.Generator, None] = None
|
|
736
789
|
) -> dict:
|
|
737
790
|
"""
|
|
738
|
-
Process carbon stock measurements to
|
|
739
|
-
|
|
791
|
+
Process carbon stock measurements to build an annual inventory of carbon stocks,
|
|
792
|
+
carbon stock changes, and CO₂ emissions.
|
|
740
793
|
|
|
741
|
-
The
|
|
794
|
+
The function:
|
|
795
|
+
- Preprocesses measurements (e.g., applies decay/transition dynamics using `transition_period`).
|
|
796
|
+
- Interpolates carbon stock values across years.
|
|
797
|
+
- Calculates year-to-year stock changes.
|
|
798
|
+
- Derives CO₂ emissions from the stock changes.
|
|
799
|
+
- Merges results into a single annual inventory.
|
|
800
|
+
|
|
801
|
+
The returned inventory has the structure:
|
|
742
802
|
```
|
|
743
803
|
{
|
|
744
804
|
year (int): {
|
|
745
|
-
_InventoryKey.CARBON_STOCK:
|
|
746
|
-
_InventoryKey.CARBON_STOCK_CHANGE:
|
|
747
|
-
_InventoryKey.CO2_EMISSION:
|
|
805
|
+
_InventoryKey.CARBON_STOCK: CarbonStock,
|
|
806
|
+
_InventoryKey.CARBON_STOCK_CHANGE: CarbonStockChange,
|
|
807
|
+
_InventoryKey.CO2_EMISSION: CarbonStockChangeEmission,
|
|
748
808
|
},
|
|
749
809
|
...more years
|
|
750
810
|
}
|
|
@@ -753,18 +813,33 @@ def _process_carbon_stock_measurements(
|
|
|
753
813
|
Parameters
|
|
754
814
|
----------
|
|
755
815
|
carbon_stock_measurements : list[dict]
|
|
756
|
-
List of
|
|
757
|
-
|
|
758
|
-
|
|
816
|
+
List of carbon stock [Measurement](https://www.hestia.earth/schema/Measurement) nodes.
|
|
817
|
+
|
|
818
|
+
Each measurement is expected to include:
|
|
819
|
+
- `@id` : str, unique identifier
|
|
820
|
+
- `value` : float, the carbon stock estimate
|
|
821
|
+
- `timestamp` or `year` : temporal reference
|
|
822
|
+
- `measurementMethod` : MeasurementMethodClassification
|
|
823
|
+
|
|
824
|
+
transition_period : float, default=_TRANSITION_PERIOD_DAYS
|
|
825
|
+
The transition period (in days) over which management changes are assumed to take effect. Used to generate a
|
|
826
|
+
correlation matrix for multivariate sampling of carbon stock values.
|
|
827
|
+
|
|
828
|
+
iterations : int, default=10000
|
|
829
|
+
Number of iterations for stochastic sampling when estimating carbon stock values.
|
|
830
|
+
|
|
759
831
|
seed : int, random.Generator, or None, optional
|
|
760
|
-
Seed for random number generation
|
|
832
|
+
Seed for random number generation to ensure reproducibility. Default is `None`.
|
|
761
833
|
|
|
762
834
|
Returns
|
|
763
835
|
-------
|
|
764
836
|
dict
|
|
765
|
-
|
|
837
|
+
Annual inventory mapping years to:
|
|
838
|
+
- `_InventoryKey.CARBON_STOCK` : CarbonStock
|
|
839
|
+
- `_InventoryKey.CARBON_STOCK_CHANGE` : CarbonStockChange
|
|
840
|
+
- `_InventoryKey.CO2_EMISSION` : CarbonStockChangeEmission
|
|
766
841
|
"""
|
|
767
|
-
carbon_stocks = _preprocess_carbon_stocks(carbon_stock_measurements, iterations, seed)
|
|
842
|
+
carbon_stocks = _preprocess_carbon_stocks(carbon_stock_measurements, transition_period, iterations, seed)
|
|
768
843
|
|
|
769
844
|
carbon_stocks_by_year = _interpolate_carbon_stocks(carbon_stocks)
|
|
770
845
|
carbon_stock_changes_by_year = _calculate_stock_changes(carbon_stocks_by_year)
|
|
@@ -775,29 +850,47 @@ def _process_carbon_stock_measurements(
|
|
|
775
850
|
|
|
776
851
|
def _preprocess_carbon_stocks(
|
|
777
852
|
carbon_stock_measurements: list[dict],
|
|
853
|
+
half_life: float,
|
|
778
854
|
iterations: int = 10000,
|
|
779
855
|
seed: Union[int, random.Generator, None] = None
|
|
780
856
|
) -> list[CarbonStock]:
|
|
781
857
|
"""
|
|
782
|
-
|
|
783
|
-
|
|
858
|
+
Preprocess a list of carbon stock measurements by normalizing, filling missing values, and generating correlated
|
|
859
|
+
stochastic samples.
|
|
784
860
|
|
|
785
|
-
|
|
786
|
-
|
|
861
|
+
Steps:
|
|
862
|
+
- Measurements are expanded and sorted by date.
|
|
863
|
+
- Missing uncertainty values (e.g., standard deviations) are filled if necessary.
|
|
864
|
+
- A correlation matrix across time is built using an exponential decay function parameterized by `half_life`.
|
|
865
|
+
- Correlated random samples are drawn to represent measurement uncertainty over time.
|
|
866
|
+
- The results are returned as a list of `CarbonStock` objects.
|
|
787
867
|
|
|
788
868
|
Parameters
|
|
789
869
|
----------
|
|
790
870
|
carbon_stock_measurements : list[dict]
|
|
791
|
-
List of
|
|
792
|
-
|
|
793
|
-
|
|
871
|
+
List of carbon stock [Measurement](https://www.hestia.earth/schema/Measurement) nodes.
|
|
872
|
+
Each measurement is expected to include:
|
|
873
|
+
- `@id` : str, unique identifier
|
|
874
|
+
- `value` : float, measured carbon stock
|
|
875
|
+
- `timestamp` or `year` : temporal reference
|
|
876
|
+
- `standardDeviation` : float, optional measurement uncertainty
|
|
877
|
+
- `measurementMethod` : MeasurementMethodClassification
|
|
878
|
+
|
|
879
|
+
half_life : float
|
|
880
|
+
Transition period (in days) used to parameterize the exponential decay function for building the correlation
|
|
881
|
+
matrix across time.
|
|
882
|
+
|
|
883
|
+
iterations : int, default=10000
|
|
884
|
+
Number of stochastic samples to draw for each measurement.
|
|
885
|
+
|
|
794
886
|
seed : int, random.Generator, or None, optional
|
|
795
|
-
Seed for random number generation
|
|
887
|
+
Seed for random number generation, to ensure reproducibility.
|
|
796
888
|
|
|
797
889
|
Returns
|
|
798
890
|
-------
|
|
799
891
|
list[CarbonStock]
|
|
800
|
-
A list of
|
|
892
|
+
A list of `CarbonStock` objects, one per measurement date and method, each containing simulated sample values
|
|
893
|
+
and associated metadata.
|
|
801
894
|
"""
|
|
802
895
|
dates, values, sds, methods = _extract_node_data(
|
|
803
896
|
flatten([split_node_by_dates(m) for m in carbon_stock_measurements])
|
|
@@ -807,7 +900,7 @@ def _preprocess_carbon_stocks(
|
|
|
807
900
|
dates,
|
|
808
901
|
decay_fn=lambda dt: exponential_decay(
|
|
809
902
|
dt,
|
|
810
|
-
tau=calc_tau(
|
|
903
|
+
tau=calc_tau(half_life),
|
|
811
904
|
initial_value=_MAX_CORRELATION,
|
|
812
905
|
final_value=_MIN_CORRELATION
|
|
813
906
|
)
|
|
@@ -982,13 +1075,17 @@ def _compile_land_use_inventory(
|
|
|
982
1075
|
----------
|
|
983
1076
|
land_cover_nodes : list[dict]
|
|
984
1077
|
A list of `landCover` Management nodes, representing the site's land cover over time.
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1078
|
+
|
|
1079
|
+
summarise_land_use_func : Callable[[list[dict]], Any]
|
|
1080
|
+
Function with signature `(nodes: list[dict]) -> Any`.
|
|
1081
|
+
|
|
1082
|
+
Summarises a list of `landCover` [Management](https://www.hestia.earth/schema/Management) nodes into a
|
|
1083
|
+
comparable representation for detecting land use changes.
|
|
1084
|
+
|
|
1085
|
+
detect_land_use_change_func : Callable[[Any, Any], bool]
|
|
1086
|
+
Function with signature `(summary_a: Any, summary_b: Any) -> bool`.
|
|
1087
|
+
|
|
1088
|
+
Detects whether a land use change event has occurred between two summaries.
|
|
992
1089
|
|
|
993
1090
|
Returns
|
|
994
1091
|
-------
|
|
@@ -1086,13 +1183,14 @@ def _squash_inventory(
|
|
|
1086
1183
|
measurement_method_ranking: list[MeasurementMethodClassification] = DEFAULT_MEASUREMENT_METHOD_RANKING
|
|
1087
1184
|
) -> dict:
|
|
1088
1185
|
"""
|
|
1089
|
-
Combine the `cycle_inventory` and `
|
|
1090
|
-
|
|
1091
|
-
|
|
1186
|
+
Combine the `cycle_inventory`, `carbon_stock_inventory`, and `land_use_inventory` into a single inventory.
|
|
1187
|
+
|
|
1188
|
+
For each year, the function selects the strongest available `MeasurementMethodClassification` (based on the
|
|
1189
|
+
ranking) to provide carbon stock and emissions data, and merges it with cycle-level emissions shares and land use
|
|
1190
|
+
change information.
|
|
1092
1191
|
|
|
1093
1192
|
Parameters
|
|
1094
1193
|
----------
|
|
1095
|
-
|
|
1096
1194
|
cycle_inventory : dict
|
|
1097
1195
|
A dictionary representing the share of emissions for each cycle, grouped by year.
|
|
1098
1196
|
Format:
|
|
@@ -1133,15 +1231,16 @@ def _squash_inventory(
|
|
|
1133
1231
|
year (int): {
|
|
1134
1232
|
_InventoryKey.LAND_USE_SUMMARY: value (Any),
|
|
1135
1233
|
_InventoryKey.LAND_USE_CHANGE_EVENT: value (bool),
|
|
1136
|
-
_InventoryKey.YEARS_SINCE_LUC_EVENT: value (int)
|
|
1234
|
+
_InventoryKey.YEARS_SINCE_LUC_EVENT: value (int),
|
|
1235
|
+
_InventoryKey.YEARS_SINCE_INVENTORY_START: value (int)
|
|
1137
1236
|
},
|
|
1138
1237
|
...years
|
|
1139
1238
|
}
|
|
1140
1239
|
```
|
|
1141
1240
|
|
|
1142
1241
|
measurement_method_ranking : list[MeasurementMethodClassification], optional
|
|
1143
|
-
The order in which to prioritise `MeasurementMethodClassification`s when reducing the inventory
|
|
1144
|
-
|
|
1242
|
+
The order in which to prioritise `MeasurementMethodClassification`s when reducing the inventory to a single
|
|
1243
|
+
method per year. Defaults to:
|
|
1145
1244
|
```
|
|
1146
1245
|
MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT,
|
|
1147
1246
|
MeasurementMethodClassification.MODELLED_USING_OTHER_MEASUREMENTS,
|
|
@@ -1149,13 +1248,12 @@ def _squash_inventory(
|
|
|
1149
1248
|
MeasurementMethodClassification.TIER_2_MODEL,
|
|
1150
1249
|
MeasurementMethodClassification.TIER_1_MODEL
|
|
1151
1250
|
```
|
|
1152
|
-
|
|
1251
|
+
Note: measurements with methods not included in the ranking are ignored.
|
|
1153
1252
|
|
|
1154
1253
|
Returns
|
|
1155
1254
|
-------
|
|
1156
1255
|
dict
|
|
1157
|
-
A combined inventory
|
|
1158
|
-
The resulting structure is:
|
|
1256
|
+
A combined inventory with one entry per year containing:
|
|
1159
1257
|
```
|
|
1160
1258
|
{
|
|
1161
1259
|
year (int): {
|
|
@@ -1165,7 +1263,11 @@ def _squash_inventory(
|
|
|
1165
1263
|
_InventoryKey.SHARE_OF_EMISSION: {
|
|
1166
1264
|
cycle_id (str): value (float),
|
|
1167
1265
|
...other cycle_ids
|
|
1168
|
-
}
|
|
1266
|
+
},
|
|
1267
|
+
_InventoryKey.LAND_USE_SUMMARY: value (Any),
|
|
1268
|
+
_InventoryKey.LAND_USE_CHANGE_EVENT: value (bool),
|
|
1269
|
+
_InventoryKey.YEARS_SINCE_LUC_EVENT: value (int),
|
|
1270
|
+
_InventoryKey.YEARS_SINCE_INVENTORY_START: value (int)
|
|
1169
1271
|
},
|
|
1170
1272
|
...more years
|
|
1171
1273
|
}
|
|
@@ -1473,7 +1575,7 @@ def create_run_function(
|
|
|
1473
1575
|
|
|
1474
1576
|
return result | emission_dict | zero_emission_dict
|
|
1475
1577
|
|
|
1476
|
-
def run(cycle_id: str,
|
|
1578
|
+
def run(cycle_id: str, inventory: dict) -> list[dict]:
|
|
1477
1579
|
"""
|
|
1478
1580
|
Calculate emissions for a specific cycle using from a carbon stock change using pre-compiled inventory data.
|
|
1479
1581
|
|
|
@@ -1530,3 +1632,13 @@ def get_zero_emission(year):
|
|
|
1530
1632
|
def _get_emission_method(emission: CarbonStockChangeEmission):
|
|
1531
1633
|
method = emission.method
|
|
1532
1634
|
return method if isinstance(method, EmissionMethodTier) else EmissionMethodTier.TIER_1
|
|
1635
|
+
|
|
1636
|
+
|
|
1637
|
+
def is_soil_based_system(cycles, site_type):
|
|
1638
|
+
return site_type not in _SITE_TYPE_SYSTEMS_MAPPING or all(
|
|
1639
|
+
cumulative_nodes_term_match(
|
|
1640
|
+
cycle.get("practices", []),
|
|
1641
|
+
target_term_ids=_SITE_TYPE_SYSTEMS_MAPPING[site_type],
|
|
1642
|
+
cumulative_threshold=0
|
|
1643
|
+
) for cycle in cycles
|
|
1644
|
+
)
|