hestia-earth-models 0.67.1__py3-none-any.whl → 0.68.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hestia_earth/models/aware/scarcityWeightedWaterUse.py +5 -6
- hestia_earth/models/blonkConsultants2016/ch4ToAirNaturalVegetationBurning.py +1 -1
- hestia_earth/models/blonkConsultants2016/co2ToAirAboveGroundBiomassStockChangeLandUseChange.py +1 -1
- hestia_earth/models/blonkConsultants2016/n2OToAirNaturalVegetationBurningDirect.py +1 -1
- hestia_earth/models/blonkConsultants2016/utils.py +9 -9
- hestia_earth/models/cache_sites.py +26 -14
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandOccupation.py +2 -2
- hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandTransformation.py +2 -2
- hestia_earth/models/chaudharyBrooks2018/utils.py +13 -8
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +2 -3
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +1 -1
- hestia_earth/models/config/Cycle.json +15 -0
- hestia_earth/models/config/ImpactAssessment.json +14 -1
- hestia_earth/models/config/Site.json +8 -0
- hestia_earth/models/cycle/excretaKgMass.py +2 -2
- hestia_earth/models/cycle/materialAndSubstrate.py +3 -2
- hestia_earth/models/cycle/pastureGrass.py +3 -3
- hestia_earth/models/dammgen2009/noxToAirExcreta.py +1 -1
- hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +1 -1
- hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +2 -6
- hestia_earth/models/emissionNotRelevant/__init__.py +4 -4
- hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +30 -21
- hestia_earth/models/environmentalFootprintV3_1/photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +36 -0
- hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +2 -2
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +9 -8
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +25 -22
- hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexTotalLandUseEffects.py +7 -6
- hestia_earth/models/faostat2018/coldCarcassWeightPerHead.py +2 -2
- hestia_earth/models/faostat2018/coldDressedCarcassWeightPerHead.py +2 -2
- hestia_earth/models/faostat2018/liveweightPerHead.py +7 -8
- hestia_earth/models/faostat2018/product/price.py +34 -28
- hestia_earth/models/faostat2018/readyToCookWeightPerHead.py +2 -2
- hestia_earth/models/faostat2018/utils.py +15 -27
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +16 -9
- hestia_earth/models/geospatialDatabase/altitude.py +60 -0
- hestia_earth/models/geospatialDatabase/croppingIntensity.py +1 -1
- hestia_earth/models/geospatialDatabase/ecoClimateZone.py +2 -2
- hestia_earth/models/geospatialDatabase/longFallowRatio.py +1 -1
- hestia_earth/models/geospatialDatabase/utils.py +4 -1
- hestia_earth/models/globalCropWaterModel2008/rootingDepth.py +2 -3
- hestia_earth/models/haversineFormula/transport/distance.py +3 -3
- hestia_earth/models/hestia/landCover.py +72 -45
- hestia_earth/models/hestia/seed_emissions.py +11 -7
- hestia_earth/models/impact_assessment/__init__.py +3 -3
- hestia_earth/models/ipcc2019/animal/fatContent.py +1 -1
- hestia_earth/models/ipcc2019/animal/hoursWorkedPerDay.py +1 -1
- hestia_earth/models/ipcc2019/animal/liveweightGain.py +1 -1
- hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +1 -1
- hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +1 -1
- hestia_earth/models/ipcc2019/animal/pastureGrass.py +1 -1
- hestia_earth/models/ipcc2019/animal/pregnancyRateTotal.py +1 -1
- hestia_earth/models/ipcc2019/animal/trueProteinContent.py +1 -1
- hestia_earth/models/ipcc2019/animal/utils.py +5 -7
- hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +1 -1
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +2 -2
- hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +6 -7
- hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +5 -3
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +1 -1
- hestia_earth/models/ipcc2019/croppingDuration.py +3 -6
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +947 -0
- hestia_earth/models/ipcc2019/pastureGrass.py +1 -1
- hestia_earth/models/koble2014/residueBurnt.py +5 -7
- hestia_earth/models/koble2014/residueRemoved.py +5 -7
- hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
- hestia_earth/models/log.py +1 -1
- hestia_earth/models/mocking/search-results.json +3413 -1113
- hestia_earth/models/site/management.py +1 -1
- hestia_earth/models/site/post_checks/__init__.py +3 -2
- hestia_earth/models/site/post_checks/country.py +9 -0
- hestia_earth/models/site/pre_checks/__init__.py +3 -2
- hestia_earth/models/site/pre_checks/country.py +9 -0
- hestia_earth/models/utils/__init__.py +1 -16
- hestia_earth/models/utils/blank_node.py +25 -25
- hestia_earth/models/utils/completeness.py +3 -2
- hestia_earth/models/utils/cycle.py +5 -4
- hestia_earth/models/utils/emission.py +5 -5
- hestia_earth/models/utils/feedipedia.py +6 -6
- hestia_earth/models/utils/impact_assessment.py +1 -2
- hestia_earth/models/utils/indicator.py +9 -7
- hestia_earth/models/utils/inorganicFertiliser.py +4 -6
- hestia_earth/models/utils/input.py +6 -5
- hestia_earth/models/utils/lookup.py +32 -100
- hestia_earth/models/utils/management.py +4 -4
- hestia_earth/models/utils/measurement.py +6 -7
- hestia_earth/models/utils/method.py +20 -0
- hestia_earth/models/utils/practice.py +4 -5
- hestia_earth/models/utils/product.py +4 -5
- hestia_earth/models/utils/property.py +12 -22
- hestia_earth/models/utils/site.py +14 -8
- hestia_earth/models/utils/term.py +27 -1
- hestia_earth/models/version.py +1 -1
- hestia_earth/orchestrator/log.py +0 -11
- hestia_earth/orchestrator/models/__init__.py +17 -4
- hestia_earth/orchestrator/strategies/run/add_blank_node_if_missing.py +2 -20
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.0.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.0.dist-info}/RECORD +145 -137
- tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +3 -3
- tests/models/cml2001Baseline/test_resourceUseEnergyDepletionDuringCycle.py +1 -1
- tests/models/cycle/test_coldCarcassWeightPerHead.py +1 -1
- tests/models/cycle/test_coldDressedCarcassWeightPerHead.py +1 -1
- tests/models/cycle/test_concentrateFeed.py +1 -1
- tests/models/cycle/test_energyContentLowerHeatingValue.py +1 -1
- tests/models/cycle/test_excretaKgMass.py +1 -1
- tests/models/cycle/test_feedConversionRatio.py +3 -3
- tests/models/cycle/test_pastureGrass.py +1 -1
- tests/models/cycle/test_readyToCookWeightPerHead.py +1 -1
- tests/models/environmentalFootprintV3_1/test_photochemicalOzoneCreationPotentialHumanHealthNmvocEq.py +30 -0
- tests/models/environmentalFootprintV3_1/test_soilQualityIndexTotalLandUseEffects.py +30 -7
- tests/models/faostat2018/product/test_price.py +27 -14
- tests/models/faostat2018/test_faostat_utils.py +4 -24
- tests/models/faostat2018/test_liveweightPerHead.py +9 -9
- tests/models/globalCropWaterModel2008/test_rootingDepth.py +7 -3
- tests/models/haversineFormula/transport/test_distance.py +1 -1
- tests/models/hestia/test_landCover.py +53 -5
- tests/models/ipcc2019/animal/test_pastureGrass.py +5 -3
- tests/models/ipcc2019/test_aboveGroundCropResidueTotal.py +4 -4
- tests/models/ipcc2019/test_belowGroundCropResidue.py +4 -4
- tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +10 -10
- tests/models/ipcc2019/test_croppingDuration.py +1 -1
- tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +83 -0
- tests/models/ipcc2019/test_organicCarbonPerHa.py +12 -12
- tests/models/ipcc2019/test_pastureGrass.py +5 -3
- tests/models/pooreNemecek2018/test_excretaKgN.py +5 -5
- tests/models/pooreNemecek2018/test_excretaKgVs.py +2 -2
- tests/models/site/post_checks/test_country.py +6 -0
- tests/models/site/pre_checks/test_cache_geospatialDatabase.py +1 -1
- tests/models/site/pre_checks/test_country.py +12 -0
- tests/models/test_ecoinventV3.py +7 -3
- tests/models/utils/test_blank_node.py +4 -12
- tests/models/utils/test_dataCompleteness.py +5 -5
- tests/models/utils/test_emission.py +2 -2
- tests/models/utils/test_indicator.py +2 -2
- tests/models/utils/test_input.py +2 -2
- tests/models/utils/test_measurement.py +2 -4
- tests/models/utils/test_practice.py +4 -2
- tests/models/utils/test_product.py +2 -2
- tests/models/utils/test_property.py +4 -2
- tests/models/utils/test_site.py +7 -0
- tests/orchestrator/strategies/run/test_add_blank_node_if_missing.py +4 -9
- hestia_earth/models/environmentalFootprintV3_1/utils.py +0 -17
- tests/models/utils/test_lookup.py +0 -10
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.0.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.0.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.67.1.dist-info → hestia_earth_models-0.68.0.dist-info}/top_level.txt +0 -0
@@ -185,7 +185,7 @@ def _gap_filled_start_date(land_cover_id: str, end_date: str, cycle: dict) -> di
|
|
185
185
|
cycle_duration = _get_cycle_duration(cycle, land_cover_id)
|
186
186
|
return {
|
187
187
|
"startDate": max(
|
188
|
-
_gap_filled_date_obj(end_date) - timedelta(days=cycle_duration)
|
188
|
+
_gap_filled_date_obj(end_date) - timedelta(days=cycle_duration - 1)
|
189
189
|
if cycle_duration else datetime.fromtimestamp(0),
|
190
190
|
_gap_filled_date_obj(cycle.get("startDate"), mode=DatestrGapfillMode.START)
|
191
191
|
if cycle.get("startDate") else datetime.fromtimestamp(0)
|
@@ -2,13 +2,14 @@ from os.path import dirname, abspath
|
|
2
2
|
import sys
|
3
3
|
|
4
4
|
from hestia_earth.models.utils import _run_in_serie
|
5
|
-
from . import cache
|
5
|
+
from . import cache, country
|
6
6
|
|
7
7
|
CURRENT_DIR = dirname(abspath(__file__)) + '/'
|
8
8
|
sys.path.append(CURRENT_DIR)
|
9
9
|
|
10
10
|
MODELS = [
|
11
|
-
cache.run
|
11
|
+
cache.run,
|
12
|
+
country.run
|
12
13
|
]
|
13
14
|
|
14
15
|
|
@@ -2,7 +2,7 @@ from os.path import dirname, abspath
|
|
2
2
|
import sys
|
3
3
|
|
4
4
|
from hestia_earth.models.utils import _run_in_serie
|
5
|
-
from . import cache_years, cache_geospatialDatabase, cache_sources
|
5
|
+
from . import cache_years, cache_geospatialDatabase, cache_sources, country
|
6
6
|
|
7
7
|
CURRENT_DIR = dirname(abspath(__file__)) + '/'
|
8
8
|
sys.path.append(CURRENT_DIR)
|
@@ -10,7 +10,8 @@ sys.path.append(CURRENT_DIR)
|
|
10
10
|
MODELS = [
|
11
11
|
cache_years.run,
|
12
12
|
cache_geospatialDatabase.run,
|
13
|
-
cache_sources.run
|
13
|
+
cache_sources.run,
|
14
|
+
country.run
|
14
15
|
]
|
15
16
|
|
16
17
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
"""
|
2
|
+
Pre Checks Country
|
3
|
+
|
4
|
+
Load the complete country data from HESTIA to be able to use `subClassOf` for example.
|
5
|
+
"""
|
6
|
+
from hestia_earth.utils.api import download_hestia
|
7
|
+
|
8
|
+
|
9
|
+
def run(site: dict): return site | {'country': download_hestia(site.get('country', {}).get('@id'))}
|
@@ -8,10 +8,9 @@ import datetime
|
|
8
8
|
from functools import reduce
|
9
9
|
import operator
|
10
10
|
from pydash.objects import get
|
11
|
-
from typing import Any, Callable
|
11
|
+
from typing import Any, Callable
|
12
12
|
from hestia_earth.schema import SchemaType
|
13
13
|
from hestia_earth.utils.api import download_hestia
|
14
|
-
from hestia_earth.utils.model import linked_node
|
15
14
|
from hestia_earth.utils.tools import flatten, non_empty_list
|
16
15
|
from hestia_earth.utils.date import is_in_days, is_in_months
|
17
16
|
|
@@ -44,20 +43,6 @@ def _omit(values: dict, keys: list) -> dict: return {k: v for k, v in values.ite
|
|
44
43
|
def _include(value: dict, keys: list) -> dict: return {k: v for k, v in value.items() if k in keys}
|
45
44
|
|
46
45
|
|
47
|
-
def _include_model(node: dict, term_id: str):
|
48
|
-
term = download_hestia(term_id) or {}
|
49
|
-
return {**node, **({} if term.get('@id') is None else {'model': linked_node(term)})}
|
50
|
-
|
51
|
-
|
52
|
-
def _include_method(node: dict, term_id: Union[None, str, dict], key='method'):
|
53
|
-
term = (download_hestia(term_id) or {}) if isinstance(term_id, str) else term_id
|
54
|
-
return node | ({} if term is None or term.get('@id') is None else {key: linked_node(term)})
|
55
|
-
|
56
|
-
|
57
|
-
def _include_methodModel(node: dict, term_id: str):
|
58
|
-
return _include_method(node, term_id=term_id, key='methodModel')
|
59
|
-
|
60
|
-
|
61
46
|
def _run_in_serie(data: dict, models: list): return reduce(lambda prev, model: model(prev), models, data)
|
62
47
|
|
63
48
|
|
@@ -15,7 +15,6 @@ from typing import (
|
|
15
15
|
from dateutil import parser
|
16
16
|
from dateutil.relativedelta import relativedelta
|
17
17
|
from hestia_earth.schema import TermTermType
|
18
|
-
from hestia_earth.utils.api import download_hestia
|
19
18
|
from hestia_earth.utils.blank_node import ArrayTreatment, get_node_value
|
20
19
|
from hestia_earth.utils.model import filter_list_term_type
|
21
20
|
from hestia_earth.utils.tools import (
|
@@ -26,18 +25,21 @@ from hestia_earth.utils.tools import (
|
|
26
25
|
safe_parse_float,
|
27
26
|
non_empty_list
|
28
27
|
)
|
29
|
-
|
30
|
-
from . import is_from_model, _filter_list_term_unit, is_iterable, full_date_str
|
31
|
-
from .constant import Units, get_atomic_conversion
|
32
|
-
from .lookup import (
|
28
|
+
from hestia_earth.utils.lookup_utils import (
|
33
29
|
is_model_siteType_allowed,
|
34
30
|
is_siteType_allowed,
|
35
|
-
is_product_id_allowed,
|
36
|
-
|
31
|
+
is_product_id_allowed,
|
32
|
+
is_product_termType_allowed,
|
33
|
+
is_input_id_allowed,
|
34
|
+
is_input_termType_allowed
|
37
35
|
)
|
36
|
+
|
37
|
+
from hestia_earth.models.log import debugValues, log_as_table
|
38
|
+
from . import is_from_model, _filter_list_term_unit, is_iterable, full_date_str
|
39
|
+
from .constant import Units, get_atomic_conversion
|
40
|
+
from .lookup import _node_value
|
38
41
|
from .property import get_node_property, get_node_property_value
|
39
|
-
from .term import get_lookup_value
|
40
|
-
from ..log import debugValues, log_as_table
|
42
|
+
from .term import get_lookup_value, download_term
|
41
43
|
|
42
44
|
# TODO: verify those values
|
43
45
|
MAX_DEPTH = 1000
|
@@ -122,29 +124,29 @@ def _module_term_id(term_id: str, module):
|
|
122
124
|
return getattr(module, 'TERM_ID', term_id_str).split(',')[0]
|
123
125
|
|
124
126
|
|
125
|
-
def _run_model_required(model: str,
|
126
|
-
siteType_allowed = is_model_siteType_allowed(model,
|
127
|
+
def _run_model_required(model: str, term_id: str, data: dict):
|
128
|
+
siteType_allowed = is_model_siteType_allowed(model, term_id, data)
|
127
129
|
|
128
130
|
run_required = all([siteType_allowed])
|
129
|
-
debugValues(data, model=model, term=
|
131
|
+
debugValues(data, model=model, term=term_id,
|
130
132
|
run_required=run_required,
|
131
133
|
siteType_allowed=siteType_allowed)
|
132
134
|
return run_required
|
133
135
|
|
134
136
|
|
135
|
-
def _run_required(model: str,
|
136
|
-
siteType_allowed = is_siteType_allowed(data,
|
137
|
-
product_id_allowed = is_product_id_allowed(data,
|
138
|
-
product_termType_allowed = is_product_termType_allowed(data,
|
139
|
-
input_id_allowed = is_input_id_allowed(data,
|
140
|
-
input_termType_allowed = is_input_termType_allowed(data,
|
137
|
+
def _run_required(model: str, term_id: str, data: dict):
|
138
|
+
siteType_allowed = is_siteType_allowed(data, term_id)
|
139
|
+
product_id_allowed = is_product_id_allowed(data, term_id)
|
140
|
+
product_termType_allowed = is_product_termType_allowed(data, term_id)
|
141
|
+
input_id_allowed = is_input_id_allowed(data, term_id)
|
142
|
+
input_termType_allowed = is_input_termType_allowed(data, term_id)
|
141
143
|
|
142
144
|
run_required = all([
|
143
145
|
siteType_allowed, product_id_allowed, product_termType_allowed, input_id_allowed, input_termType_allowed
|
144
146
|
])
|
145
147
|
# model is only used for logs here, skip logs if model not provided
|
146
148
|
if model:
|
147
|
-
debugValues(data, model=model, term=
|
149
|
+
debugValues(data, model=model, term=term_id,
|
148
150
|
siteType_allowed=siteType_allowed,
|
149
151
|
product_id_allowed=product_id_allowed,
|
150
152
|
product_termType_allowed=product_termType_allowed,
|
@@ -152,7 +154,7 @@ def _run_required(model: str, term: dict, data: dict):
|
|
152
154
|
input_termType_allowed=input_termType_allowed)
|
153
155
|
# logging this for the model would cause issues parsing statuses
|
154
156
|
if model != 'emissionNotRelevant':
|
155
|
-
debugValues(data, model=model, term=
|
157
|
+
debugValues(data, model=model, term=term_id, run_required=run_required)
|
156
158
|
return run_required
|
157
159
|
|
158
160
|
|
@@ -174,10 +176,9 @@ def is_run_required(model: str, term_id: str, node: dict):
|
|
174
176
|
bool
|
175
177
|
True if the model is required to run.
|
176
178
|
"""
|
177
|
-
term = download_hestia(term_id)
|
178
179
|
return (
|
179
|
-
(_run_model_required(model,
|
180
|
-
) if
|
180
|
+
(_run_model_required(model, term_id, node) if model else True) and _run_required(model, term_id, node)
|
181
|
+
) if term_id else True
|
181
182
|
|
182
183
|
|
183
184
|
def run_if_required(model: str, term_id: str, data: dict, module):
|
@@ -1279,7 +1280,7 @@ def get_inputs_from_properties(input: dict, term_types: Union[TermTermType, List
|
|
1279
1280
|
properties = (
|
1280
1281
|
input.get('properties') or
|
1281
1282
|
input.get('term', {}).get('defaultProperties') or
|
1282
|
-
|
1283
|
+
download_term(input.get('term', {})).get('defaultProperties')
|
1283
1284
|
)
|
1284
1285
|
inputs = non_empty_list([
|
1285
1286
|
{
|
@@ -1559,7 +1560,6 @@ def convert_unit_properties(node_value: Union[int, float], node: dict, dest_unit
|
|
1559
1560
|
Convert a number `node_value` belonging to a term `node`, to unit `to_units` by chaining multiple unit conversions
|
1560
1561
|
together.
|
1561
1562
|
Uses terms properties for the conversion.
|
1562
|
-
Uses cached calls to download_hestia() internally for speedup
|
1563
1563
|
Returns None if no conversion possible.
|
1564
1564
|
"""
|
1565
1565
|
src_unit = node.get("units") or node.get('term', {}).get('units', "")
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import Union
|
2
2
|
from hestia_earth.schema import Completeness, TermTermType
|
3
|
-
|
3
|
+
|
4
|
+
from .term import download_term
|
4
5
|
|
5
6
|
completeness_fields = Completeness().required
|
6
7
|
|
@@ -12,7 +13,7 @@ def _completeness_term_type(cycle: dict, term: Union[str, dict, TermTermType]):
|
|
12
13
|
|
13
14
|
|
14
15
|
def _get_term_type_completeness(cycle: dict, term: Union[str, dict]):
|
15
|
-
term =
|
16
|
+
term = download_term(term) if isinstance(term, str) else term
|
16
17
|
term_type = term.get('termType') if term else None
|
17
18
|
return cycle.get('completeness', {}).get(term_type, False)
|
18
19
|
|
@@ -1,9 +1,10 @@
|
|
1
1
|
from hestia_earth.schema import CycleFunctionalUnit, SiteSiteType, TermTermType, AnimalReferencePeriod
|
2
2
|
from hestia_earth.utils.model import filter_list_term_type, find_term_match, find_primary_product
|
3
3
|
from hestia_earth.utils.tools import list_sum, safe_parse_float, safe_parse_date, non_empty_list
|
4
|
+
from hestia_earth.utils.lookup_utils import is_siteType_allowed
|
4
5
|
|
5
6
|
from ..log import logRequirements, debugValues
|
6
|
-
from .lookup import all_factor_value
|
7
|
+
from .lookup import all_factor_value
|
7
8
|
from .term import get_lookup_value
|
8
9
|
from .property import get_node_property
|
9
10
|
from .completeness import _is_term_type_complete
|
@@ -344,7 +345,7 @@ def is_organic(cycle: dict):
|
|
344
345
|
`True` if the `Cycle` is organic, `False` otherwise.
|
345
346
|
"""
|
346
347
|
practices = filter_list_term_type(cycle.get('practices', []), TermTermType.STANDARDSLABELS)
|
347
|
-
return
|
348
|
+
return next((get_lookup_value(p.get('term', {}), 'isOrganic') == 'organic' for p in practices), False)
|
348
349
|
|
349
350
|
|
350
351
|
def is_irrigated(cycle: dict, **log_ars):
|
@@ -463,9 +464,9 @@ def get_animals_by_period(cycle: dict, period: AnimalReferencePeriod = AnimalRef
|
|
463
464
|
]
|
464
465
|
|
465
466
|
|
466
|
-
def get_allowed_sites(model: str, term_id: str,
|
467
|
+
def get_allowed_sites(model: str, term_id: str, cycle: dict):
|
467
468
|
sites = non_empty_list([cycle.get('site', None)]) + cycle.get('otherSites', [])
|
468
|
-
allowed_sites = [s for s in sites if is_siteType_allowed(s,
|
469
|
+
allowed_sites = [s for s in sites if is_siteType_allowed(s, term_id)]
|
469
470
|
allowed_site_ids = non_empty_list([s.get('@id', s.get('id')) for s in allowed_sites])
|
470
471
|
debugValues(cycle, model=model, term=term_id, site_ids=';'.join(allowed_site_ids))
|
471
472
|
return allowed_sites
|
@@ -1,22 +1,22 @@
|
|
1
1
|
from collections.abc import Iterable
|
2
2
|
from typing import Optional, Union
|
3
3
|
from hestia_earth.schema import EmissionMethodTier, SchemaType, TermTermType
|
4
|
-
from hestia_earth.utils.api import download_hestia
|
5
4
|
from hestia_earth.utils.model import linked_node
|
6
5
|
|
7
6
|
|
8
|
-
from . import
|
7
|
+
from . import flatten_args
|
8
|
+
from .term import download_term
|
9
9
|
from .blank_node import find_terms_value
|
10
|
+
from .method import include_methodModel
|
10
11
|
from .constant import Units, get_atomic_conversion
|
11
12
|
|
12
|
-
|
13
13
|
EMISSION_METHOD_TIERS = [e.value for e in EmissionMethodTier]
|
14
14
|
|
15
15
|
|
16
16
|
def _new_emission(term, model=None):
|
17
17
|
node = {'@type': SchemaType.EMISSION.value}
|
18
|
-
node['term'] = linked_node(term if isinstance(term, dict) else
|
19
|
-
return
|
18
|
+
node['term'] = linked_node(term if isinstance(term, dict) else download_term(term, TermTermType.EMISSION))
|
19
|
+
return include_methodModel(node, model)
|
20
20
|
|
21
21
|
|
22
22
|
def get_nh3_no3_nox_to_n(cycle: dict, nh3_term_id: str, no3_term_id: str, nox_term_id: str, allow_none: bool = False):
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from hestia_earth.utils.model import find_term_match
|
2
|
-
from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
|
2
|
+
from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name, lookup_term_ids
|
3
3
|
from hestia_earth.utils.tools import non_empty_list, safe_parse_float
|
4
4
|
|
5
5
|
from hestia_earth.models.log import logShouldRun
|
@@ -11,9 +11,9 @@ DRY_MATTER_TERM_ID = 'dryMatter'
|
|
11
11
|
|
12
12
|
def get_feedipedia_properties():
|
13
13
|
lookup = download_lookup('property.csv')
|
14
|
-
term_ids = list(lookup.termid)
|
15
14
|
term_ids = [
|
16
|
-
term_id for term_id in
|
15
|
+
term_id for term_id in lookup_term_ids(lookup)
|
16
|
+
if get_table_value(lookup, 'termid', term_id, column_name('feedipediaName'))
|
17
17
|
]
|
18
18
|
return term_ids
|
19
19
|
|
@@ -25,7 +25,6 @@ def _should_rescale_by_dm(property_id: str):
|
|
25
25
|
|
26
26
|
|
27
27
|
def _dm_property(term_id: str, property_values: dict, dm_property_values: dict, dry_matter_property: dict):
|
28
|
-
blank_node = _new_property(term_id)
|
29
28
|
blank_node_data = {}
|
30
29
|
for property_key in property_values.keys():
|
31
30
|
new_dm_value = safe_parse_float(dry_matter_property.get(property_key))
|
@@ -37,7 +36,7 @@ def _dm_property(term_id: str, property_values: dict, dm_property_values: dict,
|
|
37
36
|
2
|
38
37
|
) if _should_rescale_by_dm(term_id) else old_property_value
|
39
38
|
blank_node_data[property_key] = new_value
|
40
|
-
return (
|
39
|
+
return (_new_property(term_id) | blank_node_data) if blank_node_data else None
|
41
40
|
|
42
41
|
|
43
42
|
def _map_properties(lookup, term_id: str, column_prefix: str):
|
@@ -74,7 +73,8 @@ def rescale_properties_from_dryMatter(model: str, node: dict, blank_nodes: list)
|
|
74
73
|
new_properties = non_empty_list([
|
75
74
|
exec_property(blank_node, p, dry_matter_property) for p in properties if all([
|
76
75
|
not find_term_match(all_properties, p),
|
77
|
-
p != DRY_MATTER_TERM_ID
|
76
|
+
p != DRY_MATTER_TERM_ID,
|
77
|
+
dry_matter_property
|
78
78
|
])
|
79
79
|
])
|
80
80
|
for prop in new_properties:
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from typing import Optional
|
2
2
|
from hestia_earth.schema import TermTermType
|
3
|
-
from hestia_earth.utils.lookup import download_lookup
|
4
3
|
from hestia_earth.utils.model import find_term_match, filter_list_term_type
|
5
4
|
from hestia_earth.utils.tools import list_sum, safe_parse_date
|
6
5
|
|
@@ -161,7 +160,7 @@ def impact_country_value(
|
|
161
160
|
nodes = filter_list_term_type(impact.get('emissionsResourceUse', []), term_type)
|
162
161
|
|
163
162
|
country_id = get_country_id(impact)
|
164
|
-
country_id = fallback_country(country_id, [
|
163
|
+
country_id = fallback_country(country_id, [lookup]) if country_fallback else country_id
|
165
164
|
|
166
165
|
values = list(map(_term_factor_value(model, term_id, lookup, country_id, group_key), nodes))
|
167
166
|
debugValues(impact, model=model, term=term_id,
|
@@ -1,15 +1,17 @@
|
|
1
|
-
from hestia_earth.schema import SchemaType
|
2
|
-
from hestia_earth.utils.api import download_hestia
|
1
|
+
from hestia_earth.schema import SchemaType, TermTermType
|
3
2
|
from hestia_earth.utils.model import linked_node
|
4
3
|
|
5
|
-
from . import
|
4
|
+
from .method import include_methodModel
|
5
|
+
from .term import download_term
|
6
6
|
|
7
7
|
|
8
8
|
def _new_indicator(term, model=None, land_cover_id: str = None, previous_land_cover_id: str = None):
|
9
9
|
node = {'@type': SchemaType.INDICATOR.value}
|
10
|
-
node['term'] = linked_node(term if isinstance(term, dict) else
|
10
|
+
node['term'] = linked_node(term if isinstance(term, dict) else download_term(
|
11
|
+
term, TermTermType.CHARACTERISEDINDICATOR)
|
12
|
+
)
|
11
13
|
if land_cover_id:
|
12
|
-
node['landCover'] = linked_node(
|
14
|
+
node['landCover'] = linked_node(download_term(land_cover_id, TermTermType.LANDCOVER))
|
13
15
|
if previous_land_cover_id:
|
14
|
-
node['previousLandCover'] = linked_node(
|
15
|
-
return
|
16
|
+
node['previousLandCover'] = linked_node(download_term(previous_land_cover_id, TermTermType.LANDCOVER))
|
17
|
+
return include_methodModel(node, model)
|
@@ -1,18 +1,18 @@
|
|
1
1
|
from hestia_earth.schema import TermTermType
|
2
|
-
from hestia_earth.utils.lookup import
|
2
|
+
from hestia_earth.utils.lookup import download_lookup, extract_grouped_data, lookup_term_ids
|
3
3
|
from hestia_earth.utils.tools import safe_parse_float
|
4
4
|
from hestia_earth.utils.model import filter_list_term_type
|
5
5
|
|
6
|
-
from ..log import debugMissingLookup
|
7
6
|
from .term import get_lookup_value
|
8
7
|
from .fertiliser import get_fertilisers_from_inputs
|
8
|
+
from .lookup import get_region_lookup_value
|
9
9
|
|
10
10
|
BREAKDOWN_LOOKUP = 'region-inorganicFertiliser-fertGroupingNitrogen-breakdown.csv'
|
11
11
|
|
12
12
|
|
13
13
|
def get_terms():
|
14
14
|
lookup = download_lookup('inorganicFertiliser.csv', True)
|
15
|
-
return
|
15
|
+
return lookup_term_ids(lookup)
|
16
16
|
|
17
17
|
|
18
18
|
def get_term_lookup(term_id: str, col_name: str):
|
@@ -35,9 +35,7 @@ def get_NH3_emission_factor(term_id: str, soilPh: float, temperature: float):
|
|
35
35
|
|
36
36
|
|
37
37
|
def get_country_breakdown(model: str, term_id: str, country_id: str, col_name: str):
|
38
|
-
|
39
|
-
value = get_table_value(lookup, 'termid', country_id, column_name(col_name))
|
40
|
-
debugMissingLookup(BREAKDOWN_LOOKUP, 'termid', country_id, col_name, value, model=model, term=term_id)
|
38
|
+
value = get_region_lookup_value(BREAKDOWN_LOOKUP, country_id, col_name, model=model, term=term_id)
|
41
39
|
return safe_parse_float(value, None)
|
42
40
|
|
43
41
|
|
@@ -1,19 +1,20 @@
|
|
1
1
|
from hestia_earth.schema import SchemaType, TermTermType
|
2
|
-
from hestia_earth.utils.api import download_hestia
|
3
2
|
from hestia_earth.utils.model import find_term_match, linked_node, filter_list_term_type
|
4
3
|
from hestia_earth.utils.tools import list_sum, non_empty_list, list_average, flatten
|
5
4
|
from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
|
6
5
|
|
7
|
-
from
|
8
|
-
from . import
|
6
|
+
from hestia_earth.models.log import logger
|
7
|
+
from . import _filter_list_term_unit, _load_calculated_node
|
9
8
|
from .constant import Units
|
10
9
|
from .blank_node import get_total_value, get_total_value_converted, get_lookup_value
|
10
|
+
from .term import download_term
|
11
|
+
from .method import include_model
|
11
12
|
|
12
13
|
|
13
14
|
def _new_input(term, model=None):
|
14
15
|
node = {'@type': SchemaType.INPUT.value}
|
15
|
-
node['term'] = linked_node(term if isinstance(term, dict) else
|
16
|
-
return
|
16
|
+
node['term'] = linked_node(term if isinstance(term, dict) else download_term(term))
|
17
|
+
return include_model(node, model)
|
17
18
|
|
18
19
|
|
19
20
|
def load_impacts(inputs: list):
|
@@ -1,10 +1,13 @@
|
|
1
1
|
from typing import Optional, List
|
2
|
-
from numpy import recarray
|
3
|
-
from hestia_earth.schema import SchemaType
|
4
2
|
from hestia_earth.utils.lookup import (
|
5
|
-
download_lookup,
|
3
|
+
download_lookup,
|
4
|
+
get_table_value,
|
5
|
+
column_name,
|
6
|
+
extract_grouped_data,
|
7
|
+
_get_single_table_value,
|
8
|
+
lookup_term_ids
|
6
9
|
)
|
7
|
-
from hestia_earth.utils.tools import list_sum, safe_parse_float
|
10
|
+
from hestia_earth.utils.tools import list_sum, safe_parse_float
|
8
11
|
|
9
12
|
from ..log import debugValues, log_as_table, debugMissingLookup
|
10
13
|
|
@@ -15,13 +18,11 @@ def _node_value(node):
|
|
15
18
|
|
16
19
|
|
17
20
|
def _factor_value(model: str, term_id: str, lookup_name: str, lookup_col: str, grouped_key: Optional[str] = None):
|
18
|
-
lookup = download_lookup(lookup_name)
|
19
|
-
|
20
21
|
def get_value(data: dict):
|
21
22
|
node_term_id = data.get('term', {}).get('@id')
|
22
23
|
grouped_data_key = grouped_key or data.get('methodModel', {}).get('@id')
|
23
24
|
value = _node_value(data)
|
24
|
-
coefficient =
|
25
|
+
coefficient = get_region_lookup_value(lookup_name, node_term_id, lookup_col, model=model, term=term_id)
|
25
26
|
# value is either a number or matching between a model and a value (restrict value to specific model only)
|
26
27
|
coefficient = safe_parse_float(
|
27
28
|
extract_grouped_data(coefficient, grouped_data_key), None
|
@@ -69,12 +70,10 @@ def all_factor_value(
|
|
69
70
|
|
70
71
|
|
71
72
|
def _term_factor_value(model: str, term_id: str, lookup_name: str, lookup_term_id: str, group_key: str = None):
|
72
|
-
lookup = download_lookup(lookup_name, False) # avoid saving in memory as there could be many different files used
|
73
|
-
|
74
73
|
def get_value(data: dict):
|
75
74
|
node_term_id = data.get('term', {}).get('@id')
|
76
75
|
value = _node_value(data)
|
77
|
-
coefficient =
|
76
|
+
coefficient = get_region_lookup_value(lookup_name, lookup_term_id, node_term_id, model=model, term=term_id)
|
78
77
|
coefficient = safe_parse_float(extract_grouped_data(coefficient, group_key) if group_key else coefficient)
|
79
78
|
if value is not None and coefficient is not None:
|
80
79
|
debugValues(data, model=model, term=term_id,
|
@@ -107,98 +106,31 @@ def _aware_factor_value(model: str, term_id: str, lookup_name: str, aware_id: st
|
|
107
106
|
return get_value
|
108
107
|
|
109
108
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
def _get_sites(node: dict):
|
118
|
-
site = node.get('site', node.get('cycle', {}).get('site'))
|
119
|
-
other_sites = node.get('otherSites', node.get('cycle', {}).get('otherSites', []))
|
120
|
-
return non_empty_list([site] + other_sites)
|
121
|
-
|
122
|
-
|
123
|
-
def _get_site_types(node: dict):
|
124
|
-
sites = [node] if _is_site(node) else _get_sites(node)
|
125
|
-
return non_empty_list([site.get('siteType') for site in sites])
|
126
|
-
|
127
|
-
|
128
|
-
def _model_lookup_values(model: str, term: dict, restriction: str):
|
129
|
-
lookup = download_lookup(f"{term.get('termType')}-model-{restriction}.csv")
|
130
|
-
values = get_table_value(lookup, 'termid', term.get('@id'), column_name(model))
|
131
|
-
return (values or _ALLOW_ALL).split(';') if isinstance(values, str) else _ALLOW_ALL
|
132
|
-
|
133
|
-
|
134
|
-
def is_model_siteType_allowed(model: str, term: dict, data: dict):
|
135
|
-
site_types = _get_site_types(data)
|
136
|
-
allowed_values = _model_lookup_values(model, term, 'siteTypesAllowed')
|
137
|
-
return True if _ALLOW_ALL in allowed_values or not site_types else any([
|
138
|
-
(site_type in allowed_values) for site_type in site_types
|
139
|
-
])
|
140
|
-
|
141
|
-
|
142
|
-
def _lookup_values(term: dict, column: str):
|
143
|
-
lookup = download_lookup(f"{term.get('termType')}.csv")
|
144
|
-
values = get_table_value(lookup, 'termid', term.get('@id'), column_name(column))
|
145
|
-
return (values or _ALLOW_ALL).split(';') if isinstance(values, str) else _ALLOW_ALL
|
146
|
-
|
147
|
-
|
148
|
-
def is_siteType_allowed(data: dict, term: dict):
|
149
|
-
site_types = _get_site_types(data)
|
150
|
-
allowed_values = _lookup_values(term, 'siteTypesAllowed')
|
151
|
-
return True if _ALLOW_ALL in allowed_values or not site_types else any([
|
152
|
-
(site_type in allowed_values) for site_type in site_types
|
153
|
-
])
|
154
|
-
|
155
|
-
|
156
|
-
def is_product_termType_allowed(data: dict, term: dict):
|
157
|
-
products = data.get('products', [])
|
158
|
-
values = non_empty_list([p.get('term', {}).get('termType') for p in products])
|
159
|
-
allowed_values = _lookup_values(term, 'productTermTypesAllowed')
|
160
|
-
return True if any([
|
161
|
-
_ALLOW_ALL in allowed_values,
|
162
|
-
len(values) == 0
|
163
|
-
]) else any([value in allowed_values for value in values])
|
164
|
-
|
165
|
-
|
166
|
-
def is_product_id_allowed(data: dict, term: dict):
|
167
|
-
products = data.get('products', [])
|
168
|
-
values = non_empty_list([p.get('term', {}).get('@id') for p in products])
|
169
|
-
allowed_values = _lookup_values(term, 'productTermIdsAllowed')
|
170
|
-
return True if any([
|
171
|
-
_ALLOW_ALL in allowed_values,
|
172
|
-
len(values) == 0
|
173
|
-
]) else any([value in allowed_values for value in values])
|
174
|
-
|
175
|
-
|
176
|
-
def is_input_termType_allowed(data: dict, term: dict):
|
177
|
-
inputs = data.get('inputs', [])
|
178
|
-
values = non_empty_list([p.get('term', {}).get('termType') for p in inputs])
|
179
|
-
allowed_values = _lookup_values(term, 'inputTermTypesAllowed')
|
180
|
-
return True if any([
|
181
|
-
_ALLOW_ALL in allowed_values,
|
182
|
-
len(values) == 0
|
183
|
-
]) else any([value in allowed_values for value in values])
|
184
|
-
|
185
|
-
|
186
|
-
def is_input_id_allowed(data: dict, term: dict):
|
187
|
-
inputs = data.get('inputs', [])
|
188
|
-
values = non_empty_list([p.get('term', {}).get('@id') for p in inputs])
|
189
|
-
allowed_values = _lookup_values(term, 'inputTermIdsAllowed')
|
190
|
-
return True if any([
|
191
|
-
_ALLOW_ALL in allowed_values,
|
192
|
-
len(values) == 0
|
193
|
-
]) else any([value in allowed_values for value in values])
|
109
|
+
def _country_in_lookup(country_id: str):
|
110
|
+
def in_lookup(lookup_name: str):
|
111
|
+
return (
|
112
|
+
download_lookup(lookup_name.replace('region', country_id)) is not None or
|
113
|
+
country_id in lookup_term_ids(download_lookup(lookup_name))
|
114
|
+
)
|
115
|
+
return in_lookup
|
194
116
|
|
195
117
|
|
196
|
-
def fallback_country(country_id: str,
|
118
|
+
def fallback_country(country_id: str, lookups: List[str]) -> str:
|
197
119
|
"""
|
198
|
-
Given a
|
199
|
-
|
200
|
-
else fallback to the default "region-world"
|
120
|
+
Given a country `@id`, and lookup tables, checks if a location can be used in lookup file
|
121
|
+
else fallback to the default "region-world".
|
201
122
|
"""
|
202
|
-
is_in_lookup = lambda v: all(v
|
123
|
+
is_in_lookup = lambda v: all(map(_country_in_lookup(v), lookups)) # noqa: E731
|
203
124
|
fallback_id = 'region-world'
|
204
|
-
return country_id if is_in_lookup(country_id) else fallback_id if is_in_lookup(fallback_id) else None
|
125
|
+
return country_id if country_id and is_in_lookup(country_id) else fallback_id if is_in_lookup(fallback_id) else None
|
126
|
+
|
127
|
+
|
128
|
+
def get_region_lookup_value(lookup_name: str, term_id: str, column: str, **log_args):
|
129
|
+
# for performance, try to load the region specific lookup if exists
|
130
|
+
lookup = (
|
131
|
+
download_lookup(lookup_name.replace('region-', f"{term_id}-"))
|
132
|
+
if lookup_name and lookup_name.startswith('region-') else None
|
133
|
+
) or download_lookup(lookup_name)
|
134
|
+
value = get_table_value(lookup, 'termid', term_id, column_name(column))
|
135
|
+
debugMissingLookup(lookup_name, 'termid', term_id, column, value, **log_args)
|
136
|
+
return value
|
@@ -1,11 +1,11 @@
|
|
1
1
|
from hestia_earth.schema import SchemaType
|
2
2
|
from hestia_earth.utils.model import linked_node
|
3
|
-
from hestia_earth.utils.api import download_hestia
|
4
3
|
|
5
|
-
from . import
|
4
|
+
from .term import download_term
|
5
|
+
from .method import include_model
|
6
6
|
|
7
7
|
|
8
8
|
def _new_management(term, model=None):
|
9
9
|
node = {'@type': SchemaType.MANAGEMENT.value}
|
10
|
-
node['term'] = linked_node(term if isinstance(term, dict) else
|
11
|
-
return
|
10
|
+
node['term'] = linked_node(term if isinstance(term, dict) else download_term(term))
|
11
|
+
return include_model(node, model)
|