hestia-earth-models 0.69.0__py3-none-any.whl → 0.70.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/cache_sites.py +3 -2
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +2 -1
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +3 -2
- hestia_earth/models/config/Cycle.json +35 -1
- hestia_earth/models/{koble2014 → cycle}/aboveGroundCropResidue.py +1 -3
- hestia_earth/models/cycle/aboveGroundCropResidueTotal.py +1 -1
- hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +1 -1
- hestia_earth/models/cycle/animal/input/properties.py +1 -1
- hestia_earth/models/cycle/cycleDuration.py +2 -2
- hestia_earth/models/cycle/energyContentLowerHeatingValue.py +1 -1
- hestia_earth/models/cycle/input/hestiaAggregatedData.py +12 -14
- hestia_earth/models/cycle/input/properties.py +1 -1
- hestia_earth/models/cycle/siteDuration.py +3 -3
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +1 -1
- hestia_earth/models/geospatialDatabase/croppingIntensity.py +4 -4
- hestia_earth/models/geospatialDatabase/longFallowRatio.py +4 -4
- hestia_earth/models/geospatialDatabase/region.py +3 -2
- hestia_earth/models/geospatialDatabase/utils.py +6 -5
- hestia_earth/models/haversineFormula/transport/distance.py +5 -4
- hestia_earth/models/hestia/landCover.py +1 -5
- hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +2 -1
- hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +2 -1
- hestia_earth/models/hestia/seed_emissions.py +1 -1
- hestia_earth/models/impact_assessment/emissions.py +1 -1
- hestia_earth/models/impact_assessment/product/economicValueShare.py +1 -1
- hestia_earth/models/impact_assessment/product/value.py +1 -1
- hestia_earth/models/ipcc2019/animal/fatContent.py +2 -2
- hestia_earth/models/ipcc2019/animal/milkYieldPerAnimal.py +2 -2
- hestia_earth/models/ipcc2019/animal/trueProteinContent.py +2 -2
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +7 -2
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +1 -0
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +2 -1
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +2 -1
- hestia_earth/models/ipcc2019/nonCo2EmissionsToAirNaturalVegetationBurning.py +1 -0
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1.py +8 -8
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2.py +40 -12
- hestia_earth/models/koble2014/cropResidueManagement.py +1 -1
- hestia_earth/models/koble2014/residueBurnt.py +1 -1
- hestia_earth/models/koble2014/residueRemoved.py +1 -1
- hestia_earth/models/koble2014/utils.py +3 -3
- hestia_earth/models/mocking/search-results.json +1179 -1137
- hestia_earth/models/pooreNemecek2018/excretaKgN.py +1 -1
- hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py +1 -1
- hestia_earth/models/pooreNemecek2018/utils.py +6 -3
- hestia_earth/models/schmidt2007/ch4ToAirWasteTreatment.py +1 -3
- hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +1 -3
- hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +1 -3
- hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +1 -3
- hestia_earth/models/site/management.py +5 -3
- hestia_earth/models/site/pre_checks/country.py +4 -2
- hestia_earth/models/transformation/input/excreta.py +1 -1
- hestia_earth/models/utils/aggregated.py +12 -15
- hestia_earth/models/utils/blank_node.py +15 -1
- hestia_earth/models/utils/product.py +1 -1
- hestia_earth/models/utils/source.py +2 -1
- hestia_earth/models/utils/term.py +26 -1
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.69.0.dist-info → hestia_earth_models-0.70.0.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.69.0.dist-info → hestia_earth_models-0.70.0.dist-info}/RECORD +75 -75
- tests/models/cycle/input/test_hestiaAggregatedData.py +18 -16
- tests/models/{koble2014 → cycle}/test_aboveGroundCropResidue.py +3 -3
- tests/models/geospatialDatabase/test_region.py +1 -1
- tests/models/geospatialDatabase/test_utils.py +1 -1
- tests/models/haversineFormula/transport/test_distance.py +2 -2
- tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +11 -0
- tests/models/ipcc2019/test_nonCo2EmissionsToAirNaturalVegetationBurning.py +19 -6
- tests/models/ipcc2019/test_organicCarbonPerHa.py +4 -2
- tests/models/pooreNemecek2018/test_landOccupationDuringCycle.py +3 -0
- tests/models/site/pre_checks/test_country.py +4 -3
- tests/models/test_ecoinventV3.py +2 -2
- tests/models/utils/test_source.py +15 -5
- tests/orchestrator/test_models.py +1 -0
- {hestia_earth_models-0.69.0.dist-info → hestia_earth_models-0.70.0.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.69.0.dist-info → hestia_earth_models-0.70.0.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.69.0.dist-info → hestia_earth_models-0.70.0.dist-info}/top_level.txt +0 -0
@@ -80,11 +80,14 @@ def get_excreta_product_with_ratio(cycle: dict, lookup: str, **log_args):
|
|
80
80
|
) | {'value': [practice.get('ratio')]}
|
81
81
|
for product, practice in practices_with_products
|
82
82
|
# ignore matching products with an existing value
|
83
|
-
if
|
83
|
+
if all([
|
84
|
+
not product or not product.get('value', []),
|
85
|
+
product or practice.get('product-id')
|
86
|
+
])
|
84
87
|
] if practices_with_products else None
|
85
88
|
|
86
|
-
return products or [{
|
89
|
+
return products or non_empty_list([{
|
87
90
|
'@type': 'Product',
|
88
91
|
'term': {'@type': 'Term', '@id': default_product_id},
|
89
92
|
'value': [100]
|
90
|
-
}]
|
93
|
+
} if default_product_id else None])
|
@@ -9,9 +9,7 @@ from . import MODEL
|
|
9
9
|
REQUIREMENTS = {
|
10
10
|
"Cycle": {
|
11
11
|
"or": {
|
12
|
-
"
|
13
|
-
{"@type": "Product", "value": "", "term.termType": "waste"}
|
14
|
-
],
|
12
|
+
"products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
|
15
13
|
"completeness.waste": ""
|
16
14
|
}
|
17
15
|
}
|
@@ -9,9 +9,7 @@ from . import MODEL
|
|
9
9
|
REQUIREMENTS = {
|
10
10
|
"Cycle": {
|
11
11
|
"or": {
|
12
|
-
"
|
13
|
-
{"@type": "Product", "value": "", "term.termType": "waste"}
|
14
|
-
],
|
12
|
+
"products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
|
15
13
|
"completeness.waste": ""
|
16
14
|
}
|
17
15
|
}
|
@@ -9,9 +9,7 @@ from . import MODEL
|
|
9
9
|
REQUIREMENTS = {
|
10
10
|
"Cycle": {
|
11
11
|
"or": {
|
12
|
-
"
|
13
|
-
{"@type": "Product", "value": "", "term.termType": "waste"}
|
14
|
-
],
|
12
|
+
"products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
|
15
13
|
"completeness.waste": ""
|
16
14
|
}
|
17
15
|
}
|
@@ -9,9 +9,7 @@ from . import MODEL
|
|
9
9
|
REQUIREMENTS = {
|
10
10
|
"Cycle": {
|
11
11
|
"or": {
|
12
|
-
"
|
13
|
-
{"@type": "Product", "value": "", "term.termType": "waste"}
|
14
|
-
],
|
12
|
+
"products": [{"@type": "Product", "value": "", "term.termType": "waste"}],
|
15
13
|
"completeness.waste": ""
|
16
14
|
}
|
17
15
|
}
|
@@ -140,12 +140,14 @@ def management(data: dict):
|
|
140
140
|
|
141
141
|
|
142
142
|
def _get_cycle_duration(cycle: dict, land_cover_id: str):
|
143
|
-
|
143
|
+
cycle_duration = cycle.get('cycleDuration')
|
144
|
+
lookup_value = None if cycle_duration else safe_parse_float(get_table_value(
|
144
145
|
download_lookup("crop.csv"),
|
145
146
|
column_name('landCoverTermId'),
|
146
147
|
land_cover_id,
|
147
148
|
column_name('maximumCycleDuration')
|
148
|
-
))
|
149
|
+
), default=None)
|
150
|
+
return cycle_duration or (lookup_value - 1 if lookup_value else None)
|
149
151
|
|
150
152
|
|
151
153
|
def _gap_filled_date_only_str(date_str: str, mode: str = DatestrGapfillMode.END) -> str:
|
@@ -164,7 +166,7 @@ def _gap_filled_start_date(land_cover_id: str, end_date: str, cycle: dict) -> di
|
|
164
166
|
cycle_duration = _get_cycle_duration(cycle, land_cover_id)
|
165
167
|
return {
|
166
168
|
"startDate": max(
|
167
|
-
_gap_filled_date_obj(end_date) - timedelta(days=cycle_duration
|
169
|
+
_gap_filled_date_obj(end_date) - timedelta(days=cycle_duration)
|
168
170
|
if cycle_duration else datetime.fromtimestamp(0),
|
169
171
|
_gap_filled_date_obj(cycle.get("startDate"), mode=DatestrGapfillMode.START)
|
170
172
|
if cycle.get("startDate") else datetime.fromtimestamp(0)
|
@@ -1,4 +1,6 @@
|
|
1
|
-
from hestia_earth.
|
1
|
+
from hestia_earth.schema import TermTermType
|
2
2
|
|
3
|
+
from hestia_earth.models.utils.term import download_term
|
3
4
|
|
4
|
-
|
5
|
+
|
6
|
+
def run(site: dict): return site | {'country': download_term(site.get('country', {}).get('@id'), TermTermType.REGION)}
|
@@ -10,7 +10,6 @@ from . import current_year
|
|
10
10
|
from .cycle import is_organic
|
11
11
|
|
12
12
|
MODEL_KEY = 'impactAssessment'
|
13
|
-
MATCH_WORLD_QUERY = {'match': {'country.name.keyword': {'query': 'World', 'boost': 1}}}
|
14
13
|
|
15
14
|
|
16
15
|
def aggregated_end_date(end_date: str):
|
@@ -18,26 +17,25 @@ def aggregated_end_date(end_date: str):
|
|
18
17
|
return min([round(math.floor(year / 10) * 10) + 9, current_year()])
|
19
18
|
|
20
19
|
|
21
|
-
def
|
22
|
-
|
20
|
+
def _match_country_query(name: str = 'World', boost: int = 1):
|
21
|
+
return {'match': {'country.name.keyword': {'query': name, 'boost': boost}}}
|
22
|
+
|
23
|
+
|
24
|
+
def _match_country(country: dict):
|
23
25
|
country_name = country.get('name') if country else None
|
24
26
|
return {
|
25
27
|
'bool': {
|
26
28
|
# either get with exact country, or default to global
|
27
29
|
'should': non_empty_list([
|
28
|
-
(
|
29
|
-
|
30
|
-
{'match': {'country.name.keyword': {'query': country_name, 'boost': 1000}}} if country_name else
|
31
|
-
None
|
32
|
-
),
|
33
|
-
MATCH_WORLD_QUERY
|
30
|
+
_match_country_query(name=country_name, boost=1000) if country_name else None,
|
31
|
+
_match_country_query()
|
34
32
|
]),
|
35
33
|
'minimum_should_match': 1
|
36
34
|
}
|
37
35
|
}
|
38
36
|
|
39
37
|
|
40
|
-
def find_closest_impact(cycle: dict, end_date: str, term: dict,
|
38
|
+
def find_closest_impact(cycle: dict, end_date: str, term: dict, country: dict, must_queries=[]):
|
41
39
|
query = {
|
42
40
|
'bool': {
|
43
41
|
'must': non_empty_list([
|
@@ -54,7 +52,7 @@ def find_closest_impact(cycle: dict, end_date: str, term: dict, region: dict, co
|
|
54
52
|
'minimum_should_match': 1
|
55
53
|
}
|
56
54
|
} if term else None,
|
57
|
-
|
55
|
+
_match_country(country)
|
58
56
|
]) + must_queries,
|
59
57
|
'should': [
|
60
58
|
# if the Cycle is organic, we can try to match organic aggregate first
|
@@ -76,14 +74,13 @@ def _link_input_to_impact(model: str, cycle: dict, date: int):
|
|
76
74
|
def run(input: dict):
|
77
75
|
term = input.get('term', {})
|
78
76
|
term_id = term.get('@id')
|
79
|
-
region = input.get('region')
|
80
77
|
country = input.get('country')
|
81
|
-
impact = find_closest_impact(cycle, date, term,
|
78
|
+
impact = find_closest_impact(cycle, date, term, country)
|
82
79
|
|
83
|
-
|
80
|
+
search_by_country_id = (country or {}).get('@id') or 'region-world'
|
84
81
|
debugValues(cycle, model=model, term=term_id, key=MODEL_KEY,
|
85
82
|
search_by_input_term_id=term_id,
|
86
|
-
|
83
|
+
search_by_country_id=search_by_country_id,
|
87
84
|
search_by_end_date=str(date),
|
88
85
|
impact_assessment_id_found=(impact or {}).get('@id'))
|
89
86
|
|
@@ -398,9 +398,17 @@ def convert_to_nitrogen(node: dict, model: str, blank_nodes: list, **log_args):
|
|
398
398
|
return value or get_node_property_value(model, input, 'crudeProteinContent', default=0, **log_args) / 6.25
|
399
399
|
|
400
400
|
values = [(i, prop_value(i)) for i in blank_nodes]
|
401
|
-
missing_nitrogen_property = [i.get('term', {}).get('@id') for i,
|
401
|
+
missing_nitrogen_property = [i.get('term', {}).get('@id') for i, value in values if not value]
|
402
402
|
|
403
403
|
debugValues(node, model=model,
|
404
|
+
convertion_details=log_as_table([
|
405
|
+
{
|
406
|
+
'id': i.get('term', {}).get('@id'),
|
407
|
+
'value': list_sum(i.get('value', [])),
|
408
|
+
'conversion-factor': value
|
409
|
+
}
|
410
|
+
for i, value in values
|
411
|
+
]),
|
404
412
|
missing_nitrogen_property=';'.join(set(missing_nitrogen_property)),
|
405
413
|
**log_args)
|
406
414
|
|
@@ -1010,6 +1018,7 @@ def group_nodes_by_year(
|
|
1010
1018
|
nodes: list[dict],
|
1011
1019
|
default_node_duration: int = 1,
|
1012
1020
|
sort_result: bool = True,
|
1021
|
+
include_spillovers: bool = False,
|
1013
1022
|
inner_key: Union[Any, None] = None,
|
1014
1023
|
mode: GroupNodesByYearMode = GroupNodesByYearMode.START_AND_END_DATE
|
1015
1024
|
) -> dict[int, list[dict]]:
|
@@ -1026,6 +1035,10 @@ def group_nodes_by_year(
|
|
1026
1035
|
Default duration of a node years if start date is not available, by default 1.
|
1027
1036
|
sort_result : bool, optional
|
1028
1037
|
Flag to sort the result by year, by default True.
|
1038
|
+
include_spillovers : bool, optional
|
1039
|
+
If grouping by start and end date, flag to determine whether nodes should be included in year groups that they
|
1040
|
+
spill-over into. If `False` year groups will not include nodes that overlap with them by less than 30% of a
|
1041
|
+
year, unless it is the only year group it overlaps with. By default False.
|
1029
1042
|
inner_key: Any | None
|
1030
1043
|
An optional inner dictionary key for the outputted annualised groups (can be used to merge annualised
|
1031
1044
|
dictionaries together), default value: `None`.
|
@@ -1066,6 +1079,7 @@ def group_nodes_by_year(
|
|
1066
1079
|
|
1067
1080
|
should_run = (
|
1068
1081
|
mode == GroupNodesByYearMode.DATES
|
1082
|
+
or include_spillovers
|
1069
1083
|
or _validate_time_fraction_dict(
|
1070
1084
|
time_fraction_dict,
|
1071
1085
|
is_final_year
|
@@ -153,7 +153,7 @@ def get_animal_produced_nitrogen(model: str, products: list) -> float:
|
|
153
153
|
def product_value(product: dict):
|
154
154
|
value = convert_product_to_unit(product, Units.KG_LIVEWEIGHT)
|
155
155
|
property = prop_value(product)
|
156
|
-
return value * property
|
156
|
+
return value * property if all([value, property]) else 0
|
157
157
|
|
158
158
|
return list_sum(list(map(product_value, products)))
|
159
159
|
|
@@ -52,7 +52,8 @@ def _extract(content: str):
|
|
52
52
|
|
53
53
|
def _list_sources():
|
54
54
|
dir = pathlib.Path(ROOT_DIR)
|
55
|
-
|
55
|
+
# ignore current file
|
56
|
+
files = list(filter(lambda f: not str(f).endswith('utils/source.py'), list(dir.rglob('**/*.py'))))
|
56
57
|
return list(set(flatten([_extract(open(f, 'r').read().replace('\n', '')) for f in files])))
|
57
58
|
|
58
59
|
|
@@ -715,7 +715,7 @@ def get_land_cover_terms():
|
|
715
715
|
|
716
716
|
Returns
|
717
717
|
-------
|
718
|
-
List of landCover terms
|
718
|
+
List of landCover terms IDs.
|
719
719
|
"""
|
720
720
|
terms = search({
|
721
721
|
"bool": {
|
@@ -726,3 +726,28 @@ def get_land_cover_terms():
|
|
726
726
|
},
|
727
727
|
}, limit=LIMIT, fields=['@id'])
|
728
728
|
return list(map(lambda n: n["@id"], terms))
|
729
|
+
|
730
|
+
|
731
|
+
def get_ionophore_terms():
|
732
|
+
"""
|
733
|
+
Find all `Ionophore` terms from the Glossary: https://hestia.earth/glossary?query=ionophore
|
734
|
+
|
735
|
+
Returns
|
736
|
+
-------
|
737
|
+
List of ionophore term IDs.
|
738
|
+
"""
|
739
|
+
terms = search({
|
740
|
+
"bool": {
|
741
|
+
"must": [
|
742
|
+
{"match": {"@type": SchemaType.TERM.value}},
|
743
|
+
{"match_phrase_prefix": {"name": "ionophore"}}
|
744
|
+
],
|
745
|
+
"should": [
|
746
|
+
{"match": {"termType": TermTermType.FEEDFOODADDITIVE.value}},
|
747
|
+
{"match": {"termType": TermTermType.VETERINARYDRUG.value}},
|
748
|
+
|
749
|
+
],
|
750
|
+
"minimum_should_match": 1
|
751
|
+
},
|
752
|
+
}, limit=LIMIT, fields=['@id'])
|
753
|
+
return list(map(lambda n: n["@id"], terms))
|
hestia_earth/models/version.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
VERSION = '0.
|
1
|
+
VERSION = '0.70.0'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: hestia-earth-models
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.70.0
|
4
4
|
Summary: HESTIA's set of modules for filling gaps in the activity data using external datasets (e.g. populating soil properties with a geospatial dataset using provided coordinates) and internal lookups (e.g. populating machinery use from fuel use). Includes rules for when gaps should be filled versus not (e.g. never gap fill yield, gap fill crop residue if yield provided etc.).
|
5
5
|
Home-page: https://gitlab.com/hestia-earth/hestia-engine-models
|
6
6
|
Author: HESTIA Team
|