hestia-earth-models 0.70.0__py3-none-any.whl → 0.70.2__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/cml2001Baseline/resourceUseMineralsAndMetalsDuringCycle.py +2 -1
- hestia_earth/models/config/Cycle.json +98 -50
- hestia_earth/models/config/ImpactAssessment.json +12 -4
- hestia_earth/models/config/Site.json +40 -21
- 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 +8 -3
- 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/{site → hestia}/management.py +4 -6
- 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/hestia/pToSurfaceWaterAquacultureSystems.py +148 -0
- 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 +166 -79
- hestia_earth/models/ipcc2019/ch4ToAirOrganicSoilCultivation.py +270 -0
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +0 -3
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +0 -3
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +88 -63
- hestia_earth/models/ipcc2019/co2ToAirLimeHydrolysis.py +7 -5
- hestia_earth/models/ipcc2019/co2ToAirOrganicSoilCultivation.py +215 -0
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +0 -3
- hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +16 -9
- hestia_earth/models/ipcc2019/n2OToAirOrganicSoilCultivationDirect.py +161 -0
- 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/ipcc2019/organicSoilCultivation_utils.py +159 -0
- hestia_earth/models/mocking/search-results.json +1113 -1113
- 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/site/grouped_measurement.py +132 -0
- hestia_earth/models/utils/__init__.py +4 -3
- hestia_earth/models/utils/background_emissions.py +52 -0
- hestia_earth/models/utils/blank_node.py +47 -14
- hestia_earth/models/utils/constant.py +26 -20
- 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/utils/product.py +39 -1
- hestia_earth/models/utils/property.py +14 -6
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/RECORD +187 -171
- 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 +3 -4
- 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/hestia/test_pToSurfaceWaterAquacultureSystems.py +56 -0
- 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 +13 -21
- 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_ch4ToAirEntericFermentation.py +2 -5
- tests/models/ipcc2019/test_ch4ToAirFloodedRice.py +10 -42
- tests/models/ipcc2019/test_ch4ToAirOrganicSoilCultivation.py +61 -0
- tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +11 -9
- tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +10 -8
- tests/models/ipcc2019/test_co2ToAirLimeHydrolysis.py +1 -1
- tests/models/ipcc2019/test_co2ToAirOrganicSoilCultivation.py +62 -0
- tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +11 -8
- tests/models/ipcc2019/test_n2OToAirOrganicSoilCultivationDirect.py +61 -0
- tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +3 -2
- tests/models/site/test_grouped_measurement.py +20 -0
- 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}/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.2.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.70.0.dist-info → hestia_earth_models-0.70.2.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@ from hestia_earth.utils.tools import flatten, non_empty_list
|
|
3
3
|
|
4
4
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
5
5
|
from hestia_earth.models.utils.measurement import _new_measurement
|
6
|
-
from .utils import
|
6
|
+
from .utils import slice_by_year
|
7
7
|
from . import MODEL
|
8
8
|
|
9
9
|
REQUIREMENTS = {
|
@@ -26,7 +26,7 @@ MEASUREMENT_ID = 'rainfallMonthly'
|
|
26
26
|
|
27
27
|
|
28
28
|
def _measurement(value: float, start_date: str, end_date: str):
|
29
|
-
data = _new_measurement(TERM_ID)
|
29
|
+
data = _new_measurement(TERM_ID, MODEL)
|
30
30
|
data['value'] = [value]
|
31
31
|
data['startDate'] = start_date
|
32
32
|
data['endDate'] = end_date
|
@@ -38,7 +38,7 @@ def _run(measurement: dict):
|
|
38
38
|
values = measurement.get('value', [])
|
39
39
|
dates = measurement.get('dates', [])
|
40
40
|
term_id = measurement.get('term', {}).get('@id')
|
41
|
-
results =
|
41
|
+
results = slice_by_year(term_id, dates, values)
|
42
42
|
return [_measurement(value, start_date, end_date) for (value, start_date, end_date) in results]
|
43
43
|
|
44
44
|
|
@@ -3,7 +3,7 @@ from hestia_earth.utils.tools import flatten, non_empty_list
|
|
3
3
|
|
4
4
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
5
5
|
from hestia_earth.models.utils.measurement import _new_measurement
|
6
|
-
from .utils import
|
6
|
+
from .utils import group_by_month
|
7
7
|
from . import MODEL
|
8
8
|
|
9
9
|
REQUIREMENTS = {
|
@@ -25,7 +25,7 @@ MEASUREMENT_ID = 'rainfallDaily'
|
|
25
25
|
|
26
26
|
|
27
27
|
def _measurement(value: list, dates: list):
|
28
|
-
data = _new_measurement(TERM_ID)
|
28
|
+
data = _new_measurement(TERM_ID, MODEL)
|
29
29
|
data['value'] = value
|
30
30
|
data['dates'] = dates
|
31
31
|
data['methodClassification'] = MeasurementMethodClassification.MODELLED_USING_OTHER_MEASUREMENTS.value
|
@@ -36,7 +36,7 @@ def _run(measurement: dict):
|
|
36
36
|
values = measurement.get('value', [])
|
37
37
|
dates = measurement.get('dates', [])
|
38
38
|
term_id = measurement.get('term', {}).get('@id')
|
39
|
-
result =
|
39
|
+
result = group_by_month(term_id, dates, values)
|
40
40
|
return _measurement(result[0], result[1]) if len(result[0]) > 0 else None
|
41
41
|
|
42
42
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from hestia_earth.schema import TermTermType
|
2
|
-
from hestia_earth.utils.model import filter_list_term_type
|
2
|
+
from hestia_earth.utils.model import filter_list_term_type, find_term_match
|
3
3
|
from hestia_earth.utils.tools import list_sum
|
4
4
|
|
5
5
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
@@ -11,14 +11,20 @@ from . import MODEL
|
|
11
11
|
REQUIREMENTS = {
|
12
12
|
"Cycle": {
|
13
13
|
"completeness.cropResidue": "False",
|
14
|
-
"
|
15
|
-
"
|
16
|
-
|
17
|
-
"
|
18
|
-
|
19
|
-
|
14
|
+
"or": {
|
15
|
+
"practices": [{
|
16
|
+
"@type": "Practice",
|
17
|
+
"term.@id": [
|
18
|
+
"residueIncorporated",
|
19
|
+
"residueIncorporatedLessThan30DaysBeforeCultivation",
|
20
|
+
"residueIncorporatedMoreThan30DaysBeforeCultivation"
|
21
|
+
]
|
22
|
+
}],
|
23
|
+
"products": [
|
24
|
+
{"@type": "Product", "term.@id": "aboveGroundCropResidueTotal", "value": "> 0"},
|
25
|
+
{"@type": "Product", "term.@id": "aboveGroundCropResidueRemoved", "value": "> 0"}
|
20
26
|
]
|
21
|
-
}
|
27
|
+
},
|
22
28
|
"none": {
|
23
29
|
"practices": [{
|
24
30
|
"@type": "Practice",
|
@@ -45,14 +51,57 @@ def _practice(value: float):
|
|
45
51
|
return practice
|
46
52
|
|
47
53
|
|
48
|
-
def
|
54
|
+
def _run_by_products(cycle: dict):
|
55
|
+
products = cycle.get('products', [])
|
56
|
+
aboveGroundCropResidueTotal = list_sum(find_term_match(products, 'aboveGroundCropResidueTotal').get('value'))
|
57
|
+
aboveGroundCropResidueRemoved = list_sum(find_term_match(products, 'aboveGroundCropResidueRemoved').get('value'))
|
58
|
+
return [_practice(aboveGroundCropResidueRemoved / aboveGroundCropResidueTotal * 100)]
|
59
|
+
|
60
|
+
|
61
|
+
def _should_run_by_products(cycle: dict):
|
62
|
+
crop_residue_incomplete = _is_term_type_incomplete(cycle, TermTermType.CROPRESIDUE)
|
63
|
+
products = cycle.get('products', [])
|
64
|
+
aboveGroundCropResidueTotal = list_sum(find_term_match(products, 'aboveGroundCropResidueTotal').get('value', [0]))
|
65
|
+
has_aboveGroundCropResidueTotal = aboveGroundCropResidueTotal > 0
|
66
|
+
aboveGroundCropResidueRemoved = list_sum(
|
67
|
+
find_term_match(products, 'aboveGroundCropResidueRemoved').get('value', [0]))
|
68
|
+
has_aboveGroundCropResidueRemoved = aboveGroundCropResidueRemoved > 0
|
69
|
+
|
70
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
71
|
+
term_type_cropResidue_incomplete=crop_residue_incomplete,
|
72
|
+
has_aboveGroundCropResidueTotal=has_aboveGroundCropResidueTotal,
|
73
|
+
has_aboveGroundCropResidueRemoved=has_aboveGroundCropResidueRemoved)
|
74
|
+
|
75
|
+
should_run = all([crop_residue_incomplete, has_aboveGroundCropResidueTotal, has_aboveGroundCropResidueRemoved])
|
76
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
77
|
+
return should_run
|
78
|
+
|
79
|
+
|
80
|
+
def _is_incorporated_practice(practice: dict):
|
81
|
+
return all([
|
82
|
+
practice.get('term', {}).get('@id').startswith('residueIncorporated'),
|
83
|
+
practice.get('term', {}).get('termType') == TermTermType.CROPRESIDUEMANAGEMENT.value,
|
84
|
+
not is_from_model(practice)
|
85
|
+
])
|
86
|
+
|
87
|
+
|
88
|
+
def _run_by_practices(cycle: dict):
|
89
|
+
incorporated_value = list_sum([
|
90
|
+
list_sum(p.get('value'))
|
91
|
+
for p in cycle.get('practices', [])
|
92
|
+
if _is_incorporated_practice(p)
|
93
|
+
])
|
94
|
+
return [_practice(100 - (incorporated_value or 0))]
|
95
|
+
|
96
|
+
|
97
|
+
def _should_run_by_practices(cycle: dict):
|
49
98
|
crop_residue_incomplete = _is_term_type_incomplete(cycle, TermTermType.CROPRESIDUE)
|
50
99
|
|
51
100
|
practices = filter_list_term_type(cycle.get('practices', []), TermTermType.CROPRESIDUEMANAGEMENT)
|
52
101
|
incorporated_practices = [
|
53
102
|
{'id': p.get('term', {}).get('@id'), 'value': list_sum(p.get('value'), None)}
|
54
103
|
for p in practices
|
55
|
-
if
|
104
|
+
if _is_incorporated_practice(p)
|
56
105
|
]
|
57
106
|
has_other_practices = any([
|
58
107
|
not p.get('term', {}).get('@id').startswith('residueIncorporated')
|
@@ -68,9 +117,12 @@ def _should_run(cycle: dict):
|
|
68
117
|
|
69
118
|
should_run = all([crop_residue_incomplete, incorporated_value, not has_other_practices])
|
70
119
|
logShouldRun(cycle, MODEL, TERM_ID, should_run)
|
71
|
-
return should_run
|
120
|
+
return should_run
|
72
121
|
|
73
122
|
|
74
123
|
def run(cycle: dict):
|
75
|
-
|
76
|
-
|
124
|
+
return (
|
125
|
+
_run_by_products(cycle) if _should_run_by_products(cycle) else
|
126
|
+
_run_by_practices(cycle) if _should_run_by_practices(cycle) else
|
127
|
+
[]
|
128
|
+
)
|
@@ -22,7 +22,7 @@ TERM_ID = 'salineWater'
|
|
22
22
|
|
23
23
|
|
24
24
|
def _measurement():
|
25
|
-
data = _new_measurement(TERM_ID)
|
25
|
+
data = _new_measurement(TERM_ID, MODEL)
|
26
26
|
data['value'] = [True]
|
27
27
|
data['methodClassification'] = MeasurementMethodClassification.MODELLED_USING_OTHER_MEASUREMENTS.value
|
28
28
|
return data
|
@@ -32,7 +32,7 @@ STANDARD_DEPTHS = {(0, 30), (0, 50)}
|
|
32
32
|
|
33
33
|
|
34
34
|
def _measurement(value: float, date: str, term_id: str, standard_fields: dict):
|
35
|
-
data = _new_measurement(
|
35
|
+
data = _new_measurement(term_id, MODEL)
|
36
36
|
data["value"] = [value]
|
37
37
|
data["depthUpper"] = standard_fields["depthUpper"]
|
38
38
|
data["depthLower"] = standard_fields["depthLower"]
|
@@ -3,7 +3,7 @@ from hestia_earth.utils.tools import flatten, non_empty_list
|
|
3
3
|
|
4
4
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
5
5
|
from hestia_earth.models.utils.measurement import _new_measurement
|
6
|
-
from .utils import
|
6
|
+
from .utils import slice_by_year
|
7
7
|
from . import MODEL
|
8
8
|
|
9
9
|
REQUIREMENTS = {
|
@@ -26,7 +26,7 @@ MEASUREMENT_ID = 'temperatureMonthly'
|
|
26
26
|
|
27
27
|
|
28
28
|
def _measurement(value: float, start_date: str, end_date: str):
|
29
|
-
data = _new_measurement(TERM_ID)
|
29
|
+
data = _new_measurement(TERM_ID, MODEL)
|
30
30
|
data['value'] = [value]
|
31
31
|
data['startDate'] = start_date
|
32
32
|
data['endDate'] = end_date
|
@@ -38,7 +38,7 @@ def _run(measurement: dict):
|
|
38
38
|
values = measurement.get('value', [])
|
39
39
|
dates = measurement.get('dates', [])
|
40
40
|
term_id = measurement.get('term', {}).get('@id')
|
41
|
-
results =
|
41
|
+
results = slice_by_year(term_id, dates, values)
|
42
42
|
return [_measurement(value, start_date, end_date) for (value, start_date, end_date) in results]
|
43
43
|
|
44
44
|
|
@@ -3,7 +3,7 @@ from hestia_earth.utils.tools import flatten, non_empty_list
|
|
3
3
|
|
4
4
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
5
5
|
from hestia_earth.models.utils.measurement import _new_measurement
|
6
|
-
from .utils import
|
6
|
+
from .utils import group_by_month
|
7
7
|
from . import MODEL
|
8
8
|
|
9
9
|
REQUIREMENTS = {
|
@@ -25,7 +25,7 @@ MEASUREMENT_ID = 'temperatureDaily'
|
|
25
25
|
|
26
26
|
|
27
27
|
def _measurement(value: list, dates: list):
|
28
|
-
data = _new_measurement(TERM_ID)
|
28
|
+
data = _new_measurement(TERM_ID, MODEL)
|
29
29
|
data['value'] = value
|
30
30
|
data['dates'] = dates
|
31
31
|
data['methodClassification'] = MeasurementMethodClassification.MODELLED_USING_OTHER_MEASUREMENTS.value
|
@@ -36,7 +36,7 @@ def _run(measurement: dict):
|
|
36
36
|
values = measurement.get('value', [])
|
37
37
|
dates = measurement.get('dates', [])
|
38
38
|
term_id = measurement.get('term', {}).get('@id')
|
39
|
-
result =
|
39
|
+
result = group_by_month(term_id, dates, values)
|
40
40
|
return _measurement(result[0], result[1]) if len(result[0]) > 0 else None
|
41
41
|
|
42
42
|
|
@@ -25,7 +25,7 @@ BIBLIO_TITLE = 'Reducing food’s environmental impacts through producers and co
|
|
25
25
|
|
26
26
|
|
27
27
|
def _measurement(site: dict, value: float):
|
28
|
-
data = _new_measurement(TERM_ID)
|
28
|
+
data = _new_measurement(TERM_ID, MODEL)
|
29
29
|
data['value'] = [value]
|
30
30
|
data['depthUpper'] = 0
|
31
31
|
data['depthLower'] = 50
|
@@ -1,6 +1,11 @@
|
|
1
|
+
from functools import reduce
|
1
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
|
2
5
|
|
6
|
+
from hestia_earth.models.utils import _omit, first_day_of_month, last_day_of_month
|
3
7
|
from hestia_earth.models.utils.term import get_lookup_value
|
8
|
+
from hestia_earth.models.utils.measurement import _new_measurement, measurement_value, has_all_months
|
4
9
|
from . import MODEL
|
5
10
|
|
6
11
|
IPCC_LAND_USE_CATEGORY_ANNUAL = "Annual crops"
|
@@ -45,3 +50,91 @@ def crop_ipcc_land_use_category(
|
|
45
50
|
column='IPCC_LAND_USE_CATEGORY',
|
46
51
|
model=MODEL
|
47
52
|
)
|
53
|
+
|
54
|
+
|
55
|
+
def get_liveAnimal_term_id(product: dict, **log_ars):
|
56
|
+
term_id = get_lookup_value(product.get('term', {}), 'liveAnimalTermId', model=MODEL, **log_ars)
|
57
|
+
return term_id.split(';')[0] if term_id else None
|
58
|
+
|
59
|
+
|
60
|
+
def _value_func(data: dict, apply_func, key: str = 'value'):
|
61
|
+
values = data.get(key, data.get('value', []))
|
62
|
+
return list(map(apply_func, values))
|
63
|
+
|
64
|
+
|
65
|
+
def copy_measurement(term_id: str, data: dict):
|
66
|
+
measurement = _new_measurement(term_id, MODEL)
|
67
|
+
return _omit(data, ['description', 'method']) | measurement
|
68
|
+
|
69
|
+
|
70
|
+
def slice_by_year(term_id: str, dates: list, values: list):
|
71
|
+
def group_values(group: dict, index: int):
|
72
|
+
try:
|
73
|
+
date = dates[index]
|
74
|
+
value = values[index]
|
75
|
+
month = dates[index][0:4]
|
76
|
+
group[month] = group.get(month, []) + [(date, value)]
|
77
|
+
except IndexError:
|
78
|
+
pass
|
79
|
+
return group
|
80
|
+
|
81
|
+
def iterate_values(data: list):
|
82
|
+
return (
|
83
|
+
measurement_value({
|
84
|
+
'term': {
|
85
|
+
'@id': term_id,
|
86
|
+
'termType': TermTermType.MEASUREMENT.value
|
87
|
+
},
|
88
|
+
'value': non_empty_list([v for (_d, v) in data])
|
89
|
+
}, is_larger_unit=True),
|
90
|
+
data[0][0],
|
91
|
+
data[-1][0]
|
92
|
+
) if has_all_months([d for (d, _v) in data]) else None
|
93
|
+
|
94
|
+
values_by_month = reduce(group_values, range(0, len(dates)), {})
|
95
|
+
return non_empty_list(map(iterate_values, values_by_month.values()))
|
96
|
+
|
97
|
+
|
98
|
+
def _extract_year_month(date: str):
|
99
|
+
try:
|
100
|
+
year = int(date[0:4])
|
101
|
+
month = int(date[5:7])
|
102
|
+
return year, month
|
103
|
+
except Exception:
|
104
|
+
return None, None
|
105
|
+
|
106
|
+
|
107
|
+
def group_by_month(term_id: str, dates: list, values: list):
|
108
|
+
def group_values(group: dict, index: int):
|
109
|
+
date = dates[index]
|
110
|
+
value = values[index]
|
111
|
+
month = dates[index][0:7]
|
112
|
+
group[month] = group.get(month, []) + [(date, value)]
|
113
|
+
return group
|
114
|
+
|
115
|
+
def map_to_month(data: list, year: int, month: int):
|
116
|
+
# make sure we got all the necessary days
|
117
|
+
difference = last_day_of_month(year, month) - first_day_of_month(year, month)
|
118
|
+
days_in_month = round(difference.days + difference.seconds / DAY, 1) + 1
|
119
|
+
|
120
|
+
return measurement_value({
|
121
|
+
'term': {
|
122
|
+
'@id': term_id,
|
123
|
+
'termType': TermTermType.MEASUREMENT.value
|
124
|
+
},
|
125
|
+
'value': non_empty_list([v for (_d, v) in data])
|
126
|
+
}, is_larger_unit=True) if len(data) == days_in_month else None
|
127
|
+
|
128
|
+
values_by_month = reduce(group_values, range(0, len(dates)), {}) if len(dates) == len(values) else {}
|
129
|
+
|
130
|
+
values = []
|
131
|
+
dates = []
|
132
|
+
for month, data in values_by_month.items():
|
133
|
+
year, m = _extract_year_month(data[0][0])
|
134
|
+
# date might not contain a year or a month, cannot handle it
|
135
|
+
value = map_to_month(data, year, m) if year and m else None
|
136
|
+
if value is not None:
|
137
|
+
dates.append(month)
|
138
|
+
values.append(value)
|
139
|
+
|
140
|
+
return values, dates
|
@@ -25,7 +25,7 @@ SITE_TYPE_TO_DEPTH = {
|
|
25
25
|
|
26
26
|
|
27
27
|
def _measurement(site: dict, value: float):
|
28
|
-
data = _new_measurement(TERM_ID)
|
28
|
+
data = _new_measurement(TERM_ID, MODEL)
|
29
29
|
data['value'] = [value]
|
30
30
|
data['methodClassification'] = MeasurementMethodClassification.MODELLED_USING_OTHER_MEASUREMENTS.value
|
31
31
|
return data | get_source(site, BIBLIO_TITLE)
|
@@ -0,0 +1,78 @@
|
|
1
|
+
from hestia_earth.schema import MeasurementMethodClassification, TermTermType
|
2
|
+
from hestia_earth.utils.model import filter_list_term_type
|
3
|
+
from hestia_earth.utils.tools import safe_parse_float
|
4
|
+
|
5
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
6
|
+
from hestia_earth.models.utils.measurement import _new_measurement
|
7
|
+
from hestia_earth.models.utils.site import related_cycles
|
8
|
+
from hestia_earth.models.utils.blank_node import get_lookup_value
|
9
|
+
from . import MODEL
|
10
|
+
|
11
|
+
REQUIREMENTS = {
|
12
|
+
"Site": {
|
13
|
+
"related": {
|
14
|
+
"Cycle": {
|
15
|
+
"@type": "Cycle",
|
16
|
+
"products": [{
|
17
|
+
"@type": "Product",
|
18
|
+
"primary": "True",
|
19
|
+
"term.termType": "liveAquaticSpecies"
|
20
|
+
}]
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
RETURNS = {
|
26
|
+
"Measurement": [{
|
27
|
+
"value": "",
|
28
|
+
"startDate": "",
|
29
|
+
"endDate": "",
|
30
|
+
"methodClassification": "expert opinion"
|
31
|
+
}]
|
32
|
+
}
|
33
|
+
LOOKUPS = {
|
34
|
+
"liveAquaticSpecies": "defaultSalinity"
|
35
|
+
}
|
36
|
+
TERM_ID = 'waterSalinity'
|
37
|
+
|
38
|
+
|
39
|
+
def _measurement(value: float, start_date: str = None, end_date: str = None):
|
40
|
+
data = _new_measurement(TERM_ID, MODEL)
|
41
|
+
data['value'] = [value]
|
42
|
+
data['endDate'] = end_date
|
43
|
+
if start_date:
|
44
|
+
data['startDate'] = start_date
|
45
|
+
data['methodClassification'] = MeasurementMethodClassification.EXPERT_OPINION.value
|
46
|
+
return data
|
47
|
+
|
48
|
+
|
49
|
+
def _should_run(site: dict):
|
50
|
+
cycles = related_cycles(site)
|
51
|
+
relevant_products = [
|
52
|
+
{
|
53
|
+
'product-id': product.get('term', {}).get('@id'),
|
54
|
+
'lookup-value': safe_parse_float(
|
55
|
+
get_lookup_value(product.get('term', {}), LOOKUPS['liveAquaticSpecies']), default=None
|
56
|
+
),
|
57
|
+
'start-date': product.get('startDate') or cycle.get('startDate'),
|
58
|
+
'end-date': product.get('endDate') or cycle.get('endDate')
|
59
|
+
}
|
60
|
+
for cycle in cycles
|
61
|
+
for product in filter_list_term_type(cycle.get('products', []), TermTermType.LIVEAQUATICSPECIES)
|
62
|
+
]
|
63
|
+
has_valid_products = any([product.get('lookup-value') for product in relevant_products])
|
64
|
+
|
65
|
+
logRequirements(site, model=MODEL, term=TERM_ID,
|
66
|
+
live_aquatic_products=log_as_table(relevant_products))
|
67
|
+
|
68
|
+
should_run = all([has_valid_products])
|
69
|
+
logShouldRun(site, MODEL, TERM_ID, should_run)
|
70
|
+
return should_run, relevant_products
|
71
|
+
|
72
|
+
|
73
|
+
def run(site: dict):
|
74
|
+
should_run, values = _should_run(site)
|
75
|
+
return [
|
76
|
+
_measurement(value.get('lookup-value'), value.get('start-date'), value.get('end-date'))
|
77
|
+
for value in values if value.get('lookup-value') is not None
|
78
|
+
] if should_run else []
|
@@ -568,7 +568,7 @@ def _measurement(
|
|
568
568
|
"dates": [f"{year}-12-31" for year in timestamps],
|
569
569
|
"methodClassification": _METHOD_CLASSIFICATION
|
570
570
|
}
|
571
|
-
measurement = _new_measurement(TERM_ID) | {
|
571
|
+
measurement = _new_measurement(TERM_ID, MODEL) | {
|
572
572
|
key: value for key, value in update_dict.items() if value
|
573
573
|
}
|
574
574
|
return measurement
|
@@ -551,7 +551,7 @@ def _measurement(
|
|
551
551
|
"dates": [f"{year}-12-31" for year in timestamps],
|
552
552
|
"methodClassification": _METHOD_CLASSIFICATION
|
553
553
|
}
|
554
|
-
measurement = _new_measurement(TERM_ID) | {
|
554
|
+
measurement = _new_measurement(TERM_ID, MODEL) | {
|
555
555
|
key: value for key, value in update_dict.items() if value
|
556
556
|
}
|
557
557
|
measurement["depthUpper"] = _DEPTH_UPPER
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from enum import Enum
|
2
2
|
from functools import reduce
|
3
3
|
from math import isclose
|
4
|
-
from numpy import random
|
4
|
+
from numpy import inf, random
|
5
5
|
from numpy.typing import NDArray
|
6
6
|
from typing import Callable, Optional, Union
|
7
7
|
|
@@ -393,9 +393,7 @@ def sample_plus_minus_error(
|
|
393
393
|
) -> NDArray:
|
394
394
|
"""Randomly sample a model parameter with a truncated normal distribution described using plus/minus error."""
|
395
395
|
sd = value * (error / 200)
|
396
|
-
|
397
|
-
high = value + (value * (error / 100))
|
398
|
-
return truncated_normal_1d(shape=(1, iterations), mu=value, sigma=sd, low=low, high=high, seed=seed)
|
396
|
+
return truncated_normal_1d(shape=(1, iterations), mu=value, sigma=sd, low=0, high=inf, seed=seed)
|
399
397
|
|
400
398
|
|
401
399
|
def sample_constant(*, iterations: int, value: float, **_) -> NDArray:
|