hestia-earth-models 0.64.3__py3-none-any.whl → 0.64.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/blonkConsultants2016/ch4ToAirNaturalVegetationBurning.py +5 -9
- hestia_earth/models/blonkConsultants2016/co2ToAirAboveGroundBiomassStockChangeLandUseChange.py +5 -9
- hestia_earth/models/blonkConsultants2016/n2OToAirNaturalVegetationBurningDirect.py +6 -13
- hestia_earth/models/cycle/animal/input/properties.py +6 -0
- hestia_earth/models/cycle/completeness/soilAmendment.py +3 -2
- hestia_earth/models/cycle/concentrateFeed.py +10 -4
- hestia_earth/models/cycle/input/properties.py +6 -0
- hestia_earth/models/cycle/liveAnimal.py +2 -2
- hestia_earth/models/cycle/milkYield.py +3 -3
- hestia_earth/models/cycle/otherSitesArea.py +59 -0
- hestia_earth/models/cycle/otherSitesUnusedDuration.py +9 -8
- hestia_earth/models/cycle/pastureSystem.py +3 -2
- hestia_earth/models/cycle/product/properties.py +6 -0
- hestia_earth/models/cycle/siteArea.py +83 -0
- hestia_earth/models/cycle/stockingDensityAnimalHousingAverage.py +28 -16
- hestia_earth/models/cycle/utils.py +1 -1
- hestia_earth/models/environmentalFootprintV3/soilQualityIndexLandOccupation.py +128 -0
- hestia_earth/models/environmentalFootprintV3/utils.py +17 -0
- hestia_earth/models/fantkeEtAl2016/__init__.py +13 -0
- hestia_earth/models/fantkeEtAl2016/damageToHumanHealthParticulateMatterFormation.py +49 -0
- hestia_earth/models/frischknechtEtAl2000/__init__.py +13 -0
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +90 -0
- hestia_earth/models/ipcc2006/co2ToAirOrganicSoilCultivation.py +17 -6
- hestia_earth/models/ipcc2006/n2OToAirOrganicSoilCultivationDirect.py +17 -6
- hestia_earth/models/ipcc2019/animal/liveweightGain.py +4 -3
- hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +4 -3
- hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +5 -4
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +904 -0
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChangeManagementChange.py +70 -618
- hestia_earth/models/mocking/search-results.json +390 -318
- hestia_earth/models/pooreNemecek2018/saplings.py +10 -7
- hestia_earth/models/site/management.py +18 -14
- hestia_earth/models/site/soilMeasurement.py +2 -2
- hestia_earth/models/utils/__init__.py +38 -0
- hestia_earth/models/utils/array_builders.py +63 -52
- hestia_earth/models/utils/blank_node.py +137 -82
- hestia_earth/models/utils/descriptive_stats.py +3 -239
- hestia_earth/models/utils/emission.py +6 -2
- hestia_earth/models/utils/feedipedia.py +15 -2
- hestia_earth/models/utils/impact_assessment.py +10 -5
- hestia_earth/models/utils/landCover.py +9 -0
- hestia_earth/models/utils/lookup.py +16 -3
- hestia_earth/models/utils/measurement.py +3 -28
- hestia_earth/models/utils/stats.py +429 -0
- hestia_earth/models/utils/term.py +15 -3
- hestia_earth/models/utils/time_series.py +90 -0
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.64.3.dist-info → hestia_earth_models-0.64.5.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.64.3.dist-info → hestia_earth_models-0.64.5.dist-info}/RECORD +76 -54
- tests/models/blonkConsultants2016/test_ch4ToAirNaturalVegetationBurning.py +2 -2
- tests/models/blonkConsultants2016/test_co2ToAirAboveGroundBiomassStockChangeLandUseChange.py +2 -2
- tests/models/blonkConsultants2016/test_n2OToAirNaturalVegetationBurningDirect.py +2 -2
- tests/models/cycle/completeness/test_soilAmendment.py +1 -1
- tests/models/cycle/test_liveAnimal.py +1 -1
- tests/models/cycle/test_milkYield.py +1 -1
- tests/models/cycle/test_otherSitesArea.py +68 -0
- tests/models/cycle/test_siteArea.py +51 -0
- tests/models/cycle/test_stockingDensityAnimalHousingAverage.py +2 -2
- tests/models/environmentalFootprintV3/test_soilQualityIndexLandOccupation.py +136 -0
- tests/models/fantkeEtAl2016/__init__.py +0 -0
- tests/models/fantkeEtAl2016/test_damageToHumanHealthParticulateMatterFormation.py +20 -0
- tests/models/frischknechtEtAl2000/__init__.py +0 -0
- tests/models/frischknechtEtAl2000/test_ionisingRadiationKbqU235Eq.py +70 -0
- tests/models/ipcc2019/test_co2ToAirCarbonStockChange_utils.py +50 -0
- tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChangeManagementChange.py +1 -39
- tests/models/pooreNemecek2018/test_saplings.py +1 -1
- tests/models/site/test_management.py +3 -153
- tests/models/utils/test_array_builders.py +67 -6
- tests/models/utils/test_blank_node.py +191 -7
- tests/models/utils/test_descriptive_stats.py +2 -86
- tests/models/utils/test_measurement.py +1 -22
- tests/models/utils/test_stats.py +186 -0
- tests/models/utils/test_time_series.py +88 -0
- {hestia_earth_models-0.64.3.dist-info → hestia_earth_models-0.64.5.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.64.3.dist-info → hestia_earth_models-0.64.5.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.64.3.dist-info → hestia_earth_models-0.64.5.dist-info}/top_level.txt +0 -0
|
@@ -14,12 +14,12 @@ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
|
14
14
|
[
|
|
15
15
|
(
|
|
16
16
|
'no live animal => no run',
|
|
17
|
-
{'
|
|
17
|
+
{'animals': [{'term': {'termType': 'crop'}, 'value': 10}]},
|
|
18
18
|
False
|
|
19
19
|
),
|
|
20
20
|
(
|
|
21
21
|
'with live animal => run',
|
|
22
|
-
{'
|
|
22
|
+
{'animals': [{'term': {'termType': 'liveAnimal'}, 'value': 10}]},
|
|
23
23
|
True
|
|
24
24
|
),
|
|
25
25
|
]
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from unittest.mock import patch
|
|
3
|
+
|
|
4
|
+
from hestia_earth.models.environmentalFootprintV3.soilQualityIndexLandOccupation import MODEL, TERM_ID, run, _should_run
|
|
5
|
+
from tests.utils import fixtures_path, fake_new_indicator
|
|
6
|
+
|
|
7
|
+
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
|
8
|
+
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_should_run():
|
|
12
|
+
with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
|
|
13
|
+
cycle = json.load(f)
|
|
14
|
+
|
|
15
|
+
# a LandCover type with no CF => no run
|
|
16
|
+
cycle['site']['management'] = [{"endDate": "2024-03-31", "@type": "Management",
|
|
17
|
+
"term": {"termType": "landCover", "@type": "Term", "@id": "ocean"}}]
|
|
18
|
+
|
|
19
|
+
should_run, *args = _should_run(cycle)
|
|
20
|
+
assert not should_run
|
|
21
|
+
|
|
22
|
+
# no management => no run
|
|
23
|
+
cycle['site']['management'] = []
|
|
24
|
+
should_run, *args = _should_run(cycle)
|
|
25
|
+
assert not should_run
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
|
|
29
|
+
def test_run(*args):
|
|
30
|
+
"""
|
|
31
|
+
Example data:
|
|
32
|
+
Country: Italy
|
|
33
|
+
Quantity in m^2: 1.3573373E-9
|
|
34
|
+
CF METHOD factor: 4.3198E+01
|
|
35
|
+
"Charact Result [soil quality index]" result also in result.jsonld : 5.86342566854E-08
|
|
36
|
+
siteArea in test file in ha: 1.3573373E-9 / 10 000 = 1.3573373e-13
|
|
37
|
+
|
|
38
|
+
Name Flow: forest Land occupation
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
args
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
|
|
48
|
+
cycle = json.load(f)
|
|
49
|
+
|
|
50
|
+
with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
|
|
51
|
+
expected = json.load(f)
|
|
52
|
+
|
|
53
|
+
value = run(cycle)
|
|
54
|
+
assert value == expected
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
|
|
58
|
+
def test_run_other_sites(*args):
|
|
59
|
+
"""
|
|
60
|
+
This test case contains 2 sites:
|
|
61
|
+
One is a crop in france, with value:
|
|
62
|
+
CF_METHOD_factor_france_permanent_crops * ( siteArea_france_crop * time_in_years )
|
|
63
|
+
= 87.631 * ( 1.0082662E-7 * 1 )
|
|
64
|
+
= 8.835537537220001e-06
|
|
65
|
+
|
|
66
|
+
And one a forest in italy, with value:
|
|
67
|
+
CF_METHOD_factor_italy_forest * ( siteArea_italy_forest * time_in_years )
|
|
68
|
+
= 43.198 * ( 1.3573373E-9 * 1 )
|
|
69
|
+
= 5.86342566854E-08
|
|
70
|
+
|
|
71
|
+
We expect the model to return 8.835537537220001e-06 + 5.86342566854E-08 = 8.894171793905402e-06
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
with open(f"{fixtures_folder}/otherSites/cycle.jsonld", encoding='utf-8') as f:
|
|
75
|
+
cycle = json.load(f)
|
|
76
|
+
|
|
77
|
+
with open(f"{fixtures_folder}/otherSites/result.jsonld", encoding='utf-8') as f:
|
|
78
|
+
expected = json.load(f)
|
|
79
|
+
|
|
80
|
+
value = run(cycle)
|
|
81
|
+
assert value == expected
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
|
|
85
|
+
def test_run_with_subclass_landcover(*args):
|
|
86
|
+
"""
|
|
87
|
+
Example data:
|
|
88
|
+
Country: Italy
|
|
89
|
+
Quantity in m^2: 1.3573373E-9
|
|
90
|
+
CF METHOD factor: 4.3198E+01
|
|
91
|
+
"Charact Result [soil quality index]" result also in result.jsonld : 5.86342566854E-08
|
|
92
|
+
siteArea in test file in ha: 1.3573373E-9 / 10 000 = 1.3573373e-13
|
|
93
|
+
|
|
94
|
+
landCover field "plantationForest" should map to
|
|
95
|
+
Name Flow: "forest, intensive Land occupation"
|
|
96
|
+
"""
|
|
97
|
+
with open(f"{fixtures_folder}/plantationForest/cycle.jsonld", encoding='utf-8') as f:
|
|
98
|
+
cycle = json.load(f)
|
|
99
|
+
|
|
100
|
+
with open(f"{fixtures_folder}/plantationForest/result.jsonld", encoding='utf-8') as f:
|
|
101
|
+
expected = json.load(f)
|
|
102
|
+
|
|
103
|
+
value = run(cycle)
|
|
104
|
+
assert value == expected
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
|
|
108
|
+
def test_run_with_region_missing_data(*args):
|
|
109
|
+
"""
|
|
110
|
+
When given valid sub-region or country not in the lookup file should default to 'region-world'
|
|
111
|
+
"""
|
|
112
|
+
with open(f"{fixtures_folder}/default-region-world/cycle.jsonld", encoding='utf-8') as f:
|
|
113
|
+
cycle = json.load(f)
|
|
114
|
+
|
|
115
|
+
with open(f"{fixtures_folder}/default-region-world/result.jsonld", encoding='utf-8') as f:
|
|
116
|
+
expected = json.load(f)
|
|
117
|
+
|
|
118
|
+
value = run(cycle)
|
|
119
|
+
assert value == expected
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
|
|
123
|
+
def test_run_with_no_region(*args):
|
|
124
|
+
"""
|
|
125
|
+
When no location is specified, defaults to region world.
|
|
126
|
+
"""
|
|
127
|
+
with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
|
|
128
|
+
cycle = json.load(f)
|
|
129
|
+
|
|
130
|
+
del cycle['site']['country']
|
|
131
|
+
|
|
132
|
+
with open(f"{fixtures_folder}/default-region-world/result.jsonld", encoding='utf-8') as f:
|
|
133
|
+
expected = json.load(f)
|
|
134
|
+
|
|
135
|
+
value = run(cycle)
|
|
136
|
+
assert value == expected
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from unittest.mock import patch
|
|
3
|
+
|
|
4
|
+
from hestia_earth.models.fantkeEtAl2016.damageToHumanHealthParticulateMatterFormation import MODEL, TERM_ID, run
|
|
5
|
+
from tests.utils import fixtures_path, fake_new_indicator
|
|
6
|
+
|
|
7
|
+
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
|
8
|
+
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
|
|
12
|
+
def test_run(mocked_indicator):
|
|
13
|
+
with open(f"{fixtures_folder}/impactassessment.jsonld", encoding='utf-8') as f:
|
|
14
|
+
impactassessment = json.load(f)
|
|
15
|
+
|
|
16
|
+
with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
|
|
17
|
+
expected = json.load(f)
|
|
18
|
+
|
|
19
|
+
value = run(impactassessment)
|
|
20
|
+
assert value == expected
|
|
File without changes
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import pytest
|
|
3
|
+
from unittest.mock import patch
|
|
4
|
+
from tests.utils import fixtures_path, fake_new_indicator
|
|
5
|
+
|
|
6
|
+
from hestia_earth.models.frischknechtEtAl2000.ionisingRadiationKbqU235Eq import MODEL, TERM_ID, run, _should_run
|
|
7
|
+
|
|
8
|
+
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
|
9
|
+
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.parametrize(
|
|
13
|
+
'test_name,impact,expected_should_run',
|
|
14
|
+
[
|
|
15
|
+
(
|
|
16
|
+
'no emissionsResourceUse => no run',
|
|
17
|
+
{},
|
|
18
|
+
False
|
|
19
|
+
),
|
|
20
|
+
(
|
|
21
|
+
'no emissions in the lookups list => no run',
|
|
22
|
+
{
|
|
23
|
+
'emissionsResourceUse': [
|
|
24
|
+
{
|
|
25
|
+
'term': {'@id': 'co2ToAirInputsProduction'}
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
False
|
|
30
|
+
),
|
|
31
|
+
(
|
|
32
|
+
'with emissions in the lookup list but no waste inputs => no run',
|
|
33
|
+
{
|
|
34
|
+
'emissionsResourceUse': [
|
|
35
|
+
{
|
|
36
|
+
'term': {'@id': 'ionisingCompoundsToAirInputsProduction'}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
False
|
|
41
|
+
),
|
|
42
|
+
(
|
|
43
|
+
'with emissions in the lookup list and waste inputs => run',
|
|
44
|
+
{
|
|
45
|
+
'emissionsResourceUse': [
|
|
46
|
+
{
|
|
47
|
+
'term': {'@id': 'ionisingCompoundsToAirInputsProduction'},
|
|
48
|
+
'inputs': [{'termType': 'waste'}]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
True
|
|
53
|
+
)
|
|
54
|
+
]
|
|
55
|
+
)
|
|
56
|
+
def test_should_run(test_name, impact, expected_should_run):
|
|
57
|
+
should_run, *args = _should_run(impact)
|
|
58
|
+
assert should_run == expected_should_run, test_name
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
|
|
62
|
+
def test_run(*args):
|
|
63
|
+
with open(f"{fixtures_folder}/impact-assessment.jsonld", encoding='utf-8') as f:
|
|
64
|
+
impactassessment = json.load(f)
|
|
65
|
+
|
|
66
|
+
with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
|
|
67
|
+
expected = json.load(f)
|
|
68
|
+
|
|
69
|
+
value = run(impactassessment)
|
|
70
|
+
assert value == expected
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier, MeasurementMethodClassification
|
|
2
|
+
|
|
3
|
+
from hestia_earth.models.ipcc2019.co2ToAirCarbonStockChange_utils import (
|
|
4
|
+
add_carbon_stock_change_emissions, calc_carbon_stock_change, calc_carbon_stock_change_emission, _convert_c_to_co2,
|
|
5
|
+
lerp_carbon_stocks, CarbonStock, CarbonStockChange, CarbonStockChangeEmission
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def test_convert_c_to_co2():
|
|
10
|
+
KG_C = 1000
|
|
11
|
+
EXPECTED = 3663.836163836164
|
|
12
|
+
assert _convert_c_to_co2(KG_C) == EXPECTED
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_lerp_carbon_stocks():
|
|
16
|
+
START = CarbonStock(20000, "2000-12-31", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT)
|
|
17
|
+
END = CarbonStock(22000, "2002-12-31", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT)
|
|
18
|
+
TARGET_DATE = "2001-12-31"
|
|
19
|
+
EXPECTED = CarbonStock(
|
|
20
|
+
21000, "2001-12-31", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
result = lerp_carbon_stocks(START, END, TARGET_DATE)
|
|
24
|
+
assert result == EXPECTED
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_calc_carbon_stock_change():
|
|
28
|
+
START = CarbonStock(20000, "2000", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT)
|
|
29
|
+
END = CarbonStock(21000, "2001", MeasurementMethodClassification.TIER_1_MODEL)
|
|
30
|
+
EXPECTED = CarbonStockChange(1000, "2000", "2001", MeasurementMethodClassification.TIER_1_MODEL)
|
|
31
|
+
|
|
32
|
+
result = calc_carbon_stock_change(START, END)
|
|
33
|
+
assert result == EXPECTED
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_calc_carbon_stock_change_emission():
|
|
37
|
+
SOC_STOCK_CHANGE = CarbonStockChange(-1000, "2000", "2001", MeasurementMethodClassification.TIER_1_MODEL)
|
|
38
|
+
EXPECTED = CarbonStockChangeEmission(3663.836163836164, "2000", "2001", EmissionMethodTier.TIER_1)
|
|
39
|
+
|
|
40
|
+
result = calc_carbon_stock_change_emission(SOC_STOCK_CHANGE)
|
|
41
|
+
assert result == EXPECTED
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_add_carbon_stock_change_emissions():
|
|
45
|
+
EMISSION_1 = CarbonStockChangeEmission(3000, "2000", "2001", EmissionMethodTier.TIER_1)
|
|
46
|
+
EMISSION_2 = CarbonStockChangeEmission(2000, "2001", "2002", EmissionMethodTier.TIER_1)
|
|
47
|
+
EXPECTED = CarbonStockChangeEmission(5000, "2000", "2002", EmissionMethodTier.TIER_1)
|
|
48
|
+
|
|
49
|
+
result = add_carbon_stock_change_emissions(EMISSION_1, EMISSION_2)
|
|
50
|
+
assert result == EXPECTED
|
|
@@ -4,12 +4,7 @@ from os.path import isfile
|
|
|
4
4
|
from pytest import mark
|
|
5
5
|
from unittest.mock import patch
|
|
6
6
|
|
|
7
|
-
from hestia_earth.
|
|
8
|
-
|
|
9
|
-
from hestia_earth.models.ipcc2019.co2ToAirSoilOrganicCarbonStockChangeManagementChange import (
|
|
10
|
-
calc_soc_stock_change, calc_soc_stock_change_emission, convert_c_to_co2, lerp_soc_stocks, MODEL, run, TERM_ID,
|
|
11
|
-
SocStock, SocStockChange, SocStockChangeEmission
|
|
12
|
-
)
|
|
7
|
+
from hestia_earth.models.ipcc2019.co2ToAirSoilOrganicCarbonStockChangeManagementChange import MODEL, run, TERM_ID
|
|
13
8
|
|
|
14
9
|
from tests.utils import fake_new_emission, fixtures_path
|
|
15
10
|
|
|
@@ -85,36 +80,3 @@ def test_run_empty(_get_site_mock, related_cycles_mock, _new_emission_mock):
|
|
|
85
80
|
|
|
86
81
|
result = run(CYCLE)
|
|
87
82
|
assert result == EXPECTED
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def test_convert_c_to_co2():
|
|
91
|
-
KG_C = 1000
|
|
92
|
-
EXPECTED = 3663.836163836164
|
|
93
|
-
assert convert_c_to_co2(KG_C) == EXPECTED
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def test_linear_interpolate_soc_stock():
|
|
97
|
-
START = SocStock(20000, "2000-12-31", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT)
|
|
98
|
-
END = SocStock(22000, "2002-12-31", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT)
|
|
99
|
-
TARGET_DATE = "2001-12-31"
|
|
100
|
-
EXPECTED = SocStock(21000, "2001-12-31", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT)
|
|
101
|
-
|
|
102
|
-
result = lerp_soc_stocks(START, END, TARGET_DATE)
|
|
103
|
-
assert result == EXPECTED
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def test_calc_soc_stock_change():
|
|
107
|
-
START = SocStock(20000, "2000", MeasurementMethodClassification.ON_SITE_PHYSICAL_MEASUREMENT)
|
|
108
|
-
END = SocStock(21000, "2001", MeasurementMethodClassification.TIER_1_MODEL)
|
|
109
|
-
EXPECTED = SocStockChange(1000, "2000", "2001", MeasurementMethodClassification.TIER_1_MODEL)
|
|
110
|
-
|
|
111
|
-
result = calc_soc_stock_change(START, END)
|
|
112
|
-
assert result == EXPECTED
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def test_calc_soc_stock_change_emission():
|
|
116
|
-
SOC_STOCK_CHANGE = SocStockChange(-1000, "2000", "2001", MeasurementMethodClassification.TIER_1_MODEL)
|
|
117
|
-
EXPECTED = SocStockChangeEmission(3663.836163836164, "2000", "2001", EmissionMethodTier.TIER_1)
|
|
118
|
-
|
|
119
|
-
result = calc_soc_stock_change_emission(SOC_STOCK_CHANGE)
|
|
120
|
-
assert result == EXPECTED
|
|
@@ -12,7 +12,7 @@ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
|
|
12
12
|
@patch(f"{class_path}.get_crop_lookup_value", return_value=10)
|
|
13
13
|
@patch(f"{class_path}._is_term_type_incomplete", return_value=True)
|
|
14
14
|
def test_should_run(mock_is_term_type_incomplete, *args):
|
|
15
|
-
cycle = {'products': [{'term': {'@id': 'wheatGrain'}}]}
|
|
15
|
+
cycle = {'cycleDuration': 200, 'products': [{'term': {'@id': 'wheatGrain'}}]}
|
|
16
16
|
|
|
17
17
|
mock_is_term_type_incomplete.return_value = False
|
|
18
18
|
should_run, *args = _should_run(cycle)
|
|
@@ -5,7 +5,6 @@ import pytest
|
|
|
5
5
|
from hestia_earth.schema import TermTermType, SiteSiteType
|
|
6
6
|
|
|
7
7
|
from hestia_earth.models.site.management import MODEL, MODEL_KEY, run, _should_run
|
|
8
|
-
from hestia_earth.models.utils.blank_node import condense_nodes
|
|
9
8
|
from tests.utils import fixtures_path
|
|
10
9
|
|
|
11
10
|
CLASS_PATH = f"hestia_earth.models.{MODEL}.{MODEL_KEY}"
|
|
@@ -39,152 +38,6 @@ def lookup_side_effect(*args, **kwargs):
|
|
|
39
38
|
return True
|
|
40
39
|
|
|
41
40
|
|
|
42
|
-
@pytest.mark.parametrize(
|
|
43
|
-
"test_name,input_nodes,expected_output_nodes",
|
|
44
|
-
[
|
|
45
|
-
(
|
|
46
|
-
"No match",
|
|
47
|
-
[
|
|
48
|
-
{"startDate": "2001", "endDate": "2002", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
49
|
-
"value": [2]},
|
|
50
|
-
{"startDate": "2003", "endDate": "2004", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
51
|
-
"value": [2]},
|
|
52
|
-
],
|
|
53
|
-
[
|
|
54
|
-
{"startDate": "2001", "endDate": "2002", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
55
|
-
"value": [2]},
|
|
56
|
-
{"startDate": "2003", "endDate": "2004", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
57
|
-
"value": [2]},
|
|
58
|
-
],
|
|
59
|
-
),
|
|
60
|
-
(
|
|
61
|
-
"No continuity",
|
|
62
|
-
[
|
|
63
|
-
{"startDate": "2001", "endDate": "2002", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
64
|
-
"value": [2]},
|
|
65
|
-
{"startDate": "2004", "endDate": "2005", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
66
|
-
"value": [2]},
|
|
67
|
-
],
|
|
68
|
-
[
|
|
69
|
-
{"startDate": "2001", "endDate": "2002", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
70
|
-
"value": [2]},
|
|
71
|
-
{"startDate": "2004", "endDate": "2005", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
72
|
-
"value": [2]},
|
|
73
|
-
],
|
|
74
|
-
),
|
|
75
|
-
(
|
|
76
|
-
"No continuity (multiple values differ)",
|
|
77
|
-
[
|
|
78
|
-
{"startDate": "2001", "endDate": "2002", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
79
|
-
"value": [10, 20]},
|
|
80
|
-
{"startDate": "2003", "endDate": "2004", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
81
|
-
"value": [10, 30]},
|
|
82
|
-
],
|
|
83
|
-
[
|
|
84
|
-
{"startDate": "2001", "endDate": "2002", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
85
|
-
"value": [10, 20]},
|
|
86
|
-
{"startDate": "2003", "endDate": "2004", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
87
|
-
"value": [10, 30]},
|
|
88
|
-
],
|
|
89
|
-
),
|
|
90
|
-
(
|
|
91
|
-
"2->1 condense (YYYY dates)",
|
|
92
|
-
[
|
|
93
|
-
{"startDate": "2001", "endDate": "2001", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
94
|
-
"value": [10, 20]},
|
|
95
|
-
{"startDate": "2002", "endDate": "2002", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
96
|
-
"value": [10, 20]},
|
|
97
|
-
],
|
|
98
|
-
[
|
|
99
|
-
{"startDate": "2001-01-01", "endDate": "2002-12-31", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
100
|
-
"value": [10, 20]}
|
|
101
|
-
],
|
|
102
|
-
),
|
|
103
|
-
(
|
|
104
|
-
"4->2 condense (YYYY-MM dates)",
|
|
105
|
-
[
|
|
106
|
-
{"startDate": "2001-01", "endDate": "2001-12", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
107
|
-
"value": [2]},
|
|
108
|
-
{"startDate": "2002-01", "endDate": "2002-03", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
109
|
-
"value": [2]},
|
|
110
|
-
],
|
|
111
|
-
[
|
|
112
|
-
{"startDate": "2001-01-01", "endDate": "2002-03-31", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
113
|
-
"value": [2]}
|
|
114
|
-
],
|
|
115
|
-
),
|
|
116
|
-
(
|
|
117
|
-
"2->1 condense (YYYY-MM-DD dates)",
|
|
118
|
-
[
|
|
119
|
-
{"startDate": "2001-01-01", "endDate": "2001-12-31", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
120
|
-
"value": [2]},
|
|
121
|
-
{"startDate": "2002-01-01", "endDate": "2002-05-04", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
122
|
-
"value": [2]},
|
|
123
|
-
],
|
|
124
|
-
[
|
|
125
|
-
{"startDate": "2001-01-01", "endDate": "2002-05-04", "term": {"@id": "treeNutTree", "units": "% area"},
|
|
126
|
-
"value": [2]}
|
|
127
|
-
],
|
|
128
|
-
),
|
|
129
|
-
(
|
|
130
|
-
"3->1 condense",
|
|
131
|
-
[
|
|
132
|
-
{"startDate": "2001-01-01", "endDate": "2001-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
133
|
-
"value": [9]},
|
|
134
|
-
{"startDate": "2002-01-01", "endDate": "2002-10-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
135
|
-
"value": [9]},
|
|
136
|
-
{"startDate": "2002-11-01", "endDate": "2004-04-05", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
137
|
-
"value": [9]},
|
|
138
|
-
],
|
|
139
|
-
[
|
|
140
|
-
{"startDate": "2001-01-01", "endDate": "2004-04-05", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
141
|
-
"value": [9]}
|
|
142
|
-
],
|
|
143
|
-
),
|
|
144
|
-
(
|
|
145
|
-
"3->2 partial condense",
|
|
146
|
-
[
|
|
147
|
-
{"startDate": "2001-01-01", "endDate": "2001-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
148
|
-
"value": [9]},
|
|
149
|
-
{"startDate": "2012-02-01", "endDate": "2012-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
150
|
-
"value": [9]},
|
|
151
|
-
{"startDate": "2002-01-01", "endDate": "2003-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
152
|
-
"value": [9]},
|
|
153
|
-
],
|
|
154
|
-
[
|
|
155
|
-
{"startDate": "2001-01-01", "endDate": "2003-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
156
|
-
"value": [9]},
|
|
157
|
-
{"startDate": "2012-02-01", "endDate": "2012-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
158
|
-
"value": [9]}
|
|
159
|
-
],
|
|
160
|
-
),
|
|
161
|
-
(
|
|
162
|
-
"7->2 multi-condense",
|
|
163
|
-
[
|
|
164
|
-
{"startDate": "2001-01-01", "endDate": "2001-11-30", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
165
|
-
"value": [7]},
|
|
166
|
-
{"startDate": "2012-02-01", "endDate": "2012-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
167
|
-
"value": [7]},
|
|
168
|
-
{"startDate": "2001-12-01", "endDate": "2001-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
169
|
-
"value": [7]},
|
|
170
|
-
{"startDate": "2002-01-01", "endDate": "2002-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
171
|
-
"value": [7]},
|
|
172
|
-
{"startDate": "2013-01-01", "endDate": "2013-05-20", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
173
|
-
"value": [7]},
|
|
174
|
-
],
|
|
175
|
-
[
|
|
176
|
-
{"startDate": "2001-01-01", "endDate": "2002-12-31", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
177
|
-
"value": [7]},
|
|
178
|
-
{"startDate": "2012-02-01", "endDate": "2013-05-20", "term": {"@id": "bananaPlant", "units": "% area"},
|
|
179
|
-
"value": [7]}
|
|
180
|
-
],
|
|
181
|
-
),
|
|
182
|
-
]
|
|
183
|
-
)
|
|
184
|
-
def test_condense_nodes(test_name, input_nodes, expected_output_nodes):
|
|
185
|
-
assert condense_nodes(input_nodes) == expected_output_nodes
|
|
186
|
-
|
|
187
|
-
|
|
188
41
|
@patch(f"{CLASS_PATH}.download_hestia", side_effect=lambda id, *args: TERM_BY_ID[id])
|
|
189
42
|
@patch(f"{CLASS_PATH}.related_cycles")
|
|
190
43
|
def test_should_run(mock_related_cycles, *args):
|
|
@@ -253,8 +106,7 @@ def test_should_run(mock_related_cycles, *args):
|
|
|
253
106
|
},
|
|
254
107
|
"value": [51],
|
|
255
108
|
"startDate": "2001",
|
|
256
|
-
"endDate": "2002"
|
|
257
|
-
"properties": {"test": "properties"}
|
|
109
|
+
"endDate": "2002"
|
|
258
110
|
}
|
|
259
111
|
],
|
|
260
112
|
"startDate": "2021",
|
|
@@ -275,8 +127,7 @@ def test_should_run(mock_related_cycles, *args):
|
|
|
275
127
|
},
|
|
276
128
|
"value": [51],
|
|
277
129
|
"startDate": "2001",
|
|
278
|
-
"endDate": "2002"
|
|
279
|
-
"properties": {"test": "properties"}
|
|
130
|
+
"endDate": "2002"
|
|
280
131
|
}
|
|
281
132
|
],
|
|
282
133
|
"startDate": "2021",
|
|
@@ -289,8 +140,7 @@ def test_should_run(mock_related_cycles, *args):
|
|
|
289
140
|
'term': TERM_BY_ID['genericCropPlant'],
|
|
290
141
|
'value': 100,
|
|
291
142
|
'endDate': '2022',
|
|
292
|
-
'startDate': '2021'
|
|
293
|
-
'properties': {'test': 'properties'}
|
|
143
|
+
'startDate': '2021'
|
|
294
144
|
}]
|
|
295
145
|
|
|
296
146
|
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
from numpy import array
|
|
2
|
-
from numpy.testing import assert_array_equal
|
|
1
|
+
from numpy import array, corrcoef
|
|
2
|
+
from numpy.testing import assert_array_equal, assert_allclose
|
|
3
3
|
from numpy.typing import NDArray
|
|
4
4
|
from pytest import mark
|
|
5
5
|
|
|
6
6
|
from hestia_earth.models.utils.array_builders import (
|
|
7
|
-
avg_run_in_columnwise, avg_run_in_rowwise, discrete_uniform_1d, discrete_uniform_2d,
|
|
8
|
-
normal_1d, normal_2d, plus_minus_uncertainty_to_normal_1d,
|
|
9
|
-
repeat_1d_array_as_columns, repeat_array_as_columns, repeat_array_as_rows,
|
|
10
|
-
triangular_2d, truncated_normal_1d, truncated_normal_2d
|
|
7
|
+
avg_run_in_columnwise, avg_run_in_rowwise, correlated_normal_2d, discrete_uniform_1d, discrete_uniform_2d,
|
|
8
|
+
gen_seed, grouped_avg, normal_1d, normal_2d, plus_minus_uncertainty_to_normal_1d,
|
|
9
|
+
plus_minus_uncertainty_to_normal_2d, repeat_1d_array_as_columns, repeat_array_as_columns, repeat_array_as_rows,
|
|
10
|
+
repeat_single, triangular_1d, triangular_2d, truncated_normal_1d, truncated_normal_2d
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
SEED = 0
|
|
14
|
+
N_ITERATIONS = 10000
|
|
14
15
|
SHAPE = (1000, 1000)
|
|
15
16
|
|
|
16
17
|
|
|
@@ -251,3 +252,63 @@ def test_gen_seed_no_id():
|
|
|
251
252
|
EXPECTED = 2140941220
|
|
252
253
|
result = gen_seed(NODE)
|
|
253
254
|
assert result == EXPECTED
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
# means, sds, correlation_matrix, tol_kwargs
|
|
258
|
+
PARAMS_CORRELATED_NORMAL_2D = [
|
|
259
|
+
(
|
|
260
|
+
array([0, 0, 0, 0, 0]),
|
|
261
|
+
array([1, 1, 1, 1, 1]),
|
|
262
|
+
array([
|
|
263
|
+
[1.0, 0.5, 0.25, 0.125, 0.0625],
|
|
264
|
+
[0.5, 1.0, 0.5, 0.25, 0.125],
|
|
265
|
+
[0.25, 0.5, 1.0, 0.5, 0.25],
|
|
266
|
+
[0.125, 0.25, 0.5, 1.0, 0.5],
|
|
267
|
+
[0.0625, 0.125, 0.25, 0.5, 1.0]
|
|
268
|
+
]),
|
|
269
|
+
{"atol": 0.05}
|
|
270
|
+
),
|
|
271
|
+
(
|
|
272
|
+
array([40000, 42000, 43000, 44333.333]),
|
|
273
|
+
array([4000, 4200, 4300, 4433.333]),
|
|
274
|
+
array([
|
|
275
|
+
[1.0, 0.965867, 0.932987, 0.901227],
|
|
276
|
+
[0.965867, 1.0, 0.965959, 0.933076],
|
|
277
|
+
[0.932987, 0.965959, 1.0, 0.965959],
|
|
278
|
+
[0.901227, 0.933076, 0.965959, 1.0]
|
|
279
|
+
]),
|
|
280
|
+
{"rtol": 0.05}
|
|
281
|
+
),
|
|
282
|
+
(
|
|
283
|
+
array([40000, 42000, 43000, 44333.333]),
|
|
284
|
+
array([4000, 4200, 4300, 4433.333]),
|
|
285
|
+
array([
|
|
286
|
+
[1.0, 0, 0, 0],
|
|
287
|
+
[0, 1.0, 0, 0],
|
|
288
|
+
[0, 0, 1.0, 0],
|
|
289
|
+
[0, 0, 0, 1.0]
|
|
290
|
+
]),
|
|
291
|
+
{"rtol": 0.05}
|
|
292
|
+
)
|
|
293
|
+
]
|
|
294
|
+
IDS_CORRELATED_NORMAL_2D = [
|
|
295
|
+
"standard normal distributions",
|
|
296
|
+
"custom normal distributions",
|
|
297
|
+
"no correlation"
|
|
298
|
+
]
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
@mark.parametrize(
|
|
302
|
+
"means, sds, correlation_matrix, tol_kwargs",
|
|
303
|
+
PARAMS_CORRELATED_NORMAL_2D,
|
|
304
|
+
ids=IDS_CORRELATED_NORMAL_2D
|
|
305
|
+
)
|
|
306
|
+
def test_correlated_normal_2d_standard_normal_dist(
|
|
307
|
+
means: NDArray, sds: NDArray, correlation_matrix: NDArray, tol_kwargs: dict
|
|
308
|
+
):
|
|
309
|
+
result = correlated_normal_2d(N_ITERATIONS, means, sds, correlation_matrix, seed=SEED)
|
|
310
|
+
empirical_correlation_matrix = corrcoef(result)
|
|
311
|
+
|
|
312
|
+
assert_allclose(result.mean(axis=1), means, **tol_kwargs) # row-wise mean matches input
|
|
313
|
+
assert_allclose(result.std(axis=1), sds, **tol_kwargs) # row-wise SD matches input
|
|
314
|
+
assert_allclose(empirical_correlation_matrix, correlation_matrix, atol=0.05) # correlation matches input
|