hestia-earth-models 0.70.0__py3-none-any.whl → 0.70.1__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/aware/scarcityWeightedWaterUse.py +8 -16
- hestia_earth/models/config/Cycle.json +52 -64
- hestia_earth/models/config/ImpactAssessment.json +12 -4
- hestia_earth/models/config/Site.json +33 -22
- hestia_earth/models/cycle/transformation.py +1 -1
- hestia_earth/models/cycle/utils.py +0 -6
- hestia_earth/models/data/ecoinventV3/__init__.py +15 -13
- hestia_earth/models/ecoalimV9/__init__.py +13 -0
- hestia_earth/models/ecoalimV9/cycle.py +128 -0
- hestia_earth/models/ecoalimV9/impact_assessment.py +125 -0
- hestia_earth/models/ecoalimV9/utils.py +31 -0
- hestia_earth/models/ecoinventV3/__init__.py +6 -14
- hestia_earth/models/ecoinventV3/utils.py +1 -29
- hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +8 -2
- hestia_earth/models/emissionNotRelevant/__init__.py +33 -8
- hestia_earth/models/{cycle → hestia}/aboveGroundCropResidue.py +4 -3
- hestia_earth/models/{cycle → hestia}/aboveGroundCropResidueTotal.py +1 -1
- hestia_earth/models/{site → hestia}/brackishWater.py +1 -1
- hestia_earth/models/{site → hestia}/cationExchangeCapacityPerKgSoil.py +1 -1
- hestia_earth/models/{cycle → hestia}/coldCarcassWeightPerHead.py +1 -1
- hestia_earth/models/{cycle → hestia}/coldDressedCarcassWeightPerHead.py +1 -1
- hestia_earth/models/{cycle → hestia}/concentrateFeed.py +1 -1
- hestia_earth/models/{cycle → hestia}/cropResidueManagement.py +1 -1
- hestia_earth/models/{cycle → hestia}/croppingIntensity.py +1 -1
- hestia_earth/models/{cycle → hestia}/energyContentLowerHeatingValue.py +1 -1
- hestia_earth/models/{cycle → hestia}/excretaKgMass.py +7 -2
- hestia_earth/models/{cycle → hestia}/excretaKgN.py +1 -1
- hestia_earth/models/{cycle → hestia}/excretaKgVs.py +1 -1
- hestia_earth/models/{cycle → hestia}/feedConversionRatio/__init__.py +1 -1
- hestia_earth/models/{site → hestia}/flowingWater.py +1 -1
- hestia_earth/models/{site → hestia}/freshWater.py +1 -1
- hestia_earth/models/{cycle → hestia}/inorganicFertiliser.py +1 -1
- hestia_earth/models/{cycle → hestia}/irrigatedTypeUnspecified.py +14 -19
- hestia_earth/models/hestia/landCover.py +30 -22
- hestia_earth/models/{cycle → hestia}/liveAnimal.py +1 -1
- hestia_earth/models/{cycle → hestia}/longFallowRatio.py +1 -1
- hestia_earth/models/{cycle → hestia}/materialAndSubstrate.py +1 -1
- hestia_earth/models/{cycle → hestia}/milkYield.py +1 -1
- hestia_earth/models/{site → hestia}/netPrimaryProduction.py +1 -1
- hestia_earth/models/{site → hestia}/organicCarbonPerHa.py +1 -1
- hestia_earth/models/{cycle → hestia}/pastureGrass.py +1 -1
- hestia_earth/models/{cycle → hestia}/pastureSystem.py +1 -1
- hestia_earth/models/{site → hestia}/potentialEvapotranspirationAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/potentialEvapotranspirationMonthly.py +3 -3
- hestia_earth/models/{site → hestia}/precipitationAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/precipitationMonthly.py +3 -3
- hestia_earth/models/{site → hestia}/rainfallAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/rainfallMonthly.py +3 -3
- hestia_earth/models/{cycle → hestia}/readyToCookWeightPerHead.py +1 -1
- hestia_earth/models/{cycle → hestia}/residueBurnt.py +1 -1
- hestia_earth/models/{cycle → hestia}/residueIncorporated.py +1 -1
- hestia_earth/models/{cycle → hestia}/residueLeftOnField.py +1 -1
- hestia_earth/models/hestia/residueRemoved.py +65 -13
- hestia_earth/models/{site → hestia}/salineWater.py +1 -1
- hestia_earth/models/{site → hestia}/soilMeasurement.py +1 -1
- hestia_earth/models/{cycle → hestia}/stockingDensityAnimalHousingAverage.py +1 -1
- hestia_earth/models/{site → hestia}/temperatureAnnual.py +3 -3
- hestia_earth/models/{site → hestia}/temperatureMonthly.py +3 -3
- hestia_earth/models/{site → hestia}/totalNitrogenPerKgSoil.py +1 -1
- hestia_earth/models/{cycle → hestia}/unknownPreSeasonWaterRegime.py +1 -1
- hestia_earth/models/hestia/utils.py +93 -0
- hestia_earth/models/{site → hestia}/waterDepth.py +1 -1
- hestia_earth/models/hestia/waterSalinity.py +78 -0
- hestia_earth/models/ipcc2019/aboveGroundBiomass.py +1 -1
- hestia_earth/models/ipcc2019/belowGroundBiomass.py +1 -1
- hestia_earth/models/ipcc2019/biomass_utils.py +2 -4
- hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +163 -78
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +31 -20
- hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +16 -9
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +35 -47
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +86 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py +127 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +7 -5
- hestia_earth/models/mocking/search-results.json +764 -772
- hestia_earth/models/pooreNemecek2018/utils.py +8 -2
- hestia_earth/models/schmidt2007/ch4ToAirWasteTreatment.py +1 -4
- hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +1 -4
- hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +1 -4
- hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +1 -4
- hestia_earth/models/utils/background_emissions.py +52 -0
- hestia_earth/models/utils/blank_node.py +9 -5
- hestia_earth/models/utils/impact_assessment.py +26 -17
- hestia_earth/models/utils/lookup.py +48 -39
- hestia_earth/models/utils/measurement.py +3 -3
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/RECORD +163 -158
- tests/models/aware/test_scarcityWeightedWaterUse.py +1 -12
- tests/models/ecoalimV9/__init__.py +0 -0
- tests/models/ecoalimV9/test_cycle.py +21 -0
- tests/models/ecoalimV9/test_impact_assessment.py +24 -0
- tests/models/environmentalFootprintV3_1/test_scarcityWeightedWaterUse.py +4 -2
- tests/models/{cycle → hestia}/test_aboveGroundCropResidue.py +1 -1
- tests/models/{cycle → hestia}/test_aboveGroundCropResidueTotal.py +1 -1
- tests/models/{site → hestia}/test_brackishWater.py +1 -1
- tests/models/{site → hestia}/test_cationExchangeCapacityPerKgSoil.py +1 -1
- tests/models/{cycle → hestia}/test_coldCarcassWeightPerHead.py +1 -1
- tests/models/{cycle → hestia}/test_coldDressedCarcassWeightPerHead.py +1 -1
- tests/models/{cycle → hestia}/test_concentrateFeed.py +1 -1
- tests/models/{cycle → hestia}/test_cropResidueManagement.py +1 -1
- tests/models/{cycle → hestia}/test_croppingIntensity.py +1 -1
- tests/models/{cycle → hestia}/test_energyContentLowerHeatingValue.py +5 -3
- tests/models/{cycle → hestia}/test_excretaKgMass.py +1 -1
- tests/models/{cycle → hestia}/test_excretaKgN.py +1 -1
- tests/models/{cycle → hestia}/test_excretaKgVs.py +1 -1
- tests/models/{cycle → hestia}/test_feedConversionRatio.py +1 -1
- tests/models/{site → hestia}/test_flowingWater.py +1 -1
- tests/models/{site → hestia}/test_freshWater.py +1 -1
- tests/models/{cycle → hestia}/test_inorganicFertiliser.py +1 -1
- tests/models/{cycle → hestia}/test_irrigatedTypeUnspecified.py +2 -5
- tests/models/hestia/test_landCover.py +4 -34
- tests/models/{cycle → hestia}/test_liveAnimal.py +1 -1
- tests/models/{cycle → hestia}/test_longFallowRatio.py +1 -1
- tests/models/{site → hestia}/test_management.py +1 -1
- tests/models/{cycle → hestia}/test_materialsAndSubstrate.py +1 -1
- tests/models/{cycle → hestia}/test_milkYield.py +1 -1
- tests/models/{site → hestia}/test_netPrimaryProduction.py +1 -1
- tests/models/{site → hestia}/test_organicCarbonPerHa.py +1 -1
- tests/models/{site → hestia}/test_organicCarbonPerKgSoil.py +1 -1
- tests/models/{site → hestia}/test_organicCarbonPerM3Soil.py +1 -1
- tests/models/{site → hestia}/test_organicMatterPerKgSoil.py +1 -1
- tests/models/{site → hestia}/test_organicMatterPerM3Soil.py +1 -1
- tests/models/{cycle → hestia}/test_pastureGrass.py +1 -1
- tests/models/{cycle → hestia}/test_pastureSystem.py +1 -1
- tests/models/{site → hestia}/test_potentialEvapotranspirationAnnual.py +1 -1
- tests/models/{site → hestia}/test_potentialEvapotranspirationMonthly.py +1 -1
- tests/models/{site → hestia}/test_precipitationAnnual.py +1 -1
- tests/models/{site → hestia}/test_precipitationMonthly.py +1 -1
- tests/models/{site → hestia}/test_rainfallAnnual.py +1 -1
- tests/models/{site → hestia}/test_rainfallMonthly.py +1 -1
- tests/models/{cycle → hestia}/test_readyToCookWeightPerHead.py +1 -1
- tests/models/{cycle → hestia}/test_residueBurnt.py +1 -1
- tests/models/{cycle → hestia}/test_residueIncorporated.py +1 -1
- tests/models/{cycle → hestia}/test_residueLeftOnField.py +1 -1
- tests/models/hestia/test_residueRemoved.py +15 -3
- tests/models/{site → hestia}/test_salineWater.py +1 -1
- tests/models/{site → hestia}/test_soilMeasurement.py +2 -2
- tests/models/{cycle → hestia}/test_stockingDensityAnimalHousingAverage.py +1 -1
- tests/models/{site → hestia}/test_temperatureAnnual.py +1 -1
- tests/models/{site → hestia}/test_temperatureMonthly.py +1 -1
- tests/models/{site → hestia}/test_totalNitrogenPerKgSoil.py +1 -1
- tests/models/{cycle → hestia}/test_unknownPreSeasonWaterRegime.py +1 -1
- tests/models/{site → hestia}/test_waterDepth.py +1 -1
- tests/models/hestia/test_waterSalinity.py +26 -0
- tests/models/ipcc2019/test_ch4ToAirFloodedRice.py +10 -42
- tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +2 -1
- tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +3 -2
- tests/models/test_ecoinventV3AndEmberClimate.py +2 -2
- tests/models/test_emissionNotRelevant.py +0 -8
- tests/models/utils/test_measurement.py +1 -1
- hestia_earth/models/cycle/residueRemoved.py +0 -54
- hestia_earth/models/hestia/nh3ToSurfaceWaterAquacultureSystems.py +0 -64
- hestia_earth/models/site/utils.py +0 -93
- tests/models/cycle/test_residueRemoved.py +0 -37
- tests/models/hestia/test_nh3ToSurfaceWaterAquacultureSystems.py +0 -51
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioCarbon.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioDryMatter.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioEnergy.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioFedWeight.py +0 -0
- /hestia_earth/models/{cycle → hestia}/feedConversionRatio/feedConversionRatioNitrogen.py +0 -0
- /hestia_earth/models/{site → hestia}/management.py +0 -0
- /hestia_earth/models/{site → hestia}/organicCarbonPerKgSoil.py +0 -0
- /hestia_earth/models/{site → hestia}/organicCarbonPerM3Soil.py +0 -0
- /hestia_earth/models/{site → hestia}/organicMatterPerKgSoil.py +0 -0
- /hestia_earth/models/{site → hestia}/organicMatterPerM3Soil.py +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.1.dist-info}/top_level.txt +0 -0
@@ -4,7 +4,7 @@ import pytest
|
|
4
4
|
|
5
5
|
from tests.utils import fixtures_path, fake_new_measurement
|
6
6
|
|
7
|
-
from hestia_earth.models.
|
7
|
+
from hestia_earth.models.hestia.soilMeasurement import (
|
8
8
|
MODEL,
|
9
9
|
MODEL_KEY,
|
10
10
|
_get_overlap,
|
@@ -13,7 +13,7 @@ from hestia_earth.models.site.soilMeasurement import (
|
|
13
13
|
)
|
14
14
|
|
15
15
|
class_path = f"hestia_earth.models.{MODEL}.{MODEL_KEY}"
|
16
|
-
fixtures_folder = f"{fixtures_path}/
|
16
|
+
fixtures_folder = f"{fixtures_path}/{MODEL}/soilMeasurement"
|
17
17
|
|
18
18
|
|
19
19
|
@pytest.mark.parametrize(
|
@@ -3,7 +3,7 @@ import pytest
|
|
3
3
|
import json
|
4
4
|
from tests.utils import fixtures_path, fake_new_practice
|
5
5
|
|
6
|
-
from hestia_earth.models.
|
6
|
+
from hestia_earth.models.hestia.stockingDensityAnimalHousingAverage import MODEL, TERM_ID, run, _should_run
|
7
7
|
|
8
8
|
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
9
9
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
@@ -2,7 +2,7 @@ from unittest.mock import patch
|
|
2
2
|
import json
|
3
3
|
from tests.utils import fixtures_path, fake_new_measurement
|
4
4
|
|
5
|
-
from hestia_earth.models.
|
5
|
+
from hestia_earth.models.hestia.temperatureAnnual import MODEL, TERM_ID, run, _should_run
|
6
6
|
|
7
7
|
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
8
8
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
@@ -2,7 +2,7 @@ from unittest.mock import patch
|
|
2
2
|
import json
|
3
3
|
from tests.utils import fixtures_path, fake_new_measurement
|
4
4
|
|
5
|
-
from hestia_earth.models.
|
5
|
+
from hestia_earth.models.hestia.temperatureMonthly import MODEL, TERM_ID, run, _should_run
|
6
6
|
|
7
7
|
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
8
8
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
@@ -2,7 +2,7 @@ from unittest.mock import patch
|
|
2
2
|
import json
|
3
3
|
from tests.utils import fixtures_path, fake_new_measurement
|
4
4
|
|
5
|
-
from hestia_earth.models.
|
5
|
+
from hestia_earth.models.hestia.totalNitrogenPerKgSoil import MODEL, TERM_ID, run, _should_run
|
6
6
|
|
7
7
|
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
8
8
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
@@ -2,7 +2,7 @@ from unittest.mock import patch
|
|
2
2
|
import json
|
3
3
|
from tests.utils import fake_new_practice, fixtures_path
|
4
4
|
|
5
|
-
from hestia_earth.models.
|
5
|
+
from hestia_earth.models.hestia.unknownPreSeasonWaterRegime import MODEL, TERM_ID, _should_run, run
|
6
6
|
|
7
7
|
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
8
8
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
@@ -2,7 +2,7 @@ from unittest.mock import patch
|
|
2
2
|
import json
|
3
3
|
from tests.utils import fixtures_path, fake_new_measurement
|
4
4
|
|
5
|
-
from hestia_earth.models.
|
5
|
+
from hestia_earth.models.hestia.waterDepth import MODEL, TERM_ID, run
|
6
6
|
|
7
7
|
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
8
8
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from unittest.mock import Mock, patch
|
2
|
+
import json
|
3
|
+
from tests.utils import fixtures_path, fake_new_measurement
|
4
|
+
|
5
|
+
from hestia_earth.models.hestia.waterSalinity import MODEL, TERM_ID, run
|
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_measurement", side_effect=fake_new_measurement)
|
12
|
+
@patch(f"{class_path}.related_cycles")
|
13
|
+
def test_run(mock_related_cycles: Mock, *args):
|
14
|
+
with open(f"{fixtures_folder}/site.jsonld", encoding='utf-8') as f:
|
15
|
+
site = json.load(f)
|
16
|
+
|
17
|
+
with open(f"{fixtures_folder}/cycles.jsonld", encoding='utf-8') as f:
|
18
|
+
cycles = json.load(f)
|
19
|
+
|
20
|
+
mock_related_cycles.return_value = cycles
|
21
|
+
|
22
|
+
with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
|
23
|
+
expected = json.load(f)
|
24
|
+
|
25
|
+
value = run(site)
|
26
|
+
assert value == expected
|
@@ -1,57 +1,25 @@
|
|
1
|
-
|
1
|
+
import os
|
2
|
+
import pytest
|
3
|
+
from unittest.mock import Mock, patch
|
2
4
|
import json
|
3
5
|
from tests.utils import fixtures_path, fake_new_emission, FLOODED_RICE_TERMS
|
4
6
|
|
5
|
-
from hestia_earth.models.ipcc2019.ch4ToAirFloodedRice import MODEL, TERM_ID, run
|
7
|
+
from hestia_earth.models.ipcc2019.ch4ToAirFloodedRice import MODEL, TERM_ID, run
|
6
8
|
|
7
9
|
class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
|
8
10
|
fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
|
11
|
+
_folders = [d for d in os.listdir(fixtures_folder) if os.path.isdir(os.path.join(fixtures_folder, d))]
|
9
12
|
|
10
13
|
|
11
|
-
@
|
12
|
-
def test_should_run(mock_flooded_rice):
|
13
|
-
# no site => no run
|
14
|
-
cycle = {'site': {}}
|
15
|
-
should_run, *args = _should_run(cycle)
|
16
|
-
assert not should_run
|
17
|
-
|
18
|
-
# with site => no run
|
19
|
-
cycle['site'] = {'country': {'@id': 'country'}}
|
20
|
-
should_run, *args = _should_run(cycle)
|
21
|
-
assert not should_run
|
22
|
-
|
23
|
-
# with croppingDuration => no run
|
24
|
-
cycle['practices'] = [{'term': {'@id': 'croppingDuration'}}]
|
25
|
-
should_run, *args = _should_run(cycle)
|
26
|
-
assert not should_run
|
27
|
-
|
28
|
-
# with flooded rice => run
|
29
|
-
mock_flooded_rice.return_value = True
|
30
|
-
should_run, *args = _should_run(cycle)
|
31
|
-
assert should_run is True
|
32
|
-
|
33
|
-
|
34
|
-
@patch('hestia_earth.models.utils.product.get_rice_paddy_terms', return_value=FLOODED_RICE_TERMS)
|
35
|
-
@patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
|
36
|
-
def test_run(*args):
|
37
|
-
with open(f"{fixtures_folder}/cycle.jsonld", encoding="utf-8") as f:
|
38
|
-
cycle = json.load(f)
|
39
|
-
|
40
|
-
with open(f"{fixtures_folder}/result.jsonld", encoding="utf-8") as f:
|
41
|
-
expected = json.load(f)
|
42
|
-
|
43
|
-
result = run(cycle)
|
44
|
-
assert result == expected
|
45
|
-
|
46
|
-
|
14
|
+
@pytest.mark.parametrize("folder", _folders)
|
47
15
|
@patch('hestia_earth.models.utils.product.get_rice_paddy_terms', return_value=FLOODED_RICE_TERMS)
|
48
16
|
@patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
|
49
|
-
def
|
50
|
-
with open(f"{fixtures_folder}/
|
17
|
+
def test_run(mock_new_emission: Mock, mock_rice_terms: Mock, folder: str):
|
18
|
+
with open(f"{fixtures_folder}/{folder}/cycle.jsonld", encoding="utf-8") as f:
|
51
19
|
cycle = json.load(f)
|
52
20
|
|
53
|
-
with open(f"{fixtures_folder}/
|
21
|
+
with open(f"{fixtures_folder}/{folder}/result.jsonld", encoding="utf-8") as f:
|
54
22
|
expected = json.load(f)
|
55
23
|
|
56
24
|
result = run(cycle)
|
57
|
-
assert result == expected
|
25
|
+
assert result == expected, folder
|
@@ -66,7 +66,8 @@ RUN_SCENARIOS = [
|
|
66
66
|
("with-gapfilled-start-date-end-date", 1), # Closes issue #972
|
67
67
|
("forest-to-orchard-with-ground-cover", 3), # Closes issue #989
|
68
68
|
("orchard-data-complete", 3), # Closes issue #1011
|
69
|
-
("orchard-data-partially-complete", 3)
|
69
|
+
("orchard-data-partially-complete", 3), # Closes issue #1011
|
70
|
+
("with-linalgerror", 1)
|
70
71
|
]
|
71
72
|
"""List of (subfolder: str, num_cycles: int)."""
|
72
73
|
|
@@ -32,8 +32,9 @@ RUN_SCENARIOS = [
|
|
32
32
|
("forest-to-cropland", 4),
|
33
33
|
("historical-land-cover-mix", 3),
|
34
34
|
("deforestation-reforestation", 1), # gains should not offset losses
|
35
|
-
("no-clearance-via-fire", 1), # LUC in the UK, which has a percentage burned factor of 0
|
36
|
-
("forest-to-cropland-with-ground-cover", 4) # Cover crops/ground covers should be ignored
|
35
|
+
("no-clearance-via-fire", 1), # LUC in the UK, which has a percentage burned factor of 0, should run
|
36
|
+
("forest-to-cropland-with-ground-cover", 4), # Cover crops/ground covers should be ignored
|
37
|
+
("single-year", 1) # should not run, multiple years of land cover data required
|
37
38
|
]
|
38
39
|
|
39
40
|
|
@@ -6,15 +6,8 @@ from hestia_earth.models.emissionNotRelevant import MODEL, run
|
|
6
6
|
|
7
7
|
class_path = f"hestia_earth.models.{MODEL}"
|
8
8
|
fixtures_folder = f"{fixtures_path}/{MODEL}"
|
9
|
-
EMISSION_IDS = [
|
10
|
-
'ch4ToAirCropResidueBurning',
|
11
|
-
'ch4ToAirExcreta',
|
12
|
-
'ch4ToAirFuelCombustion',
|
13
|
-
'n2OToAirAquacultureSystemsDirect'
|
14
|
-
]
|
15
9
|
|
16
10
|
|
17
|
-
@patch(f"{class_path}.get_all_emission_terms", return_value=EMISSION_IDS)
|
18
11
|
@patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
|
19
12
|
def test_run_cropland(*args):
|
20
13
|
with open(f"{fixtures_folder}/cropland/cycle.jsonld", encoding='utf-8') as f:
|
@@ -27,7 +20,6 @@ def test_run_cropland(*args):
|
|
27
20
|
assert result == expected
|
28
21
|
|
29
22
|
|
30
|
-
@patch(f"{class_path}.get_all_emission_terms", return_value=EMISSION_IDS)
|
31
23
|
@patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
|
32
24
|
def test_run_pond(*args):
|
33
25
|
with open(f"{fixtures_folder}/pond/cycle.jsonld", encoding='utf-8') as f:
|
@@ -12,7 +12,7 @@ class_path = 'hestia_earth.models.utils.measurement'
|
|
12
12
|
fixtures_folder = f"{fixtures_path}/utils/measurement"
|
13
13
|
|
14
14
|
|
15
|
-
@patch(f"{class_path}.
|
15
|
+
@patch(f"{class_path}.include_method", side_effect=lambda n, **kwargs: n)
|
16
16
|
@patch(f"{class_path}.download_term", return_value=TERM)
|
17
17
|
def test_new_measurement(*args):
|
18
18
|
# with a Term as string
|
@@ -1,54 +0,0 @@
|
|
1
|
-
from hestia_earth.schema import TermTermType
|
2
|
-
from hestia_earth.utils.model import find_term_match
|
3
|
-
from hestia_earth.utils.tools import list_sum
|
4
|
-
|
5
|
-
from hestia_earth.models.log import logRequirements, logShouldRun
|
6
|
-
from hestia_earth.models.utils.completeness import _is_term_type_incomplete
|
7
|
-
from hestia_earth.models.utils.practice import _new_practice
|
8
|
-
from . import MODEL
|
9
|
-
|
10
|
-
REQUIREMENTS = {
|
11
|
-
"Cycle": {
|
12
|
-
"completeness.cropResidue": "False",
|
13
|
-
"products": [
|
14
|
-
{"@type": "Product", "term.@id": "aboveGroundCropResidueTotal", "value": "> 0"},
|
15
|
-
{"@type": "Product", "term.@id": "aboveGroundCropResidueRemoved", "value": "> 0"}
|
16
|
-
]
|
17
|
-
}
|
18
|
-
}
|
19
|
-
RETURNS = {
|
20
|
-
"Practice": [{
|
21
|
-
"value": ""
|
22
|
-
}]
|
23
|
-
}
|
24
|
-
TERM_ID = 'residueRemoved'
|
25
|
-
|
26
|
-
|
27
|
-
def _practice(value: float):
|
28
|
-
practice = _new_practice(TERM_ID)
|
29
|
-
practice['value'] = [value]
|
30
|
-
return practice
|
31
|
-
|
32
|
-
|
33
|
-
def _should_run(cycle: dict):
|
34
|
-
crop_residue_incomplete = _is_term_type_incomplete(cycle, TermTermType.CROPRESIDUE)
|
35
|
-
products = cycle.get('products', [])
|
36
|
-
aboveGroundCropResidueTotal = list_sum(find_term_match(products, 'aboveGroundCropResidueTotal').get('value', [0]))
|
37
|
-
has_aboveGroundCropResidueTotal = aboveGroundCropResidueTotal > 0
|
38
|
-
aboveGroundCropResidueRemoved = list_sum(
|
39
|
-
find_term_match(products, 'aboveGroundCropResidueRemoved').get('value', [0]))
|
40
|
-
has_aboveGroundCropResidueRemoved = aboveGroundCropResidueRemoved > 0
|
41
|
-
|
42
|
-
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
43
|
-
term_type_cropResidue_incomplete=crop_residue_incomplete,
|
44
|
-
has_aboveGroundCropResidueTotal=has_aboveGroundCropResidueTotal,
|
45
|
-
has_aboveGroundCropResidueRemoved=has_aboveGroundCropResidueRemoved)
|
46
|
-
|
47
|
-
should_run = all([crop_residue_incomplete, has_aboveGroundCropResidueTotal, has_aboveGroundCropResidueRemoved])
|
48
|
-
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
49
|
-
return should_run, aboveGroundCropResidueTotal, aboveGroundCropResidueRemoved
|
50
|
-
|
51
|
-
|
52
|
-
def run(cycle: dict):
|
53
|
-
should_run, total, value = _should_run(cycle)
|
54
|
-
return [_practice(value / total * 100)] if should_run else []
|
@@ -1,64 +0,0 @@
|
|
1
|
-
from hestia_earth.schema import TermTermType, EmissionMethodTier
|
2
|
-
from hestia_earth.models.utils.emission import _new_emission
|
3
|
-
from hestia_earth.utils.model import filter_list_term_type
|
4
|
-
from hestia_earth.models.utils.aquacultureManagement import valid_site_type
|
5
|
-
from hestia_earth.models.utils.input import total_excreta_tan
|
6
|
-
from . import MODEL
|
7
|
-
|
8
|
-
|
9
|
-
REQUIREMENTS = {
|
10
|
-
"Cycle": {
|
11
|
-
"products": [{
|
12
|
-
"@type": "Product",
|
13
|
-
"term.termType": "excreta",
|
14
|
-
"term.@id": "excretaLiquidFishCrustaceansKgN"
|
15
|
-
}]
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
|
-
RETURNS = {
|
20
|
-
"Emission": [{
|
21
|
-
"value": "",
|
22
|
-
"methodTier": "tier 1"
|
23
|
-
}]
|
24
|
-
}
|
25
|
-
|
26
|
-
TIER = EmissionMethodTier.TIER_1.value
|
27
|
-
TERM_ID = 'nh3ToSurfaceWaterAquacultureSystems'
|
28
|
-
_EXCRETA_TERM_ID = 'excretaLiquidFishCrustaceansKgN'
|
29
|
-
|
30
|
-
|
31
|
-
def _emission(value: float):
|
32
|
-
emission = _new_emission(TERM_ID, MODEL)
|
33
|
-
emission['value'] = [round(value, 7)]
|
34
|
-
emission['methodTier'] = TIER
|
35
|
-
return emission
|
36
|
-
|
37
|
-
|
38
|
-
def _run(excreta_products: list):
|
39
|
-
value = total_excreta_tan(excreta_products)
|
40
|
-
return [_emission(value)]
|
41
|
-
|
42
|
-
|
43
|
-
def _valid_excreta(cycle: dict):
|
44
|
-
excreta_products = filter_list_term_type(cycle.get('products', []), TermTermType.EXCRETA.value)
|
45
|
-
valid_excreta_products = [
|
46
|
-
product for product in excreta_products if all([
|
47
|
-
product.get('term', {}).get('@id') == _EXCRETA_TERM_ID
|
48
|
-
])
|
49
|
-
]
|
50
|
-
return valid_excreta_products
|
51
|
-
|
52
|
-
|
53
|
-
def _should_run(cycle: dict):
|
54
|
-
valid_excreta_products = _valid_excreta(cycle)
|
55
|
-
should_run = all([
|
56
|
-
valid_site_type(cycle),
|
57
|
-
bool(valid_excreta_products),
|
58
|
-
])
|
59
|
-
return should_run, valid_excreta_products
|
60
|
-
|
61
|
-
|
62
|
-
def run(cycle: dict):
|
63
|
-
should_run, valid_excreta_products = _should_run(cycle)
|
64
|
-
return _run(valid_excreta_products) if should_run else []
|
@@ -1,93 +0,0 @@
|
|
1
|
-
from functools import reduce
|
2
|
-
from hestia_earth.schema import TermTermType
|
3
|
-
from hestia_earth.utils.tools import non_empty_list
|
4
|
-
from hestia_earth.utils.date import DAY
|
5
|
-
|
6
|
-
from hestia_earth.models.utils import _omit, first_day_of_month, last_day_of_month
|
7
|
-
from hestia_earth.models.utils.measurement import _new_measurement, measurement_value, has_all_months
|
8
|
-
|
9
|
-
|
10
|
-
def copy_measurement(term_id: str, data: dict):
|
11
|
-
measurement = _new_measurement(term_id)
|
12
|
-
return {
|
13
|
-
**_omit(data, ['description', 'methodModel']),
|
14
|
-
**measurement
|
15
|
-
}
|
16
|
-
|
17
|
-
|
18
|
-
def _value_func(data: dict, apply_func, key: str = 'value'):
|
19
|
-
values = data.get(key, data.get('value', []))
|
20
|
-
return list(map(apply_func, values))
|
21
|
-
|
22
|
-
|
23
|
-
def _slice_by_year(term_id: str, dates: list, values: list):
|
24
|
-
def group_values(group: dict, index: int):
|
25
|
-
try:
|
26
|
-
date = dates[index]
|
27
|
-
value = values[index]
|
28
|
-
month = dates[index][0:4]
|
29
|
-
group[month] = group.get(month, []) + [(date, value)]
|
30
|
-
except IndexError:
|
31
|
-
pass
|
32
|
-
return group
|
33
|
-
|
34
|
-
def iterate_values(data: list):
|
35
|
-
return (
|
36
|
-
measurement_value({
|
37
|
-
'term': {
|
38
|
-
'@id': term_id,
|
39
|
-
'termType': TermTermType.MEASUREMENT.value
|
40
|
-
},
|
41
|
-
'value': non_empty_list([v for (_d, v) in data])
|
42
|
-
}, is_larger_unit=True),
|
43
|
-
data[0][0],
|
44
|
-
data[-1][0]
|
45
|
-
) if has_all_months([d for (d, _v) in data]) else None
|
46
|
-
|
47
|
-
values_by_month = reduce(group_values, range(0, len(dates)), {})
|
48
|
-
return non_empty_list(map(iterate_values, values_by_month.values()))
|
49
|
-
|
50
|
-
|
51
|
-
def _extract_year_month(date: str):
|
52
|
-
try:
|
53
|
-
year = int(date[0:4])
|
54
|
-
month = int(date[5:7])
|
55
|
-
return year, month
|
56
|
-
except Exception:
|
57
|
-
return None, None
|
58
|
-
|
59
|
-
|
60
|
-
def _group_by_month(term_id: str, dates: list, values: list):
|
61
|
-
def group_values(group: dict, index: int):
|
62
|
-
date = dates[index]
|
63
|
-
value = values[index]
|
64
|
-
month = dates[index][0:7]
|
65
|
-
group[month] = group.get(month, []) + [(date, value)]
|
66
|
-
return group
|
67
|
-
|
68
|
-
def map_to_month(data: list, year: int, month: int):
|
69
|
-
# make sure we got all the necessary days
|
70
|
-
difference = last_day_of_month(year, month) - first_day_of_month(year, month)
|
71
|
-
days_in_month = round(difference.days + difference.seconds / DAY, 1) + 1
|
72
|
-
|
73
|
-
return measurement_value({
|
74
|
-
'term': {
|
75
|
-
'@id': term_id,
|
76
|
-
'termType': TermTermType.MEASUREMENT.value
|
77
|
-
},
|
78
|
-
'value': non_empty_list([v for (_d, v) in data])
|
79
|
-
}, is_larger_unit=True) if len(data) == days_in_month else None
|
80
|
-
|
81
|
-
values_by_month = reduce(group_values, range(0, len(dates)), {}) if len(dates) == len(values) else {}
|
82
|
-
|
83
|
-
values = []
|
84
|
-
dates = []
|
85
|
-
for month, data in values_by_month.items():
|
86
|
-
year, m = _extract_year_month(data[0][0])
|
87
|
-
# date might not contain a year or a month, cannot handle it
|
88
|
-
value = map_to_month(data, year, m) if year and m else None
|
89
|
-
if value is not None:
|
90
|
-
dates.append(month)
|
91
|
-
values.append(value)
|
92
|
-
|
93
|
-
return values, dates
|
@@ -1,37 +0,0 @@
|
|
1
|
-
from unittest.mock import patch
|
2
|
-
import json
|
3
|
-
from tests.utils import fake_new_practice, fixtures_path
|
4
|
-
|
5
|
-
from hestia_earth.models.cycle.residueRemoved import MODEL, TERM_ID, _should_run, run
|
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
|
-
# no products => no run
|
13
|
-
cycle = {'completeness': {'cropResidue': False}, 'products': []}
|
14
|
-
should_run, *args = _should_run(cycle)
|
15
|
-
assert not should_run
|
16
|
-
|
17
|
-
# with `aboveGroundCropResidueTotal` => no run
|
18
|
-
cycle['products'].append({'term': {'@id': 'aboveGroundCropResidueTotal'}, 'value': [10]})
|
19
|
-
should_run, *args = _should_run(cycle)
|
20
|
-
assert not should_run
|
21
|
-
|
22
|
-
# with `aboveGroundCropResidueRemoved` => run
|
23
|
-
cycle['products'].append({'term': {'@id': 'aboveGroundCropResidueRemoved'}, 'value': [10]})
|
24
|
-
should_run, *args = _should_run(cycle)
|
25
|
-
assert should_run is True
|
26
|
-
|
27
|
-
|
28
|
-
@patch(f"{class_path}._new_practice", side_effect=fake_new_practice)
|
29
|
-
def test_run(*args):
|
30
|
-
with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
|
31
|
-
data = json.load(f)
|
32
|
-
|
33
|
-
with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
|
34
|
-
expected = json.load(f)
|
35
|
-
|
36
|
-
result = run(data)
|
37
|
-
assert result == expected
|
@@ -1,51 +0,0 @@
|
|
1
|
-
from unittest.mock import patch
|
2
|
-
import json
|
3
|
-
from tests.utils import fixtures_path, fake_new_emission
|
4
|
-
|
5
|
-
from hestia_earth.models.hestia.nh3ToSurfaceWaterAquacultureSystems import MODEL, TERM_ID, run, _should_run
|
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}.valid_site_type", return_value=True)
|
12
|
-
def test_should_run(mock_valid_excreta, *args):
|
13
|
-
cycle = {}
|
14
|
-
should_run, *args = _should_run(cycle)
|
15
|
-
assert not should_run
|
16
|
-
|
17
|
-
# without the right type of excreta => no run
|
18
|
-
cycle['products'] = [
|
19
|
-
{
|
20
|
-
'term': {
|
21
|
-
'@id': 'excretaSolidFishCrustaceansKgN',
|
22
|
-
'termType': 'excreta'
|
23
|
-
}
|
24
|
-
}
|
25
|
-
]
|
26
|
-
should_run, *args = _should_run(cycle)
|
27
|
-
assert not should_run
|
28
|
-
|
29
|
-
# with fish_excreta_tan => run
|
30
|
-
cycle['products'] = [
|
31
|
-
{
|
32
|
-
'term': {
|
33
|
-
'@id': 'excretaLiquidFishCrustaceansKgN',
|
34
|
-
'termType': 'excreta'
|
35
|
-
}
|
36
|
-
}
|
37
|
-
]
|
38
|
-
should_run, *args = _should_run(cycle)
|
39
|
-
assert should_run is True
|
40
|
-
|
41
|
-
|
42
|
-
@patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
|
43
|
-
def test_run(*args):
|
44
|
-
with open(f"{fixtures_folder}/cycle.jsonld", encoding="utf-8") as f:
|
45
|
-
cycle = json.load(f)
|
46
|
-
|
47
|
-
with open(f"{fixtures_folder}/result.jsonld", encoding="utf-8") as f:
|
48
|
-
expected = json.load(f)
|
49
|
-
|
50
|
-
value = run(cycle)
|
51
|
-
assert value == expected
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|