hestia-earth-models 0.59.3__py3-none-any.whl → 0.59.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of hestia-earth-models might be problematic. Click here for more details.

Files changed (24) hide show
  1. hestia_earth/models/geospatialDatabase/potentialEvapotranspirationMonthly.py +98 -0
  2. hestia_earth/models/geospatialDatabase/precipitationMonthly.py +98 -0
  3. hestia_earth/models/geospatialDatabase/temperatureAnnual.py +1 -2
  4. hestia_earth/models/geospatialDatabase/temperatureMonthly.py +98 -0
  5. hestia_earth/models/geospatialDatabase/utils.py +8 -1
  6. hestia_earth/models/ipcc2019/organicCarbonPerHa.py +2 -25
  7. hestia_earth/models/mocking/search-results.json +8 -8
  8. hestia_earth/models/site/management.py +6 -6
  9. hestia_earth/models/site/pre_checks/cache_geospatialDatabase.py +27 -7
  10. hestia_earth/models/site/utils.py +2 -6
  11. hestia_earth/models/utils/__init__.py +9 -0
  12. hestia_earth/models/utils/site.py +8 -5
  13. hestia_earth/models/version.py +1 -1
  14. {hestia_earth_models-0.59.3.dist-info → hestia_earth_models-0.59.4.dist-info}/METADATA +2 -2
  15. {hestia_earth_models-0.59.3.dist-info → hestia_earth_models-0.59.4.dist-info}/RECORD +24 -18
  16. tests/models/geospatialDatabase/test_potentialEvapotranspirationMonthly.py +20 -0
  17. tests/models/geospatialDatabase/test_precipitationMonthly.py +20 -0
  18. tests/models/geospatialDatabase/test_temperatureMonthly.py +20 -0
  19. tests/models/ipcc2019/test_organicCarbonPerHa.py +4 -21
  20. tests/models/site/test_management.py +13 -13
  21. tests/models/utils/test_site.py +1 -1
  22. {hestia_earth_models-0.59.3.dist-info → hestia_earth_models-0.59.4.dist-info}/LICENSE +0 -0
  23. {hestia_earth_models-0.59.3.dist-info → hestia_earth_models-0.59.4.dist-info}/WHEEL +0 -0
  24. {hestia_earth_models-0.59.3.dist-info → hestia_earth_models-0.59.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,98 @@
1
+ """
2
+ Must be associated with at least 1 `Cycle` that has an
3
+ [endDate](https://hestia.earth/schema/Cycle#endDate) after `1979-01-01` and before `2020-06-01`.
4
+ """
5
+ from hestia_earth.schema import MeasurementMethodClassification
6
+ from hestia_earth.utils.tools import flatten, non_empty_list
7
+
8
+ from hestia_earth.models.log import logRequirements, logShouldRun
9
+ from hestia_earth.models.utils import first_day_of_month, last_day_of_month
10
+ from hestia_earth.models.utils.measurement import _new_measurement
11
+ from hestia_earth.models.utils.source import get_source
12
+ from hestia_earth.models.utils.site import related_years
13
+ from .utils import KELVIN_0, download, has_geospatial_data, should_download
14
+ from . import MODEL
15
+
16
+ REQUIREMENTS = {
17
+ "Site": {
18
+ "or": [
19
+ {"latitude": "", "longitude": ""},
20
+ {"boundary": {}},
21
+ {"region": {"@type": "Term", "termType": "region"}}
22
+ ]
23
+ }
24
+ }
25
+ RETURNS = {
26
+ "Measurement": [{
27
+ "value": "",
28
+ "dates": "",
29
+ "methodClassification": "geospatial dataset"
30
+ }]
31
+ }
32
+ TERM_ID = 'potentialEvapotranspirationMonthly'
33
+ EE_PARAMS = {
34
+ 'collection': 'IDAHO_EPSCOR/TERRACLIMATE',
35
+ 'band_name': 'pet',
36
+ 'ee_type': 'raster',
37
+ 'reducer': 'mean',
38
+ 'reducer_annual': 'sum'
39
+ }
40
+ BIBLIO_TITLE = 'ERA5: Fifth generation of ECMWF atmospheric reanalyses of the global climate'
41
+
42
+
43
+ def _measurement(site: dict, value: list, dates: list):
44
+ measurement = _new_measurement(TERM_ID)
45
+ measurement['value'] = value
46
+ measurement['dates'] = dates
47
+ measurement['methodClassification'] = MeasurementMethodClassification.GEOSPATIAL_DATASET.value
48
+ return measurement | get_source(site, BIBLIO_TITLE)
49
+
50
+
51
+ def _to_celcius(kelvin_value: int): return kelvin_value - KELVIN_0 if kelvin_value else None
52
+
53
+
54
+ def _download(site: dict, start_date: str, end_date: str):
55
+ return download(
56
+ TERM_ID,
57
+ site,
58
+ {
59
+ **EE_PARAMS,
60
+ 'start_date': start_date,
61
+ 'end_date': end_date
62
+ }
63
+ )
64
+
65
+
66
+ def _run(site: dict, years: list):
67
+ # fetch from first year to last
68
+ years = range(years[0], years[-1] + 1) if len(years) > 1 else years
69
+
70
+ dates = flatten([
71
+ [
72
+ (first_day_of_month(year, month).strftime('%Y-%m-%d'), last_day_of_month(year, month).strftime('%Y-%m-%d'))
73
+ for month in range(1, 13)
74
+ ] for year in years
75
+ ])
76
+ values = non_empty_list([
77
+ (_to_celcius(_download(site, start_date, end_date)), start_date[0:7]) for start_date, end_date in dates
78
+ ])
79
+ return _measurement(site, [v for v, d in values], [d for v, d in values])
80
+
81
+
82
+ def run(site: dict):
83
+ contains_geospatial_data = has_geospatial_data(site)
84
+ below_max_area_size = should_download(TERM_ID, site)
85
+
86
+ years = related_years(site)
87
+ has_years = len(years) > 0
88
+
89
+ logRequirements(site, model=MODEL, term=TERM_ID,
90
+ contains_geospatial_data=contains_geospatial_data,
91
+ below_max_area_size=below_max_area_size,
92
+ has_years=has_years,
93
+ years=';'.join(map(lambda y: str(y), years)))
94
+
95
+ should_run = all([contains_geospatial_data, below_max_area_size, has_years])
96
+ logShouldRun(site, MODEL, TERM_ID, should_run)
97
+
98
+ return _run(site, years) if should_run else []
@@ -0,0 +1,98 @@
1
+ """
2
+ Must be associated with at least 1 `Cycle` that has an
3
+ [endDate](https://hestia.earth/schema/Cycle#endDate) after `1979-01-01` and before `2020-06-01`.
4
+ """
5
+ from hestia_earth.schema import MeasurementMethodClassification
6
+ from hestia_earth.utils.tools import flatten, non_empty_list
7
+
8
+ from hestia_earth.models.log import logRequirements, logShouldRun
9
+ from hestia_earth.models.utils import first_day_of_month, last_day_of_month
10
+ from hestia_earth.models.utils.measurement import _new_measurement
11
+ from hestia_earth.models.utils.source import get_source
12
+ from hestia_earth.models.utils.site import related_years
13
+ from .utils import KELVIN_0, download, has_geospatial_data, should_download
14
+ from . import MODEL
15
+
16
+ REQUIREMENTS = {
17
+ "Site": {
18
+ "or": [
19
+ {"latitude": "", "longitude": ""},
20
+ {"boundary": {}},
21
+ {"region": {"@type": "Term", "termType": "region"}}
22
+ ]
23
+ }
24
+ }
25
+ RETURNS = {
26
+ "Measurement": [{
27
+ "value": "",
28
+ "dates": "",
29
+ "methodClassification": "geospatial dataset"
30
+ }]
31
+ }
32
+ TERM_ID = 'precipitationMonthly'
33
+ EE_PARAMS = {
34
+ 'collection': 'ECMWF/ERA5/MONTHLY',
35
+ 'band_name': 'total_precipitation',
36
+ 'ee_type': 'raster',
37
+ 'reducer': 'mean',
38
+ 'reducer_annual': 'sum'
39
+ }
40
+ BIBLIO_TITLE = 'ERA5: Fifth generation of ECMWF atmospheric reanalyses of the global climate'
41
+
42
+
43
+ def _measurement(site: dict, value: list, dates: list):
44
+ measurement = _new_measurement(TERM_ID)
45
+ measurement['value'] = value
46
+ measurement['dates'] = dates
47
+ measurement['methodClassification'] = MeasurementMethodClassification.GEOSPATIAL_DATASET.value
48
+ return measurement | get_source(site, BIBLIO_TITLE)
49
+
50
+
51
+ def _to_celcius(kelvin_value: int): return kelvin_value - KELVIN_0 if kelvin_value else None
52
+
53
+
54
+ def _download(site: dict, start_date: str, end_date: str):
55
+ return download(
56
+ TERM_ID,
57
+ site,
58
+ {
59
+ **EE_PARAMS,
60
+ 'start_date': start_date,
61
+ 'end_date': end_date
62
+ }
63
+ )
64
+
65
+
66
+ def _run(site: dict, years: list):
67
+ # fetch from first year to last
68
+ years = range(years[0], years[-1] + 1) if len(years) > 1 else years
69
+
70
+ dates = flatten([
71
+ [
72
+ (first_day_of_month(year, month).strftime('%Y-%m-%d'), last_day_of_month(year, month).strftime('%Y-%m-%d'))
73
+ for month in range(1, 13)
74
+ ] for year in years
75
+ ])
76
+ values = non_empty_list([
77
+ (_to_celcius(_download(site, start_date, end_date)), start_date[0:7]) for start_date, end_date in dates
78
+ ])
79
+ return _measurement(site, [v for v, d in values], [d for v, d in values])
80
+
81
+
82
+ def run(site: dict):
83
+ contains_geospatial_data = has_geospatial_data(site)
84
+ below_max_area_size = should_download(TERM_ID, site)
85
+
86
+ years = related_years(site)
87
+ has_years = len(years) > 0
88
+
89
+ logRequirements(site, model=MODEL, term=TERM_ID,
90
+ contains_geospatial_data=contains_geospatial_data,
91
+ below_max_area_size=below_max_area_size,
92
+ has_years=has_years,
93
+ years=';'.join(map(lambda y: str(y), years)))
94
+
95
+ should_run = all([contains_geospatial_data, below_max_area_size, has_years])
96
+ logShouldRun(site, MODEL, TERM_ID, should_run)
97
+
98
+ return _run(site, years) if should_run else []
@@ -9,7 +9,7 @@ from hestia_earth.models.log import logRequirements, logShouldRun
9
9
  from hestia_earth.models.utils.measurement import _new_measurement
10
10
  from hestia_earth.models.utils.source import get_source
11
11
  from hestia_earth.models.utils.site import related_years
12
- from .utils import download, has_geospatial_data, should_download
12
+ from .utils import KELVIN_0, download, has_geospatial_data, should_download
13
13
  from . import MODEL
14
14
 
15
15
  REQUIREMENTS = {
@@ -38,7 +38,6 @@ EE_PARAMS = {
38
38
  'reducer_annual': 'mean'
39
39
  }
40
40
  BIBLIO_TITLE = 'ERA5: Fifth generation of ECMWF atmospheric reanalyses of the global climate'
41
- KELVIN_0 = 273.15
42
41
 
43
42
 
44
43
  def _measurement(site: dict, value: float, year: int):
@@ -0,0 +1,98 @@
1
+ """
2
+ Must be associated with at least 1 `Cycle` that has an
3
+ [endDate](https://hestia.earth/schema/Cycle#endDate) after `1979-01-01` and before `2020-06-01`.
4
+ """
5
+ from hestia_earth.schema import MeasurementMethodClassification
6
+ from hestia_earth.utils.tools import flatten, non_empty_list
7
+
8
+ from hestia_earth.models.log import logRequirements, logShouldRun
9
+ from hestia_earth.models.utils import first_day_of_month, last_day_of_month
10
+ from hestia_earth.models.utils.measurement import _new_measurement
11
+ from hestia_earth.models.utils.source import get_source
12
+ from hestia_earth.models.utils.site import related_years
13
+ from .utils import KELVIN_0, download, has_geospatial_data, should_download
14
+ from . import MODEL
15
+
16
+ REQUIREMENTS = {
17
+ "Site": {
18
+ "or": [
19
+ {"latitude": "", "longitude": ""},
20
+ {"boundary": {}},
21
+ {"region": {"@type": "Term", "termType": "region"}}
22
+ ]
23
+ }
24
+ }
25
+ RETURNS = {
26
+ "Measurement": [{
27
+ "value": "",
28
+ "dates": "",
29
+ "methodClassification": "geospatial dataset"
30
+ }]
31
+ }
32
+ TERM_ID = 'temperatureMonthly'
33
+ EE_PARAMS = {
34
+ 'collection': 'ECMWF/ERA5/MONTHLY',
35
+ 'band_name': 'mean_2m_air_temperature',
36
+ 'ee_type': 'raster',
37
+ 'reducer': 'mean',
38
+ 'reducer_annual': 'mean'
39
+ }
40
+ BIBLIO_TITLE = 'ERA5: Fifth generation of ECMWF atmospheric reanalyses of the global climate'
41
+
42
+
43
+ def _measurement(site: dict, value: list, dates: list):
44
+ measurement = _new_measurement(TERM_ID)
45
+ measurement['value'] = value
46
+ measurement['dates'] = dates
47
+ measurement['methodClassification'] = MeasurementMethodClassification.GEOSPATIAL_DATASET.value
48
+ return measurement | get_source(site, BIBLIO_TITLE)
49
+
50
+
51
+ def _to_celcius(kelvin_value: int): return kelvin_value - KELVIN_0 if kelvin_value else None
52
+
53
+
54
+ def _download(site: dict, start_date: str, end_date: str):
55
+ return download(
56
+ TERM_ID,
57
+ site,
58
+ {
59
+ **EE_PARAMS,
60
+ 'start_date': start_date,
61
+ 'end_date': end_date
62
+ }
63
+ )
64
+
65
+
66
+ def _run(site: dict, years: list):
67
+ # fetch from first year to last
68
+ years = range(years[0], years[-1] + 1) if len(years) > 1 else years
69
+
70
+ dates = flatten([
71
+ [
72
+ (first_day_of_month(year, month).strftime('%Y-%m-%d'), last_day_of_month(year, month).strftime('%Y-%m-%d'))
73
+ for month in range(1, 13)
74
+ ] for year in years
75
+ ])
76
+ values = non_empty_list([
77
+ (_to_celcius(_download(site, start_date, end_date)), start_date[0:7]) for start_date, end_date in dates
78
+ ])
79
+ return _measurement(site, [v for v, d in values], [d for v, d in values])
80
+
81
+
82
+ def run(site: dict):
83
+ contains_geospatial_data = has_geospatial_data(site)
84
+ below_max_area_size = should_download(TERM_ID, site)
85
+
86
+ years = related_years(site)
87
+ has_years = len(years) > 0
88
+
89
+ logRequirements(site, model=MODEL, term=TERM_ID,
90
+ contains_geospatial_data=contains_geospatial_data,
91
+ below_max_area_size=below_max_area_size,
92
+ has_years=has_years,
93
+ years=';'.join(map(lambda y: str(y), years)))
94
+
95
+ should_run = all([contains_geospatial_data, below_max_area_size, has_years])
96
+ logShouldRun(site, MODEL, TERM_ID, should_run)
97
+
98
+ return _run(site, years) if should_run else []
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  from hestia_earth.schema import TermTermType
3
3
  from hestia_earth.utils.api import download_hestia
4
+ from hestia_earth.utils.tools import non_empty_list
4
5
 
5
6
  from hestia_earth.models.log import debugValues, logErrorRun, logRequirements
6
7
  from hestia_earth.models.utils.site import cached_value, region_factor, region_level_1_id
@@ -19,6 +20,7 @@ GEOPANDAS_COLLECTION_NAME = {
19
20
  'gadm36_4': 'gadm/gadm36_4',
20
21
  'gadm36_5': 'gadm/gadm36_5'
21
22
  }
23
+ KELVIN_0 = 273.15
22
24
 
23
25
 
24
26
  def use_geopandas(): return os.getenv('HEE_USE_GEOPANDAS', 'false') == 'true'
@@ -131,8 +133,13 @@ def _parse_run_query(term: str, query: dict):
131
133
 
132
134
  def _get_cached_data(term: str, site: dict, data: dict):
133
135
  cache = _cached_value(site, term)
136
+ cache_sub_key = '-'.join(non_empty_list([
137
+ data.get('year'),
138
+ data.get('start_date'),
139
+ data.get('end_date')
140
+ ]))
134
141
  # data can be grouped by year when required
135
- value = cache.get(data.get('year')) if data.get('year') and cache is not None else cache
142
+ value = cache.get(cache_sub_key) if cache_sub_key and cache is not None else cache
136
143
  if value is not None:
137
144
  debugValues(site, model=MODEL, term=term, value_from_cache=value)
138
145
  return value
@@ -18,15 +18,12 @@ from typing import (
18
18
  from hestia_earth.schema import (
19
19
  CycleFunctionalUnit,
20
20
  MeasurementMethodClassification,
21
- SchemaType,
22
21
  SiteSiteType,
23
22
  TermTermType,
24
23
  )
25
- from hestia_earth.utils.api import find_related
26
24
  from hestia_earth.utils.model import find_term_match, filter_list_term_type
27
25
  from hestia_earth.utils.tools import flatten, list_sum, non_empty_list
28
26
 
29
- from hestia_earth.models.utils import _load_calculated_node
30
27
  from hestia_earth.models.log import log_as_table, logRequirements, logShouldRun
31
28
  from hestia_earth.models.utils.blank_node import (
32
29
  cumulative_nodes_match,
@@ -54,7 +51,7 @@ from hestia_earth.models.utils.term import (
54
51
  get_upland_rice_crop_terms,
55
52
  get_upland_rice_land_cover_terms
56
53
  )
57
-
54
+ from hestia_earth.models.utils.site import related_cycles
58
55
  from .utils import check_consecutive
59
56
  from . import MODEL
60
57
 
@@ -3554,7 +3551,7 @@ def _should_run(site: dict) -> tuple[bool, dict]:
3554
3551
  site_type = site.get("siteType", "")
3555
3552
  management_nodes = site.get("management", [])
3556
3553
  measurement_nodes = site.get("measurements", [])
3557
- cycles = _calculated_cycles(site.get("@id"))
3554
+ cycles = related_cycles(site.get("@id"))
3558
3555
 
3559
3556
  has_management = len(management_nodes) > 0
3560
3557
  has_measurements = len(measurement_nodes) > 0
@@ -3611,26 +3608,6 @@ def _should_run(site: dict) -> tuple[bool, dict]:
3611
3608
  return should_run_tier_1, should_run_tier_2, inventory, kwargs
3612
3609
 
3613
3610
 
3614
- def _calculated_cycles(site_id: str):
3615
- """
3616
- Get the list of `Cycle`s related to the `Site`. Gets the `recalculated` data if available, else `original`.
3617
-
3618
- Parameters
3619
- ----------
3620
- site_id : str
3621
- The `@id` of the `Site`.
3622
-
3623
- Returns
3624
- -------
3625
- list[dict]
3626
- The related `Cycle`s as `dict`.
3627
- """
3628
- nodes = find_related(SchemaType.SITE, site_id, SchemaType.CYCLE)
3629
- return list(
3630
- map(lambda node: _load_calculated_node(node, SchemaType.CYCLE), nodes or [])
3631
- )
3632
-
3633
-
3634
3611
  def _should_run_tier_1(
3635
3612
  inventory: dict,
3636
3613
  *,
@@ -918,11 +918,11 @@
918
918
  },
919
919
  {
920
920
  "@type": "Term",
921
- "@id": "residueIncorporated"
921
+ "@id": "residueIncorporatedMoreThan30DaysBeforeCultivation"
922
922
  },
923
923
  {
924
924
  "@type": "Term",
925
- "@id": "residueIncorporatedMoreThan30DaysBeforeCultivation"
925
+ "@id": "residueIncorporated"
926
926
  },
927
927
  {
928
928
  "@type": "Term",
@@ -1299,7 +1299,7 @@
1299
1299
  "@type": "Term",
1300
1300
  "name": "Generic crop, seed",
1301
1301
  "@id": "genericCropSeed",
1302
- "_score": 23.9092
1302
+ "_score": 23.910892
1303
1303
  }
1304
1304
  ]
1305
1305
  },
@@ -1405,11 +1405,11 @@
1405
1405
  "results": [
1406
1406
  {
1407
1407
  "@type": "Term",
1408
- "@id": "waterMarine"
1408
+ "@id": "waterDrainageCanal"
1409
1409
  },
1410
1410
  {
1411
1411
  "@type": "Term",
1412
- "@id": "waterDrainageCanal"
1412
+ "@id": "waterMarine"
1413
1413
  },
1414
1414
  {
1415
1415
  "@type": "Term",
@@ -1740,15 +1740,15 @@
1740
1740
  },
1741
1741
  {
1742
1742
  "@type": "Term",
1743
- "@id": "fullInversionTillage"
1743
+ "@id": "fullTillage"
1744
1744
  },
1745
1745
  {
1746
1746
  "@type": "Term",
1747
- "@id": "fullTillage"
1747
+ "@id": "minimumTillage"
1748
1748
  },
1749
1749
  {
1750
1750
  "@type": "Term",
1751
- "@id": "minimumTillage"
1751
+ "@id": "fullInversionTillage"
1752
1752
  },
1753
1753
  {
1754
1754
  "@type": "Term",
@@ -9,9 +9,9 @@ from hestia_earth.utils.model import filter_list_term_type, linked_node
9
9
  from hestia_earth.utils.tools import flatten
10
10
 
11
11
  from hestia_earth.models.log import logRequirements, logShouldRun, log_blank_nodes_id
12
- from hestia_earth.models.utils.site import related_cycles
13
12
  from hestia_earth.models.utils.term import get_lookup_value
14
13
  from hestia_earth.models.utils.blank_node import get_node_value
14
+ from hestia_earth.models.utils.site import related_cycles
15
15
  from . import MODEL
16
16
 
17
17
  REQUIREMENTS = {
@@ -96,7 +96,7 @@ def _get_items_with_relevant_term_type(cycles: List[dict], item_name: str, relev
96
96
  )
97
97
 
98
98
 
99
- def should_run(site: dict):
99
+ def _should_run(site: dict):
100
100
  # Only get related cycles once.
101
101
  cycles = related_cycles(site.get("@id"))
102
102
 
@@ -158,11 +158,11 @@ def should_run(site: dict):
158
158
  practice_ids=log_blank_nodes_id(practices)
159
159
  )
160
160
 
161
- _should_run = any(products_crop_forage + products_land_cover + practices)
161
+ should_run = any(products_crop_forage + products_land_cover + practices)
162
162
  logShouldRun(site, MODEL, None, should_run=_should_run, model_key=MODEL_KEY)
163
- return _should_run, products_crop_forage + products_land_cover, practices
163
+ return should_run, products_crop_forage + products_land_cover, practices
164
164
 
165
165
 
166
166
  def run(site: dict):
167
- _should_run, products, practices = should_run(site)
168
- return list(map(management, products + practices)) if _should_run else []
167
+ should_run, products, practices = _should_run(site)
168
+ return list(map(management, products + practices)) if should_run else []
@@ -4,10 +4,10 @@ Pre Checks Cache Geospatial Database
4
4
  This model caches results from Geospatial Database.
5
5
  """
6
6
  from functools import reduce
7
- from hestia_earth.utils.tools import flatten
7
+ from hestia_earth.utils.tools import flatten, non_empty_list
8
8
 
9
9
  from hestia_earth.models.log import debugValues
10
- from hestia_earth.models.utils import CACHE_KEY, cached_value
10
+ from hestia_earth.models.utils import CACHE_KEY, cached_value, first_day_of_month, last_day_of_month
11
11
  from hestia_earth.models.utils.site import CACHE_YEARS_KEY
12
12
  from hestia_earth.models.geospatialDatabase.utils import (
13
13
  MAX_AREA_SIZE, CACHE_VALUE, CACHE_AREA_SIZE,
@@ -34,7 +34,12 @@ def cache_site_results(results: list, collections: list, area_size: int = None):
34
34
  collection = collections[index]
35
35
  name = collection.get('name')
36
36
  value = results[index]
37
- data = (group.get(name, {}) | {collection.get('year'): value}) if 'year' in collection else value
37
+ cache_sub_key = '-'.join(non_empty_list([
38
+ collection.get('year'),
39
+ collection.get('start_date'),
40
+ collection.get('end_date')
41
+ ]))
42
+ data = (group.get(name, {}) | {cache_sub_key: value} if cache_sub_key else value)
38
43
  return group | {name: data}
39
44
 
40
45
  return reduce(_combine_result, range(0, len(results)), {}) | (
@@ -42,13 +47,28 @@ def cache_site_results(results: list, collections: list, area_size: int = None):
42
47
  )
43
48
 
44
49
 
50
+ def _extend_collection_by_month(year: int):
51
+ return [{
52
+ 'start_date': first_day_of_month(year, month).strftime('%Y-%m-%d'),
53
+ 'end_date': last_day_of_month(year, month).strftime('%Y-%m-%d')
54
+ } for month in range(1, 13)]
55
+
56
+
45
57
  def _extend_collection(name: str, collection: dict, years: list = []):
46
58
  data = collection | {'name': name, 'collection': _collection_name(collection.get('collection'))}
59
+
60
+ year_params = [{'year': str(year)} for year in years]
61
+ # fetch from first year to last
62
+ month_years = range(years[0], years[-1] + 1) if len(years) > 1 else years
63
+ month_params = flatten(map(_extend_collection_by_month, month_years))
64
+
47
65
  return [
48
- data | {
49
- 'year': str(year)
50
- } for year in years
51
- ] if 'reducer_annual' in collection and 'reducer_period' not in collection else [data]
66
+ (data | params) for params in year_params
67
+ ] if name.endswith('Annual') else [
68
+ (data | params) for params in month_params
69
+ ] if name.endswith('Monthly') else [
70
+ data
71
+ ]
52
72
 
53
73
 
54
74
  def _extend_collections(values: list, years: list = []):
@@ -1,10 +1,9 @@
1
1
  from functools import reduce
2
- import datetime
3
2
  from hestia_earth.schema import TermTermType
4
3
  from hestia_earth.utils.tools import non_empty_list
5
4
  from hestia_earth.utils.date import DAY
6
5
 
7
- from hestia_earth.models.utils import _omit
6
+ from hestia_earth.models.utils import _omit, first_day_of_month, last_day_of_month
8
7
  from hestia_earth.models.utils.measurement import _new_measurement, measurement_value, has_all_months
9
8
 
10
9
 
@@ -68,10 +67,7 @@ def _group_by_month(term_id: str, dates: list, values: list):
68
67
 
69
68
  def map_to_month(data: list, year: int, month: int):
70
69
  # make sure we got all the necessary days
71
- first_day_of_month = datetime.date(year, month, 1)
72
- last_day_of_month = datetime.date(year + int(month / 12), (month % 12) + 1, 1) - datetime.timedelta(days=1)
73
-
74
- difference = last_day_of_month - first_day_of_month
70
+ difference = last_day_of_month(year, month) - first_day_of_month(year, month)
75
71
  days_in_month = round(difference.days + difference.seconds / DAY, 1) + 1
76
72
 
77
73
  return measurement_value({
@@ -1,5 +1,6 @@
1
1
  from os.path import dirname, abspath
2
2
  import sys
3
+ import datetime
3
4
  from functools import reduce
4
5
  import operator
5
6
  from typing import Any
@@ -126,3 +127,11 @@ def _get_by_key(x, y):
126
127
 
127
128
 
128
129
  def get_dict_key(value: dict, key: str): return reduce(lambda x, y: _get_by_key(x, y), key.split('.'), value)
130
+
131
+
132
+ def first_day_of_month(year: int, month: int):
133
+ return datetime.date(int(year), int(month), 1)
134
+
135
+
136
+ def last_day_of_month(year: int, month: int):
137
+ return datetime.date(int(year) + int(int(month) / 12), (int(month) % 12) + 1, 1) - datetime.timedelta(days=1)
@@ -1,10 +1,10 @@
1
1
  from hestia_earth.schema import SchemaType, SiteSiteType, TermTermType
2
- from hestia_earth.utils.api import download_hestia, find_related
2
+ from hestia_earth.utils.api import find_related
3
3
  from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
4
4
  from hestia_earth.utils.tools import non_empty_list, safe_parse_date
5
5
 
6
6
  from hestia_earth.models.log import debugMissingLookup
7
- from . import cached_value
7
+ from . import cached_value, _load_calculated_node
8
8
 
9
9
  CACHE_YEARS_KEY = 'years'
10
10
  WATER_TYPES = [
@@ -47,8 +47,7 @@ def is_site(site: dict): return site.get('@type', site.get('type')) == SchemaTyp
47
47
  def related_cycles(site_id: str):
48
48
  """
49
49
  Get the list of `Cycle` related to the `Site`.
50
-
51
- In Hestia, a `Cycle` must have a link to a `Site`, therefore a `Site` can be related to many `Cycle`s.
50
+ Gets the `recalculated` data if available, else `original`.
52
51
 
53
52
  Parameters
54
53
  ----------
@@ -61,7 +60,7 @@ def related_cycles(site_id: str):
61
60
  The related `Cycle`s as `dict`.
62
61
  """
63
62
  nodes = find_related(SchemaType.SITE, site_id, SchemaType.CYCLE)
64
- return non_empty_list(map(lambda node: download_hestia(node.get('@id'), SchemaType.CYCLE), nodes or []))
63
+ return non_empty_list(map(lambda node: _load_calculated_node(node, SchemaType.CYCLE), nodes or []))
65
64
 
66
65
 
67
66
  def _cycle_end_year(cycle: dict):
@@ -75,6 +74,10 @@ def related_years(site: dict):
75
74
  )
76
75
 
77
76
 
77
+ def related_months(site: dict):
78
+ return cached_value(site)
79
+
80
+
78
81
  def valid_site_type(site: dict, site_types=[SiteSiteType.CROPLAND.value, SiteSiteType.PERMANENT_PASTURE.value]):
79
82
  """
80
83
  Check if the site `siteType` is allowed.
@@ -1 +1 @@
1
- VERSION = '0.59.3'
1
+ VERSION = '0.59.4'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hestia-earth-models
3
- Version: 0.59.3
3
+ Version: 0.59.4
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
@@ -18,7 +18,7 @@ Requires-Dist: CurrencyConverter ==0.16.8
18
18
  Requires-Dist: haversine >=2.7.0
19
19
  Requires-Dist: pydash
20
20
  Provides-Extra: spatial
21
- Requires-Dist: hestia-earth.earth-engine >=0.4.2 ; extra == 'spatial'
21
+ Requires-Dist: hestia-earth.earth-engine >=0.4.7 ; extra == 'spatial'
22
22
 
23
23
  # Hestia Engine Models
24
24
 
@@ -3,7 +3,7 @@ hestia_earth/models/__init__.py,sha256=qEFeq3yuf3lQKVseALmL8aPM8fpCS54B_5pry00M3
3
3
  hestia_earth/models/cache_sites.py,sha256=kp_3D09P-JdAn9vt7eU-KKTwd6BAXWKQL_0UQCDsH2s,4798
4
4
  hestia_earth/models/log.py,sha256=b63I3qyTtQs17xxbq8RI0Fv2lvZ1oDZ9k0njhxqiFFk,3459
5
5
  hestia_earth/models/requirements.py,sha256=znNZJAhwX2iYiKcAQXPftY7z_1MsNa0QxCXkXyHm_U0,17363
6
- hestia_earth/models/version.py,sha256=CbLC-bytMU-XpY8CM5H7SMZR8Ap_SRMUQNvt55nruo0,19
6
+ hestia_earth/models/version.py,sha256=dVCy68c5An9e5A-5RC7W7zhxXlwTjzAHL1hfZj8TunQ,19
7
7
  hestia_earth/models/agribalyse2016/__init__.py,sha256=WvK0qCQbnYtg9oZxrACd1wGormZyXibPtpCnIQeDqbw,415
8
8
  hestia_earth/models/agribalyse2016/fuelElectricity.py,sha256=mrh8seYSYdTgcMDCETLiknuPeJehg071YoG4UiyW0yU,4404
9
9
  hestia_earth/models/agribalyse2016/machineryInfrastructureDepreciatedAmountPerCycle.py,sha256=_Rbngu0DzHKa62JwBl58ZC_ui1zLF2que_nB7ukhOQc,3392
@@ -143,19 +143,22 @@ hestia_earth/models/geospatialDatabase/nutrientLossToAquaticEnvironment.py,sha25
143
143
  hestia_earth/models/geospatialDatabase/organicCarbonPerKgSoil.py,sha256=gt3-crrUN0HPtIKY7Hf9dUteCXkegSICVjO-jufDqas,2196
144
144
  hestia_earth/models/geospatialDatabase/potentialEvapotranspirationAnnual.py,sha256=UlCBvAD-6H-4sdryfPuX1YDlOsGPOI8T9y0q4O0Tau8,2544
145
145
  hestia_earth/models/geospatialDatabase/potentialEvapotranspirationLongTermAnnualMean.py,sha256=uGMCkSZk8gJ6gFHhaiV1PtQxuP0Gzt4m3is0vkQSiXU,2122
146
+ hestia_earth/models/geospatialDatabase/potentialEvapotranspirationMonthly.py,sha256=vNO0cJLE8LGrFeEF2PPRCJWFbdOxHIDG7KH8BTe4cg4,3284
146
147
  hestia_earth/models/geospatialDatabase/precipitationAnnual.py,sha256=8_lMKVUPClnp7tetHrsoUY2ZGG2J7c-cXqJD8rznp0Q,2803
147
148
  hestia_earth/models/geospatialDatabase/precipitationLongTermAnnualMean.py,sha256=fS5knfil5f2QP8-gxFdXuoGTxXpzoJQZ9h4UjWIWjCA,2376
149
+ hestia_earth/models/geospatialDatabase/precipitationMonthly.py,sha256=SbsldfQS4bePegyvJERc13zH8Xy3VVdLFuAKCx6JbME,3279
148
150
  hestia_earth/models/geospatialDatabase/region.py,sha256=rdywdsI4OglcO05tih0UQx0qbnm8BAn7mP-x74iV03c,1462
149
151
  hestia_earth/models/geospatialDatabase/sandContent.py,sha256=BZUn2z4BN1HgCGZ2Xsifca2CRTaZ4gdcaZ8A1_UoPQM,2704
150
152
  hestia_earth/models/geospatialDatabase/siltContent.py,sha256=0GnBZHjqS_Py4730s4LqzQ_GikBSxFyUGYG4dEiXiGs,2162
151
153
  hestia_earth/models/geospatialDatabase/slope.py,sha256=g1SpuYks60injv2w-CMjESNfu8KM1JsiYnRT9XZfSuY,1859
152
154
  hestia_earth/models/geospatialDatabase/slopeLength.py,sha256=6pGr1qR0EiiUKkeflpYut7eI6UsnXAzHDoHhAzXKFJk,1864
153
155
  hestia_earth/models/geospatialDatabase/soilPh.py,sha256=egvtnVPCL0El2J9oVLAFxl6HoZQsK-RrNobA0LMAtOY,2109
154
- hestia_earth/models/geospatialDatabase/temperatureAnnual.py,sha256=PJGFvudYZgYiwVoY2h8jkO8tJb-hoBgVTzupemPH1WQ,2814
156
+ hestia_earth/models/geospatialDatabase/temperatureAnnual.py,sha256=0UwONdo7ClGQ6mxg44ghT_KGpDXXoJwesDHTv-yZAyk,2806
155
157
  hestia_earth/models/geospatialDatabase/temperatureLongTermAnnualMean.py,sha256=G276JqkPwZsMH7fexrjPCwVfWGYzS7mHLag2UsiqjIs,2261
158
+ hestia_earth/models/geospatialDatabase/temperatureMonthly.py,sha256=LtYPegS3m8K8ZQ3HVBcca5Pr-ffIaAF62hwPGVe-vCo,3282
156
159
  hestia_earth/models/geospatialDatabase/totalNitrogenPerKgSoil.py,sha256=kjP3ue-tlzMQNx2hBM56_CBBRa8Pcosmd2BPgyiNVW4,2081
157
160
  hestia_earth/models/geospatialDatabase/totalPhosphorusPerKgSoil.py,sha256=5oasLMYgfnPwSse0D8EEe_pV57AMusac853BgVSUh5E,2070
158
- hestia_earth/models/geospatialDatabase/utils.py,sha256=zCwT9PfC38gTbmhMI-Pz-AM0JAEOYG2j_4s_pxonBlc,5876
161
+ hestia_earth/models/geospatialDatabase/utils.py,sha256=VmzT7r-o_7wnABlnu49q-H6CAVJD5D9Zmz-Po2jkNe4,6081
159
162
  hestia_earth/models/geospatialDatabase/waterDepth.py,sha256=Xy2UxwAJrgdOkcw59NetEHMt5vgRYE6qg4fgXb1ptlU,1643
160
163
  hestia_earth/models/globalCropWaterModel2008/__init__.py,sha256=vQxexzFCl2Uv2RiIJfcppkRi9RgzBsJ68yhVDK4GvAU,425
161
164
  hestia_earth/models/globalCropWaterModel2008/rootingDepth.py,sha256=pajS-6UWxqIqnzW0IjkgNm-2Vl3bMor2UZOQtQQERuc,4096
@@ -245,7 +248,7 @@ hestia_earth/models/ipcc2019/no3ToGroundwaterInorganicFertiliser.py,sha256=wTvMB
245
248
  hestia_earth/models/ipcc2019/no3ToGroundwaterOrganicFertiliser.py,sha256=zOhp6NhYUuUNU_LMMwhZBP78YC2XRWRlGnajBUX2AN8,3095
246
249
  hestia_earth/models/ipcc2019/noxToAirInorganicFertiliser.py,sha256=D-UyzY55mOiIcXRzEtvPY-r1bDFgb9YqA08SmHsQeNA,4226
247
250
  hestia_earth/models/ipcc2019/noxToAirOrganicFertiliser.py,sha256=SVgVNp76bIv9oUjrZZuI6xYLo4Gw2DRU5tbp14gydOE,3911
248
- hestia_earth/models/ipcc2019/organicCarbonPerHa.py,sha256=9zWmAolHbFuvw2dxK4zZ8bW-1VDy7j44DYPmspJ0U-M,142577
251
+ hestia_earth/models/ipcc2019/organicCarbonPerHa.py,sha256=QmSoBEmkrukZz4rwXDRoW_vDrfF5yopBrrFcf10BGio,141999
249
252
  hestia_earth/models/ipcc2019/pastureGrass.py,sha256=CpDEtdnbKd_8eaDLcflJ-dGik3t879HIoEIzuaHNmC0,23168
250
253
  hestia_earth/models/ipcc2019/utils.py,sha256=MSDMu15D9DnilFUgi4_6jYXC0FaKso3OODauGTMB6hs,6229
251
254
  hestia_earth/models/ipcc2021/__init__.py,sha256=VTgGFKhwMmk_nuI1RRq0in27fHYVPBonlXlPK00K8no,409
@@ -348,7 +351,7 @@ hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystems
348
351
  hestia_earth/models/linkedImpactAssessment/__init__.py,sha256=GZb-7uylALKNabUQaPjwekZHqBBeVCuL3wG2OzHeEo8,4565
349
352
  hestia_earth/models/mocking/__init__.py,sha256=kmSeOTSvurMUxw7Ajhf3G-SVPQ1NgmirMTk4TSOEicY,765
350
353
  hestia_earth/models/mocking/mock_search.py,sha256=V-ycVBTkJu7PP37Ivy_16hpKBV4aEtJb5S9DfChPNSU,2038
351
- hestia_earth/models/mocking/search-results.json,sha256=lqiVVybBoRY40119-ykY8FND8RfzK0WLCcBKlQzHE-8,39777
354
+ hestia_earth/models/mocking/search-results.json,sha256=TUYddNUVoFlEpTTglJq5Xkg4nt0pZTSSadUzh6Ehrsw,39779
352
355
  hestia_earth/models/pooreNemecek2018/__init__.py,sha256=nPboL7ULJzL5nJD5q7q9VOZt_fxbKVm8fmn1Az5YkVY,417
353
356
  hestia_earth/models/pooreNemecek2018/aboveGroundCropResidueTotal.py,sha256=Qt-mel4dkhK6N5uUOutNOinCTFjbjtGzITaaI0LvYc4,2396
354
357
  hestia_earth/models/pooreNemecek2018/belowGroundCropResidue.py,sha256=JT0RybbvWVlo01FO8K0Yj41HrEaJT3Kj1xfayr2X-xw,2315
@@ -441,7 +444,7 @@ hestia_earth/models/schmidt2007/utils.py,sha256=pQ76IBWMwi10Wa5PjsehtdnOMw-GVgDt
441
444
  hestia_earth/models/site/__init__.py,sha256=aVuLLhq0OQVm-_MZoq4JAKMidqexUWJBg_7mmojmDzc,405
442
445
  hestia_earth/models/site/cationExchangeCapacityPerKgSoil.py,sha256=0eH4A-tXJ0hvIkiYXWxlx8TfrdbIKUGYUDk97-yQJgg,3653
443
446
  hestia_earth/models/site/flowingWater.py,sha256=0ZuSXMr3EUTY3wsy8hdfuXeZcNX-n3D45MfX3dwyaeA,1728
444
- hestia_earth/models/site/management.py,sha256=3jZuDfBVoSuG9xCXYVv3yVLmzxvQvejvZ23FZTkGeO8,5402
447
+ hestia_earth/models/site/management.py,sha256=3xKv2DCsSSqjJCaOqB1JzhGgV-yywk6Pu1CqgILCh-A,5400
445
448
  hestia_earth/models/site/netPrimaryProduction.py,sha256=UIIQkYd911qVzrWjxBLrC37e-RARIVgDwLdARY9BuLw,1849
446
449
  hestia_earth/models/site/organicCarbonPerHa.py,sha256=gcmhZavc2EWvkroKkpFM5xXowPTgyXGh1XL6lgs3CX4,14303
447
450
  hestia_earth/models/site/organicCarbonPerKgSoil.py,sha256=t--wAshiAKS-JvEKhLFRadGvgSBv5NFZ68jdyms_wh4,1945
@@ -458,14 +461,14 @@ hestia_earth/models/site/soilMeasurement.py,sha256=pFh7-lpcBrvpOZ071XhadpuK_5Aoy
458
461
  hestia_earth/models/site/temperatureAnnual.py,sha256=Q3b1RH2_hpA0JWwOYA5nKgMGcXHjV8-akXT9vB0cbwc,2012
459
462
  hestia_earth/models/site/temperatureMonthly.py,sha256=yXwpFCGT2tUqvVBNedaPyBmN_KlzZqo5yv2TWem1pBk,1890
460
463
  hestia_earth/models/site/totalNitrogenPerKgSoil.py,sha256=8ERrTZpN_yCRUyFg_EYaX4abE9jLcyX3lx3MO4Bi6CE,1938
461
- hestia_earth/models/site/utils.py,sha256=sX-U-Edomaw5hhXZVQJ5ugWJmk8-jpdgWts6xDaulRo,3303
464
+ hestia_earth/models/site/utils.py,sha256=b5y6jNmTclC1Vs8FzwW22u3sVyFsvs5if3NJzvLZQLs,3176
462
465
  hestia_earth/models/site/waterDepth.py,sha256=uasApPdOzibZMiOyKNKr_ajAkzwUEEPm1j0FNEy49TY,1293
463
466
  hestia_earth/models/site/measurement/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
464
467
  hestia_earth/models/site/measurement/value.py,sha256=7IhUbIj7n5vB7yXoNxXsWbliEJjg1Ww3T5g_P2IyNCU,1661
465
468
  hestia_earth/models/site/post_checks/__init__.py,sha256=CkExxesk1GuG8NjrbKfix1iDuVUgU-9i1ccM_X7MZn4,284
466
469
  hestia_earth/models/site/post_checks/cache.py,sha256=_MZsNsclecUdHDT2MsYx4cEsVUXydIasddgZNA6SU4k,284
467
470
  hestia_earth/models/site/pre_checks/__init__.py,sha256=fjv6nU5fiL-CLyaa-cBpiLB-xujgPzeK7i7ZJuTOjCI,394
468
- hestia_earth/models/site/pre_checks/cache_geospatialDatabase.py,sha256=9JwbsKl8Pgmh4HuHZcRUnObBViWom0wZFGTOHN_Iaao,4078
471
+ hestia_earth/models/site/pre_checks/cache_geospatialDatabase.py,sha256=XmAJAohSQQwbjqx-xTqB6LuU4lyz5lcG8njVuWFDGsU,4820
469
472
  hestia_earth/models/site/pre_checks/cache_sources.py,sha256=RzvSgHJTpVkAB3mEvRju_irDQmdJRK7GUdU6PhS2Gaw,904
470
473
  hestia_earth/models/site/pre_checks/cache_years.py,sha256=qGwTaHlWxnVT7iVxXVcpJ-oG6M-VH4ZpCDTdTixUHR4,883
471
474
  hestia_earth/models/stehfestBouwman2006/__init__.py,sha256=EhvD4NK6oEPevusLb1WdYV3GT_fCtQx4gvdMhK_dEIQ,420
@@ -498,7 +501,7 @@ hestia_earth/models/transformation/product/__init__.py,sha256=47DEQpj8HBSa-_TImW
498
501
  hestia_earth/models/transformation/product/excreta.py,sha256=Yj9wMF5if-zivb6qbN3vy1X51ZNYxvoyG9f4KPp3Y18,5700
499
502
  hestia_earth/models/usetoxV2/__init__.py,sha256=pK37V3H-KvYcvRKw4Mv8CWrB2N0LFLzmv0jKLdhGGqs,409
500
503
  hestia_earth/models/usetoxV2/freshwaterEcotoxicityPotentialCtue.py,sha256=oYNwThnMXjZymif5buyHiczFiOq_61jOdDMOAyy8vwQ,1018
501
- hestia_earth/models/utils/__init__.py,sha256=ooBopT4rd4fO_zx07tJ2-RTCaLpuQzoh-xIwAb5kCG4,3997
504
+ hestia_earth/models/utils/__init__.py,sha256=-kuwCLmQOihU3n1RxqhojRa3Izd6PGOqA30k7qKl4vc,4275
502
505
  hestia_earth/models/utils/aggregated.py,sha256=sz6usleZmo_tC_hIvmGgYsX8-H0dulXmmhHK4EkA5Kg,4946
503
506
  hestia_earth/models/utils/animalProduct.py,sha256=JA-xGQiwsz-VPR_8UfI5hKa918bpQOWIok3--b_iVuM,681
504
507
  hestia_earth/models/utils/aquacultureManagement.py,sha256=3uSTSMDNNPa26NTJGZCYwByv3QZVyxj6bh2aFCoBzHk,126
@@ -527,7 +530,7 @@ hestia_earth/models/utils/practice.py,sha256=tNadOzsrNlCEt801B815XaruJXzZ5yPASam
527
530
  hestia_earth/models/utils/product.py,sha256=XwxrRwdREWc4N5cE0oLJbLdEucKFRKgKNDj-Kd8mZEQ,9837
528
531
  hestia_earth/models/utils/productivity.py,sha256=bUBVCZInGqHuHZvHDSYPQkjWXQxOtTjEk-1-f_BsFOo,594
529
532
  hestia_earth/models/utils/property.py,sha256=7UV9pxSX49RnUsbEqOeohzxyXXShao1XAnEYCCVKS0k,4923
530
- hestia_earth/models/utils/site.py,sha256=4i6rjvFIzOEcsNcF1B9I8OFdVR_iFDODcWgq2_XFXfc,3155
533
+ hestia_earth/models/utils/site.py,sha256=OhSpyDqVwnIglBtoa3iUImzVr0Xj254oYR1wMiAiOHs,3176
531
534
  hestia_earth/models/utils/source.py,sha256=HhZkvQoFdy6j6FC2cwP5EbHXHFM4pif9gpnuzeDwEh4,1746
532
535
  hestia_earth/models/utils/temperature.py,sha256=ljlG4-yCgFFb6LRZweb18cZKLrr7K2mqd4E4Hz_D1f8,476
533
536
  hestia_earth/models/utils/term.py,sha256=_DahtnHIS5wtyEXew3gpV52QjnsAWQZmyxnz4fu6mrI,17780
@@ -668,8 +671,10 @@ tests/models/geospatialDatabase/test_nutrientLossToAquaticEnvironment.py,sha256=
668
671
  tests/models/geospatialDatabase/test_organicCarbonPerKgSoil.py,sha256=WomlRdVl4f6ooJz2YctPf0YGiNs-9To6XFwTdtpm0SQ,1024
669
672
  tests/models/geospatialDatabase/test_potentialEvapotranspirationAnnual.py,sha256=6s4XDmKi__njKE_3tFMIAHr0a1w7X4t8uFRtihN_cm4,706
670
673
  tests/models/geospatialDatabase/test_potentialEvapotranspirationLongTermAnnualMean.py,sha256=KzIXuYeO5IZ8l4tKsIEaWcFeV_vSPDSpR6xiuvt_x4o,1003
674
+ tests/models/geospatialDatabase/test_potentialEvapotranspirationMonthly.py,sha256=iu8HWAwl52fWDQJ_Nz5AZIAzbuMAjQfiQwxCHlciI-o,762
671
675
  tests/models/geospatialDatabase/test_precipitationAnnual.py,sha256=OhN7dbLZUG8ofvV7C56RKE_hGFXGtOuzXYz3EwFcQyg,744
672
676
  tests/models/geospatialDatabase/test_precipitationLongTermAnnualMean.py,sha256=wGGKXGemg3OEgDRRXy52oFf5p8jU57iraTgQMWDzusQ,1033
677
+ tests/models/geospatialDatabase/test_precipitationMonthly.py,sha256=FTmnMXqwxuV_FwNzx8ZJsF5DCdaOdXPNV9UQ5gFKALs,748
673
678
  tests/models/geospatialDatabase/test_region.py,sha256=5q3q5TK7yzvoZI2gknf-TPNcmDqVkMo0D3-KY401J2k,882
674
679
  tests/models/geospatialDatabase/test_sandContent.py,sha256=hvV0Z51hKPLoSBNsjLJ18upGSt3FUHYbp2ofx7fBUvU,1177
675
680
  tests/models/geospatialDatabase/test_siltContent.py,sha256=udJDh2gidlkQVkotxWjCCsXRkbvAQxfpFAjEj5dtNJE,1124
@@ -678,6 +683,7 @@ tests/models/geospatialDatabase/test_slopeLength.py,sha256=56iCm-qn41NpeVHU9dKtA
678
683
  tests/models/geospatialDatabase/test_soilPh.py,sha256=Xi-SQ9HesSbvpaUd97n7KbDhxLVZLh07mQ-YtOR0FZU,1008
679
684
  tests/models/geospatialDatabase/test_temperatureAnnual.py,sha256=1hW0fHUlFOAWiPqYZm4ZbTGqjpOAmLb1mkucnAaTrIQ,742
680
685
  tests/models/geospatialDatabase/test_temperatureLongTermAnnualMean.py,sha256=Wrz9dbDvXM0OgBA3mXpzY0WZk-yqIp980JRKenxFqno,1031
686
+ tests/models/geospatialDatabase/test_temperatureMonthly.py,sha256=eUaI1TZ-9sXFxWR2UoKBbca8dzW21zp5jGcfbooTt3M,746
681
687
  tests/models/geospatialDatabase/test_totalNitrogenPerKgSoil.py,sha256=_U3j5hqwYezG7e9v2WyO9ik2QJ9MqjM1QWPGkDChP7M,1024
682
688
  tests/models/geospatialDatabase/test_totalPhosphorusPerKgSoil.py,sha256=N5Vqf3YKlxHxWRe1PP3Kpbd30bhPOsB8eYr2IGS7quk,1026
683
689
  tests/models/geospatialDatabase/test_utils.py,sha256=2AOTtxs7KjPUVQXyErHsm7578523a5WNODVbbuxafAY,758
@@ -769,7 +775,7 @@ tests/models/ipcc2019/test_no3ToGroundwaterInorganicFertiliser.py,sha256=e7REnQ9
769
775
  tests/models/ipcc2019/test_no3ToGroundwaterOrganicFertiliser.py,sha256=e1ZViD12qB3bLdH3TJw3GbBP8iqMen-UJbcFkytb3VQ,1609
770
776
  tests/models/ipcc2019/test_noxToAirInorganicFertiliser.py,sha256=NZBSBJLM_j2PEpHRON2ysgKNF8x5sHfQVoAKQdGsfzk,1537
771
777
  tests/models/ipcc2019/test_noxToAirOrganicFertiliser.py,sha256=LR5pjV5vRbgSSQAw8kYRp_ij4CHInzgaDS6EggQuBiw,1104
772
- tests/models/ipcc2019/test_organicCarbonPerHa.py,sha256=g6EYKDiotsmod8zup2316g3auvy3cdGncaZ_2rO03Fg,21876
778
+ tests/models/ipcc2019/test_organicCarbonPerHa.py,sha256=QTo8GL_jXNRH_r8fgt0K9Z_QEP9PjuRN6N0fyyebAj0,21346
773
779
  tests/models/ipcc2019/test_pastureGrass.py,sha256=pE4PWdR541v4xWDYihP7Dou8V1iqg5GwD5_rjGRzrds,2292
774
780
  tests/models/ipcc2021/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
775
781
  tests/models/ipcc2021/test_gwp100.py,sha256=JRklKMSg-OXopb9ZufGgl94deuMuJSsfNXRZDBtOZrE,1119
@@ -958,7 +964,7 @@ tests/models/schmidt2007/test_utils.py,sha256=rmtOV3xiFynjgx8lQNGsJqquG8HDxz3LDm
958
964
  tests/models/site/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
959
965
  tests/models/site/test_cationExchangeCapacityPerKgSoil.py,sha256=tNMhN998vcjQ15I-5mNnFh2d7mHzEBIBO6o1VSfQNUE,1075
960
966
  tests/models/site/test_flowingWater.py,sha256=t_rxvdlmUVDsFBoDF20_zDM-0iiLKkNCV7knO9l1T7o,1370
961
- tests/models/site/test_management.py,sha256=wwXuaIaGz5kh65PPXqp9WvvlKYSCNFZQoHJMU-mKJ-4,3779
967
+ tests/models/site/test_management.py,sha256=dY_1QlIbnm-cQruD7DQT6fhWezC63X3B4yknq8d6RIQ,3774
962
968
  tests/models/site/test_netPrimaryProduction.py,sha256=JCxG0MODbKVvl3hOqmKzh4FjHYn3Xs9KsVod6LvKQII,1108
963
969
  tests/models/site/test_organicCarbonPerHa.py,sha256=6Qtc0Xmveir7MmNF4Ekv5YkV92TNp8GfDnURPVg05-4,3471
964
970
  tests/models/site/test_organicCarbonPerKgSoil.py,sha256=0M-NMg_T3UXzGT_VlKOKhSxg4cZ0_zhd3FRgY5Hpj6o,1087
@@ -1028,13 +1034,13 @@ tests/models/utils/test_measurement.py,sha256=Sl5dPZgu1Nrb7kliFiUpx-kEH81v7MdxiH
1028
1034
  tests/models/utils/test_practice.py,sha256=ILaxkb3qICor9AquAGYiOtA-YKnq0hppmJQzNC_VNyA,612
1029
1035
  tests/models/utils/test_product.py,sha256=kwvgAeeEoRgkeStX0zQcFd-4DJhoUhX6Apaks0MU2L0,2305
1030
1036
  tests/models/utils/test_property.py,sha256=t2npw86IK7C6G4ypiPtanFi0db4PB7G5VBR1GjRGl34,618
1031
- tests/models/utils/test_site.py,sha256=cSKrkLeerymMLZAwCnbQce38NwgxXojQHAVm9DPUTpg,1181
1037
+ tests/models/utils/test_site.py,sha256=5nCW3onTk6GF_N-h4NYDrlSoxHhXY2GVMbjaDsicbSE,1187
1032
1038
  tests/models/utils/test_source.py,sha256=mv3vHZV5cjpoLA2I1109-YUkuzAiuhbRSnv_76_f0CA,631
1033
1039
  tests/models/utils/test_term.py,sha256=JJmzyHnhVGeQ7tG-T6DjE7CoIJPH0guH-y2kjGeZiJY,3756
1034
1040
  tests/models/webbEtAl2012AndSintermannEtAl2012/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1035
1041
  tests/models/webbEtAl2012AndSintermannEtAl2012/test_nh3ToAirOrganicFertiliser.py,sha256=qi2FNXS5Af2WDtm7nq_FsprH3BfCF0XxnE0XHmC4aIY,2244
1036
- hestia_earth_models-0.59.3.dist-info/LICENSE,sha256=EFSZhfUdZCTsCIYdHzTGewMKfRfp7X9t1s2aaKxm8O0,1154
1037
- hestia_earth_models-0.59.3.dist-info/METADATA,sha256=gyNoaOgImXrijST_O_SKIa6sDSY9vSDOJA0716l11uU,3134
1038
- hestia_earth_models-0.59.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1039
- hestia_earth_models-0.59.3.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1040
- hestia_earth_models-0.59.3.dist-info/RECORD,,
1042
+ hestia_earth_models-0.59.4.dist-info/LICENSE,sha256=EFSZhfUdZCTsCIYdHzTGewMKfRfp7X9t1s2aaKxm8O0,1154
1043
+ hestia_earth_models-0.59.4.dist-info/METADATA,sha256=GRtBR9ZzqxPAH4asis3_RYiwPtga8Kk-Rs5Yfefk318,3134
1044
+ hestia_earth_models-0.59.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
1045
+ hestia_earth_models-0.59.4.dist-info/top_level.txt,sha256=1dqA9TqpOLTEgpqa-YBsmbCmmNU1y56AtfFGEceZ2A0,19
1046
+ hestia_earth_models-0.59.4.dist-info/RECORD,,
@@ -0,0 +1,20 @@
1
+ from unittest.mock import patch
2
+ import json
3
+ from tests.utils import fixtures_path, fake_new_measurement
4
+
5
+ from hestia_earth.models.geospatialDatabase.potentialEvapotranspirationMonthly 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}.get_source", return_value={})
12
+ @patch(f"{class_path}._new_measurement", side_effect=fake_new_measurement)
13
+ @patch(f"{class_path}.related_years", return_value=['2009'])
14
+ @patch(f"{class_path}.download", return_value=None)
15
+ def test_run(mock_download, *args):
16
+ with open(f"{fixtures_path}/{MODEL}/site.jsonld", encoding='utf-8') as f:
17
+ site = json.load(f)
18
+
19
+ run(site)
20
+ assert mock_download.call_count == 12
@@ -0,0 +1,20 @@
1
+ from unittest.mock import patch
2
+ import json
3
+ from tests.utils import fixtures_path, fake_new_measurement
4
+
5
+ from hestia_earth.models.geospatialDatabase.precipitationMonthly 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}.get_source", return_value={})
12
+ @patch(f"{class_path}._new_measurement", side_effect=fake_new_measurement)
13
+ @patch(f"{class_path}.related_years", return_value=['2009'])
14
+ @patch(f"{class_path}.download", return_value=None)
15
+ def test_run(mock_download, *args):
16
+ with open(f"{fixtures_path}/{MODEL}/site.jsonld", encoding='utf-8') as f:
17
+ site = json.load(f)
18
+
19
+ run(site)
20
+ assert mock_download.call_count == 12
@@ -0,0 +1,20 @@
1
+ from unittest.mock import patch
2
+ import json
3
+ from tests.utils import fixtures_path, fake_new_measurement
4
+
5
+ from hestia_earth.models.geospatialDatabase.temperatureMonthly 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}.get_source", return_value={})
12
+ @patch(f"{class_path}._new_measurement", side_effect=fake_new_measurement)
13
+ @patch(f"{class_path}.related_years", return_value=['2009'])
14
+ @patch(f"{class_path}.download", return_value=None)
15
+ def test_run(mock_download, *args):
16
+ with open(f"{fixtures_path}/{MODEL}/site.jsonld", encoding='utf-8') as f:
17
+ site = json.load(f)
18
+
19
+ run(site)
20
+ assert mock_download.call_count == 12
@@ -16,7 +16,6 @@ from hestia_earth.models.ipcc2019.organicCarbonPerHa import (
16
16
  _calc_temperature_factor,
17
17
  _calc_tier_1_soc_stocks,
18
18
  _calc_water_factor,
19
- _calculated_cycles,
20
19
  _check_cropland_low_category,
21
20
  _check_cropland_medium_category,
22
21
  _get_carbon_input_kwargs,
@@ -146,11 +145,11 @@ RUN_SUBFOLDERS = [
146
145
  @patch(f"{class_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
147
146
  @patch(f"{class_path}.get_upland_rice_land_cover_terms", return_value=UPLAND_RICE_LAND_COVER_TERM_IDS)
148
147
  @patch(f"{class_path}.get_upland_rice_crop_terms", return_value=UPLAND_RICE_CROP_TERM_IDS)
149
- @patch(f"{class_path}._calculated_cycles")
148
+ @patch(f"{class_path}.related_cycles")
150
149
  @patch("hestia_earth.models.utils.property.find_term_property")
151
150
  def test_run(
152
151
  mock_find_term_property,
153
- mock_calculated_cycles,
152
+ mock_related_cycles,
154
153
  _mock_get_upland_rice_crop_terms,
155
154
  _mock_get_upland_rice_land_cover_terms,
156
155
  _mock_get_residue_removed_or_burnt_terms,
@@ -169,7 +168,7 @@ def test_run(
169
168
  return json.load(f)
170
169
 
171
170
  mock_find_term_property.side_effect = find_term_property_side_effect
172
- mock_calculated_cycles.return_value = load_cycles_from_file() if load_cycles else []
171
+ mock_related_cycles.return_value = load_cycles_from_file() if load_cycles else []
173
172
 
174
173
  with open(f"{folder}/site.jsonld", encoding='utf-8') as f:
175
174
  site = json.load(f)
@@ -189,7 +188,7 @@ def test_run(
189
188
  @patch(f"{class_path}.get_residue_removed_or_burnt_terms", return_value=RESIDUE_REMOVED_OR_BURNT_TERM_IDS)
190
189
  @patch(f"{class_path}.get_upland_rice_land_cover_terms", return_value=UPLAND_RICE_LAND_COVER_TERM_IDS)
191
190
  @patch(f"{class_path}.get_upland_rice_crop_terms", return_value=UPLAND_RICE_CROP_TERM_IDS)
192
- @patch(f"{class_path}._calculated_cycles", return_value=[])
191
+ @patch(f"{class_path}.related_cycles", return_value=[])
193
192
  def test_run_no_data(*args):
194
193
  SITE = {}
195
194
  EXPECTED = []
@@ -234,22 +233,6 @@ def test_calc_water_factor():
234
233
  assert _calc_water_factor(1, 1) == _calc_water_factor(1000, 1000)
235
234
 
236
235
 
237
- @patch(f"{class_path}.find_related")
238
- @patch("hestia_earth.models.utils.download_hestia")
239
- def test_calculated_cycles(mock_download_hestia, mock_find_related):
240
- CYCLES = [{"@id": "cycle"}]
241
- EXPECTED = [{"@id": "cycle", "@type": "Cycle"}]
242
-
243
- mock_download_hestia.side_effect = lambda node_id, node_type, **_: {
244
- "@type": node_type.value,
245
- "@id": node_id
246
- }
247
- mock_find_related.return_value = CYCLES
248
-
249
- result = _calculated_cycles({})
250
- assert EXPECTED == result
251
-
252
-
253
236
  # --- IPCC SOIL CATEGORY TESTS ---
254
237
 
255
238
 
@@ -2,7 +2,7 @@ import json
2
2
  from unittest.mock import patch
3
3
  from hestia_earth.schema import TermTermType
4
4
 
5
- from hestia_earth.models.site.management import MODEL, MODEL_KEY, run, should_run
5
+ from hestia_earth.models.site.management import MODEL, MODEL_KEY, run, _should_run
6
6
  from tests.utils import fixtures_path
7
7
 
8
8
  CLASS_PATH = f"hestia_earth.models.{MODEL}.{MODEL_KEY}"
@@ -18,13 +18,13 @@ TERM_BY_ID = {
18
18
  def test_should_run(mock_related_cycles, *args):
19
19
  # no cycles => do not run
20
20
  mock_related_cycles.return_value = []
21
- _should_run, *args = should_run({})
22
- assert _should_run is False
21
+ should_run, *args = _should_run({})
22
+ assert should_run is False
23
23
 
24
24
  # no products => do not run
25
25
  mock_related_cycles.return_value = [{"products": []}]
26
- _should_run, *args = should_run({})
27
- assert _should_run is False
26
+ should_run, *args = _should_run({})
27
+ assert should_run is False
28
28
 
29
29
  # with irrelevant termType => do not run
30
30
  mock_related_cycles.return_value = [
@@ -37,8 +37,8 @@ def test_should_run(mock_related_cycles, *args):
37
37
  "endDate": "2022"
38
38
  }
39
39
  ]
40
- _should_run, *args = should_run({})
41
- assert _should_run is False
40
+ should_run, *args = _should_run({})
41
+ assert should_run is False
42
42
 
43
43
  # products and practices but no relevant terms/termTypes => do not run
44
44
  mock_related_cycles.return_value = [
@@ -53,8 +53,8 @@ def test_should_run(mock_related_cycles, *args):
53
53
  ]
54
54
  }
55
55
  ]
56
- _should_run, *args = should_run({})
57
- assert _should_run is False
56
+ should_run, *args = _should_run({})
57
+ assert should_run is False
58
58
 
59
59
  # # practices with relevant termType => run
60
60
  mock_related_cycles.return_value = [
@@ -67,8 +67,8 @@ def test_should_run(mock_related_cycles, *args):
67
67
  "endDate": "2022"
68
68
  }
69
69
  ]
70
- _should_run, *args = should_run({})
71
- assert _should_run is True
70
+ should_run, *args = _should_run({})
71
+ assert should_run is True
72
72
 
73
73
  # with relevant product => run
74
74
  mock_related_cycles.return_value = [
@@ -89,8 +89,8 @@ def test_should_run(mock_related_cycles, *args):
89
89
  "endDate": "2022"
90
90
  }
91
91
  ]
92
- _should_run, *args = should_run({})
93
- assert _should_run is True
92
+ should_run, *args = _should_run({})
93
+ assert should_run is True
94
94
  assert args[0] == [{
95
95
  'term': TERM_BY_ID['genericCropPlant'],
96
96
  'value': 100,
@@ -19,7 +19,7 @@ def test_region_level_1_id():
19
19
 
20
20
 
21
21
  @patch(f"{class_path}.find_related", return_value=[CYCLE])
22
- @patch(f"{class_path}.download_hestia", return_value=CYCLE)
22
+ @patch(f"{class_path}._load_calculated_node", return_value=CYCLE)
23
23
  def test_related_cycles(*args):
24
24
  assert related_cycles('id') == [CYCLE]
25
25