hestia-earth-models 0.61.6__py3-none-any.whl → 0.61.8__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 (52) hide show
  1. hestia_earth/models/cycle/completeness/electricityFuel.py +56 -0
  2. hestia_earth/models/cycle/input/hestiaAggregatedData.py +1 -1
  3. hestia_earth/models/emepEea2019/nh3ToAirInorganicFertiliser.py +44 -59
  4. hestia_earth/models/geospatialDatabase/histosol.py +4 -0
  5. hestia_earth/models/ipcc2006/co2ToAirOrganicSoilCultivation.py +4 -2
  6. hestia_earth/models/ipcc2006/n2OToAirOrganicSoilCultivationDirect.py +1 -1
  7. hestia_earth/models/ipcc2019/aboveGroundCropResidueTotal.py +1 -1
  8. hestia_earth/models/ipcc2019/belowGroundCropResidue.py +1 -1
  9. hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +1 -1
  10. hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChangeManagementChange.py +511 -458
  11. hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +5 -1
  12. hestia_earth/models/ipcc2019/organicCarbonPerHa.py +117 -3881
  13. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +2060 -0
  14. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +1630 -0
  15. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +324 -0
  16. hestia_earth/models/mocking/search-results.json +360 -260
  17. hestia_earth/models/schererPfister2015/pToDrainageWaterSoilFlux.py +1 -1
  18. hestia_earth/models/schererPfister2015/pToGroundwaterSoilFlux.py +1 -1
  19. hestia_earth/models/site/organicCarbonPerHa.py +58 -44
  20. hestia_earth/models/site/soilMeasurement.py +25 -38
  21. hestia_earth/models/utils/__init__.py +28 -0
  22. hestia_earth/models/utils/aquacultureManagement.py +2 -2
  23. hestia_earth/models/utils/array_builders.py +578 -0
  24. hestia_earth/models/utils/blank_node.py +2 -3
  25. hestia_earth/models/utils/crop.py +24 -1
  26. hestia_earth/models/utils/cycle.py +0 -23
  27. hestia_earth/models/utils/descriptive_stats.py +285 -0
  28. hestia_earth/models/utils/emission.py +73 -2
  29. hestia_earth/models/utils/inorganicFertiliser.py +2 -2
  30. hestia_earth/models/utils/lookup.py +6 -3
  31. hestia_earth/models/utils/measurement.py +118 -4
  32. hestia_earth/models/utils/site.py +25 -13
  33. hestia_earth/models/version.py +1 -1
  34. {hestia_earth_models-0.61.6.dist-info → hestia_earth_models-0.61.8.dist-info}/METADATA +1 -1
  35. {hestia_earth_models-0.61.6.dist-info → hestia_earth_models-0.61.8.dist-info}/RECORD +52 -40
  36. tests/models/cycle/completeness/test_electricityFuel.py +21 -0
  37. tests/models/emepEea2019/test_nh3ToAirInorganicFertiliser.py +2 -2
  38. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChangeManagementChange.py +54 -165
  39. tests/models/ipcc2019/test_organicCarbonPerHa.py +219 -460
  40. tests/models/ipcc2019/test_organicCarbonPerHa_tier_1_utils.py +471 -0
  41. tests/models/ipcc2019/test_organicCarbonPerHa_tier_2_utils.py +208 -0
  42. tests/models/ipcc2019/test_organicCarbonPerHa_utils.py +75 -0
  43. tests/models/site/test_organicCarbonPerHa.py +3 -12
  44. tests/models/site/test_soilMeasurement.py +5 -19
  45. tests/models/utils/test_array_builders.py +253 -0
  46. tests/models/utils/{test_cycle.py → test_crop.py} +2 -2
  47. tests/models/utils/test_descriptive_stats.py +134 -0
  48. tests/models/utils/test_emission.py +51 -1
  49. tests/models/utils/test_measurement.py +54 -2
  50. {hestia_earth_models-0.61.6.dist-info → hestia_earth_models-0.61.8.dist-info}/LICENSE +0 -0
  51. {hestia_earth_models-0.61.6.dist-info → hestia_earth_models-0.61.8.dist-info}/WHEEL +0 -0
  52. {hestia_earth_models-0.61.6.dist-info → hestia_earth_models-0.61.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,578 @@
1
+ """
2
+ Based on code by Cool Farm Tool:
3
+ https://gitlab.com/MethodsCFT/coolfarm-soc/-/blob/main/src/cfasoc/builders.py
4
+ """
5
+ import hashlib
6
+ from numpy import array, concatenate, cumsum, full, hstack, random, mean, prod, vstack
7
+ from numpy.typing import NDArray, DTypeLike
8
+ from typing import Union
9
+
10
+ from .descriptive_stats import calc_z_critical
11
+
12
+
13
+ def repeat_single(shape: tuple, value: float, dtype: DTypeLike = None) -> NDArray:
14
+ """
15
+ Repeat a single value to form an array of a defined shape.
16
+
17
+ Parameters
18
+ ----------
19
+ shape : tuple
20
+ Shape (rows, columns).
21
+ value : float
22
+ Value to be repeated.
23
+ dtype : DTypeLike, optional
24
+ The desired data-type for the array.
25
+
26
+ Returns
27
+ -------
28
+ NDArray
29
+ Array with repeated value.
30
+ """
31
+ return full(shape=shape, fill_value=value, dtype=dtype)
32
+
33
+
34
+ def repeat_array_as_columns(n_iterations: int, array: NDArray) -> NDArray:
35
+ """
36
+ Repeat a numpy array horizontally as columns.
37
+
38
+ Parameters
39
+ ----------
40
+ n_iterations : int
41
+ Number of times the columns should be repeated.
42
+ array : NDArray
43
+ Array to repeat.
44
+
45
+ Returns
46
+ -------
47
+ NDArray
48
+ Repeated array.
49
+ """
50
+ return hstack([array for _ in range(n_iterations)])
51
+
52
+
53
+ def repeat_array_as_rows(n_iterations: int, array: NDArray) -> NDArray:
54
+ """
55
+ Repeat a numpy array vertically as rows.
56
+
57
+ Parameters
58
+ ----------
59
+ n_iterations : int
60
+ Number of times the rows should be repeated.
61
+ array : NDArray
62
+ Array to repeat.
63
+
64
+ Returns
65
+ -------
66
+ NDArray
67
+ Repeated array.
68
+ """
69
+ return vstack([array for _ in range(n_iterations)])
70
+
71
+
72
+ def repeat_1d_array_as_columns(n_columns: int, column: NDArray) -> NDArray:
73
+ """
74
+ Repeat a column (NDArray) to form an array of a defined shape
75
+
76
+ Parameters
77
+ ----------
78
+ n_columns : int
79
+ How many times the column (NDArray) should be repeated.
80
+ column : NDArray
81
+ The column (NDArray) to be repeated.
82
+
83
+ Returns
84
+ -------
85
+ NDArray
86
+ Repeated array.
87
+ """
88
+ return vstack([column for _ in range(n_columns)]).transpose()
89
+
90
+
91
+ def discrete_uniform_1d(
92
+ shape: tuple, low: float, high: float, seed: Union[int, random.Generator, None] = None
93
+ ) -> NDArray:
94
+ """
95
+ Sample from a discrete uniform distribution and produce an array of a specified shape.
96
+ All rows in a specified column will have the same sample value, but each column will be different (1 dimensional
97
+ variability).
98
+
99
+ Parameters
100
+ ----------
101
+ shape : tuple
102
+ Shape (rows, columns).
103
+ low : float
104
+ Lower bound of the discrete uniform distribution to be sampled.
105
+ high : float
106
+ Upper bound of the discrete uniform distribution to be sampled.
107
+ seed : int | Generator | None, optional
108
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
109
+ fresh, unpredictable entropy will be pulled from the OS.
110
+
111
+ Returns
112
+ -------
113
+ NDArray
114
+ Array of samples with 1 dimensional variability.
115
+ """
116
+ n_rows, n_columns = shape
117
+ rng = random.default_rng(seed)
118
+ return repeat_array_as_rows(
119
+ n_rows,
120
+ rng.uniform(low=low, high=high, size=n_columns)
121
+ )
122
+
123
+
124
+ def discrete_uniform_2d(
125
+ shape: tuple, low: float, high: float, seed: Union[int, random.Generator, None] = None
126
+ ) -> NDArray:
127
+ """
128
+ Sample from a discrete uniform distribution and produce an array of a specified shape.
129
+ All rows and columns contain different sample values (2 dimensional variability).
130
+
131
+ Parameters
132
+ ----------
133
+ shape : tuple
134
+ Shape (rows, columns).
135
+ low : float
136
+ Lower bound of the discrete uniform distribution to be sampled.
137
+ high : float
138
+ Upper bound of the discrete uniform distribution to be sampled.
139
+ seed : int | Generator | None, optional
140
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
141
+ fresh, unpredictable entropy will be pulled from the OS.
142
+
143
+ Returns
144
+ -------
145
+ NDArray
146
+ Array of samples with 2 dimensional variability.
147
+ """
148
+ rng = random.default_rng(seed)
149
+ return rng.uniform(low=low, high=high, size=shape)
150
+
151
+
152
+ def triangular_1d(
153
+ shape: tuple, low: float, high: float, mode: float, seed: Union[int, random.Generator, None] = None
154
+ ) -> NDArray:
155
+ """
156
+ Sample from a triangular distribution and produce an array of a specified shape.
157
+ All rows in a specified column will have the same sample value, but each column will be different (1 dimensional
158
+ variability).
159
+
160
+ Parameters
161
+ ----------
162
+ shape : tuple
163
+ Shape (rows, columns).
164
+ low : float
165
+ Lower bound of the triangular distribution to be sampled.
166
+ high : float
167
+ Upper bound of the triangular distribution to be sampled.
168
+ mode : float
169
+ Mode of the triangular distribution to be sampled.
170
+ seed : int | Generator | None, optional
171
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
172
+ fresh, unpredictable entropy will be pulled from the OS.
173
+
174
+ Returns
175
+ -------
176
+ NDArray
177
+ Array of samples with 1 dimensional variability.
178
+ """
179
+ n_rows, n_columns = shape
180
+ rng = random.default_rng(seed)
181
+ return repeat_array_as_rows(
182
+ n_rows,
183
+ rng.triangular(left=low, mode=mode, right=high, size=n_columns)
184
+ )
185
+
186
+
187
+ def triangular_2d(
188
+ shape: tuple, low: float, high: float, mode: float, seed: Union[int, random.Generator, None] = None
189
+ ) -> NDArray:
190
+ """
191
+ Sample from a triangular distribution and produce an array of a specified shape.
192
+ All rows and columns contain different sample values (2 dimensional variability).
193
+
194
+ Parameters
195
+ ----------
196
+ shape : tuple
197
+ Shape (rows, columns).
198
+ low : float
199
+ Lower bound of the triangular distribution to be sampled.
200
+ high : float
201
+ Upper bound of the triangular distribution to be sampled.
202
+ mode : float
203
+ Mode of the triangular distribution to be sampled.
204
+ seed : int | Generator | None, optional
205
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
206
+ fresh, unpredictable entropy will be pulled from the OS.
207
+
208
+ Returns
209
+ -------
210
+ NDArray
211
+ Array of samples with 2 dimensional variability.
212
+ """
213
+ rng = random.default_rng(seed)
214
+ return rng.triangular(left=low, mode=mode, right=high, size=shape)
215
+
216
+
217
+ def normal_1d(
218
+ shape: tuple, mu: float, sigma: float, seed: Union[int, random.Generator, None] = None
219
+ ) -> NDArray:
220
+ """
221
+ Sample from a normal distribution and produce an array of a specified shape.
222
+ All rows in a specified column will have the same sample value, but each column will be different (1 dimensional
223
+ variability).
224
+
225
+ Parameters
226
+ ----------
227
+ shape : tuple
228
+ Shape (rows, columns).
229
+ mu : float
230
+ Mean of the normal distribution to be sampled.
231
+ sigma : float
232
+ Standard deviation of the normal distribution to be sampled.
233
+ seed : int | Generator | None, optional
234
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
235
+ fresh, unpredictable entropy will be pulled from the OS.
236
+
237
+ Returns
238
+ -------
239
+ NDArray
240
+ Array of samples with 1 dimensional variability.
241
+ """
242
+ n_rows, n_columns = shape
243
+ rng = random.default_rng(seed)
244
+ return repeat_array_as_rows(
245
+ n_rows,
246
+ rng.normal(loc=mu, scale=sigma, size=n_columns)
247
+ )
248
+
249
+
250
+ def normal_2d(
251
+ shape: tuple, mu: float, sigma: float, seed: Union[int, random.Generator, None] = None
252
+ ) -> NDArray:
253
+ """
254
+ Sample from a normal distribution and produce an array of a specified shape.
255
+ All rows and columns contain different sample values (2 dimensional variability).
256
+
257
+ Parameters
258
+ ----------
259
+ shape : tuple
260
+ Shape (rows, columns).
261
+ mu : float
262
+ Mean of the normal distribution to be sampled.
263
+ sigma : float
264
+ Standard deviation of the normal distribution to be sampled.
265
+ seed : int | Generator | None, optional
266
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
267
+ fresh, unpredictable entropy will be pulled from the OS.
268
+
269
+ Returns
270
+ -------
271
+ NDArray
272
+ Array of samples with 2 dimensional variability.
273
+ """
274
+ rng = random.default_rng(seed)
275
+ return rng.normal(loc=mu, scale=sigma, size=shape)
276
+
277
+
278
+ def truncated_normal_1d(
279
+ shape: tuple, mu: float, sigma: float, low: float, high: float, seed: Union[int, random.Generator, None] = None
280
+ ) -> NDArray:
281
+ """
282
+ Sample from a truncated normal distribution and produce an array of a specified shape.
283
+ All rows in a specified column will have the same sample value, but each column will be different (1 dimensional
284
+ variability).
285
+
286
+ Parameters
287
+ ----------
288
+ shape : tuple
289
+ Shape (rows, columns).
290
+ mu : float
291
+ Mean of the normal distribution to be sampled.
292
+ sigma : float
293
+ Standard deviation of the normal distribution to be sampled.
294
+ low : float
295
+ Lower bound of the normal distribution to be sampled.
296
+ high : float
297
+ Upper bound of the normal distribution to be sampled.
298
+ seed : int | Generator | None, optional
299
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
300
+ fresh, unpredictable entropy will be pulled from the OS.
301
+
302
+ Returns
303
+ -------
304
+ NDArray
305
+ Array of samples with 1 dimensional variability.
306
+ """
307
+ n_rows, n_columns = shape
308
+ return repeat_array_as_rows(
309
+ n_rows,
310
+ _truncnorm_rvs(a=low, b=high, loc=mu, scale=sigma, shape=n_columns, seed=seed)
311
+ )
312
+
313
+
314
+ def truncated_normal_2d(
315
+ shape: tuple, mu: float, sigma: float, low: float, high: float, seed: Union[int, random.Generator, None] = None
316
+ ) -> NDArray:
317
+ """
318
+ Sample from a truncated normal distribution and produce an array of a specified shape.
319
+ All rows and columns contain different sample values (2 dimensional variability).
320
+
321
+ Parameters
322
+ ----------
323
+ shape : tuple
324
+ Shape (rows, columns).
325
+ mu : float
326
+ Mean of the normal distribution to be sampled.
327
+ sigma : float
328
+ Standard deviation of the normal distribution to be sampled.
329
+ low : float
330
+ Lower bound of the normal distribution to be sampled.
331
+ high : float
332
+ Upper bound of the normal distribution to be sampled.
333
+ seed : int | Generator | None, optional
334
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
335
+ fresh, unpredictable entropy will be pulled from the OS.
336
+
337
+ Returns
338
+ -------
339
+ NDArray
340
+ Array of samples with 2 dimensional variability.
341
+ """
342
+ return _truncnorm_rvs(a=low, b=high, loc=mu, scale=sigma, shape=shape, seed=seed)
343
+
344
+
345
+ def _truncnorm_rvs(
346
+ a: float,
347
+ b: float,
348
+ loc: float,
349
+ scale: float,
350
+ shape: Union[int, tuple[int, ...]],
351
+ seed: Union[int, random.Generator, None] = None
352
+ ) -> NDArray:
353
+ """
354
+ Generate random samples from a truncated normal distribution. Unlike the `scipy` equivalent, the `a` and `b` values
355
+ are the abscissae at which we wish to truncate the distribution (as opposed to the number of standard deviations
356
+ from `loc`).
357
+
358
+ Parameters
359
+ ----------
360
+ loc : float
361
+ Mean ("centre") of the distribution.
362
+ scale : float
363
+ Standard deviation (spread or "width") of the distribution. Must be non-negative.
364
+ size : int | tuple[int, ...]
365
+ Output shape. If the given shape is, e.g., (m, n, k), then m * n * k samples are drawn.
366
+ seed : int | Generator | None, optional
367
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
368
+ fresh, unpredictable entropy will be pulled from the OS.
369
+
370
+ Returns
371
+ -------
372
+ NDArray
373
+ Array of samples.
374
+ """
375
+ size = prod(shape)
376
+ samples = array([])
377
+ rng = random.default_rng(seed)
378
+
379
+ while samples.size < size:
380
+ samples_temp = rng.normal(loc, scale, (size - samples.size) * 2)
381
+ valid_samples = samples_temp[(a <= samples_temp) & (samples_temp <= b)]
382
+ samples = concatenate([samples, valid_samples])
383
+
384
+ return samples[:size].reshape(shape)
385
+
386
+
387
+ def plus_minus_uncertainty_to_normal_1d(
388
+ shape: tuple,
389
+ value: float,
390
+ uncertainty: float,
391
+ confidence_interval: float = 95,
392
+ seed: Union[int, random.Generator, None] = None
393
+ ) -> NDArray:
394
+ """
395
+ Return a normally distributed sample given a value and uncertainty expressed as +/- a percentage.
396
+
397
+ All rows in a specified column will have the same sample value, but each column will be different (1 dimensional
398
+ variability).
399
+
400
+ This function has been written to serve Table 5.5b on Page 5.32, Tier 2 Steady State Method for Mineral Soils,
401
+ Chapter 5 Cropland, 2019 Refinement to the 2006 IPCC Guidelines for National Greenhouse Gas Inventories. Table 5.5b
402
+ notes:
403
+
404
+ "Uncertainty is assumed to be ±75% for the N content estimates and ±50% for the lignin content estimates,
405
+ expressed as a 95% confidence intervals."
406
+
407
+ This function also serves Table 11.2 on Page 11.19, Tier 2 Steady State Method for Mineral Soils, Chapter 11 N2O
408
+ Emissions from Managed Soils, and CO2 Emissions from Lime and Urea Application, 2019 Refinement to the 2006 IPCC
409
+ Guidelines for National Greenhouse Gas Inventories.
410
+
411
+ Parameters
412
+ ----------
413
+ shape : tuple
414
+ Shape (rows, columns).
415
+ value : float
416
+ Reported value.
417
+ uncertainty : float
418
+ Uncertainty expressed as +/- a percentage.
419
+ confidence_interval : float
420
+ Confidence interval the uncertainty represents.
421
+ seed : int | Generator | None, optional
422
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
423
+ fresh, unpredictable entropy will be pulled from the OS.
424
+
425
+ Returns
426
+ -------
427
+ NDArray
428
+ Array of samples with 1 dimensional variability.
429
+ """
430
+ n_rows, n_columns = shape
431
+ n_sds = calc_z_critical(confidence_interval)
432
+ sigma = (value * (uncertainty / 100)) / n_sds
433
+ return repeat_array_as_rows(
434
+ n_rows,
435
+ normal_1d(shape=(1, n_columns), mu=value, sigma=sigma, seed=seed)
436
+ )
437
+
438
+
439
+ def plus_minus_uncertainty_to_normal_2d(
440
+ shape: tuple,
441
+ value: float,
442
+ uncertainty: float,
443
+ confidence_interval: float = 95,
444
+ seed: Union[int, random.Generator, None] = None
445
+ ) -> NDArray:
446
+ """
447
+ Return a normally distributed sample given a value and uncertainty expressed as +/- a percentage.
448
+
449
+ All rows and columns contain different sample values (2 dimensional variability).
450
+
451
+ This function has been written to serve Table 5.5b on Page 5.32, Tier 2 Steady State Method for Mineral Soils,
452
+ Chapter 5 Cropland, 2019 Refinement to the 2006 IPCC Guidelines for National Greenhouse Gas Inventories. Table 5.5b
453
+ notes:
454
+
455
+ "Uncertainty is assumed to be ±75% for the N content estimates and ±50% for the lignin content estimates,
456
+ expressed as a 95% confidence intervals."
457
+
458
+ This function also serves Table 11.2 on Page 11.19, Tier 2 Steady State Method for Mineral Soils, Chapter 11 N2O
459
+ Emissions from Managed Soils, and CO2 Emissions from Lime and Urea Application, 2019 Refinement to the 2006 IPCC
460
+ Guidelines for National Greenhouse Gas Inventories.
461
+
462
+ Parameters
463
+ ----------
464
+ shape : tuple
465
+ Shape (rows, columns).
466
+ value : float
467
+ Reported value.
468
+ uncertainty : float
469
+ Uncertainty expressed as +/- a percentage.
470
+ confidence_interval : float
471
+ Confidence interval the uncertainty represents.
472
+ seed : int | Generator | None, optional
473
+ A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
474
+ fresh, unpredictable entropy will be pulled from the OS.
475
+
476
+ Returns
477
+ -------
478
+ NDArray
479
+ Array of samples with 2 dimensional variability.
480
+ """
481
+ n_sds = calc_z_critical(confidence_interval)
482
+ sigma = (value * (uncertainty / 100)) / n_sds
483
+ return normal_2d(shape=shape, mu=value, sigma=sigma, seed=seed)
484
+
485
+
486
+ def grouped_avg(arr: NDArray, n: int = 12) -> NDArray:
487
+ """ Row-wise averaging of numpy arrays. For example:
488
+ 1 2 3
489
+ 4 5 6
490
+ 7 8 9
491
+ 10 11 12
492
+ 13 14 15
493
+ 16 17 18
494
+
495
+ if n = 6, becomes:
496
+ 8.5 9.5 10.5
497
+
498
+ because:
499
+ (1 + 4 + 7 + 10 + 13 + 16) / 6 = 8.5
500
+ (2 + 5 + 8 + 11 + 14 + 17) / 6 = 9.5
501
+ etc.
502
+
503
+ if n = 2, becomes:
504
+ 2.5 3.5 4.5
505
+ 8.5 9.5 10.5
506
+ 14.5 15.5 16.5
507
+
508
+ because:
509
+ (in column 0) (1 + 4) / 2 = 2.5, (7 + 10) / 2 = 8.5, (13 + 16) / 2 = 14.5
510
+ (in column 1) (2 + 5) / 2 = 3.5, (8 + 11) / 2 = 9.5, (14 + 17) / 2 = 15.5
511
+
512
+ Source: https://stackoverflow.com/questions/30379311/fast-way-to-take-average-of-every-n-rows-in-a-npy-array
513
+
514
+ Parameters
515
+ ----------
516
+ arr : NDArray
517
+ Input array.
518
+ n : int, optional
519
+ Number of rows to average. Defaults to 12.
520
+
521
+ Returns
522
+ -------
523
+ NDArray
524
+ Output array
525
+ """
526
+ result = cumsum(arr, 0)[n-1::n] / float(n)
527
+ result[1:] = result[1:] - result[:-1]
528
+ return result
529
+
530
+
531
+ def avg_run_in_columnwise(arr: NDArray, n: int):
532
+ """
533
+ Reduce the first `n` elements of each column in an array by averaging them, while leaving the rest of the array
534
+ modified.
535
+
536
+ Parameters
537
+ ----------
538
+ arr : NDArray
539
+ Input array.
540
+ n : int
541
+ The number of run-in elements to average.
542
+
543
+ Returns
544
+ -------
545
+ NDArray
546
+ The new array where the first element in each column is an average of the run in elements.
547
+ """
548
+ run_in: NDArray = mean(arr[:n], 0)
549
+ return vstack([run_in, arr[n:]])
550
+
551
+
552
+ def avg_run_in_rowwise(arr: NDArray, n: int):
553
+ """
554
+ Reduce the first `n` elements of each row in an array by averaging them, while leaving the rest of the array
555
+ modified.
556
+
557
+ Parameters
558
+ ----------
559
+ arr : NDArray
560
+ Input array.
561
+ n : int
562
+ The number of run-in elements to average.
563
+
564
+ Returns
565
+ -------
566
+ NDArray
567
+ The new array where the first element in each row is an average of the run in elements.
568
+ """
569
+ return avg_run_in_columnwise(arr.transpose(), n).transpose()
570
+
571
+
572
+ def gen_seed(node: dict) -> int:
573
+ """
574
+ Generate a seed based on a node's `@id` so that rng is the same each time the model is re-run.
575
+ """
576
+ node_id = node.get("@id", "")
577
+ hashed = hashlib.shake_128(node_id.encode(), usedforsecurity=False).hexdigest(4)
578
+ return abs(int(hashed, 16))
@@ -26,7 +26,7 @@ from hestia_earth.utils.tools import (
26
26
  )
27
27
 
28
28
  from ..log import debugValues, log_as_table
29
- from . import is_from_model, _filter_list_term_unit
29
+ from . import is_from_model, _filter_list_term_unit, is_iterable
30
30
  from .constant import Units
31
31
  from .property import get_node_property, get_node_property_value
32
32
  from .lookup import (
@@ -463,8 +463,7 @@ def _convert_to_set(
463
463
  set
464
464
  A set containing the elements of the input variable.
465
465
  """
466
- is_iterable = isinstance(variable, Iterable) and not isinstance(variable, (str, bytes))
467
- return set(variable) if is_iterable else {variable}
466
+ return set(variable) if is_iterable(variable) else {variable}
468
467
 
469
468
 
470
469
  def node_term_match(
@@ -1,8 +1,9 @@
1
- from hestia_earth.schema import TermTermType
1
+ from hestia_earth.schema import TermTermType, SiteSiteType
2
2
  from hestia_earth.utils.model import find_primary_product
3
3
  from hestia_earth.utils.tools import safe_parse_float
4
4
 
5
5
  from .term import get_lookup_value
6
+ from .site import valid_site_type as site_valid_site_type
6
7
 
7
8
  FAO_LOOKUP_COLUMN = 'cropGroupingFAO'
8
9
  FAOSTAT_AREA_LOOKUP_COLUMN = 'cropGroupingFaostatArea'
@@ -34,3 +35,25 @@ def get_N2ON_fertiliser_coeff_from_primary_product(model: str, log_id: str, cycl
34
35
 
35
36
  def is_plantation(model: str, log_id: str, term_id: str):
36
37
  return get_crop_lookup_value(model, log_id, term_id, 'isPlantation')
38
+
39
+
40
+ def valid_site_type(cycle: dict, include_permanent_pasture=False):
41
+ """
42
+ Check if the `site.siteType` of the cycle is `cropland`.
43
+
44
+ Parameters
45
+ ----------
46
+ cycle : dict
47
+ The `Cycle`.
48
+ include_permanent_pasture : bool
49
+ If set to `True`, `permanent pasture` is also allowed. Defaults to `False`.
50
+
51
+ Returns
52
+ -------
53
+ bool
54
+ `True` if `siteType` matches the allowed values, `False` otherwise.
55
+ """
56
+ site_types = [SiteSiteType.CROPLAND.value] + (
57
+ [SiteSiteType.PERMANENT_PASTURE.value] if include_permanent_pasture else []
58
+ )
59
+ return site_valid_site_type(cycle.get('site', {}), site_types)
@@ -9,7 +9,6 @@ from .property import get_node_property
9
9
  from .completeness import _is_term_type_complete
10
10
  from .blank_node import get_N_total, get_P2O5_total
11
11
  from .measurement import most_relevant_measurement_value
12
- from .site import valid_site_type as site_valid_site_type
13
12
  from .crop import is_plantation
14
13
  from .currency import DEFAULT_CURRENCY
15
14
  from .inorganicFertiliser import get_cycle_inputs as get_inorganicFertiliser_inputs
@@ -330,28 +329,6 @@ def land_occupation_per_kg(model: str, term_id: str, cycle: dict, site: dict, pr
330
329
  )
331
330
 
332
331
 
333
- def valid_site_type(cycle: dict, include_permanent_pasture=False):
334
- """
335
- Check if the `site.siteType` of the cycle is `cropland`.
336
-
337
- Parameters
338
- ----------
339
- cycle : dict
340
- The `Cycle`.
341
- include_permanent_pasture : bool
342
- If set to `True`, `permanent pasture` is also allowed. Defaults to `False`.
343
-
344
- Returns
345
- -------
346
- bool
347
- `True` if `siteType` matches the allowed values, `False` otherwise.
348
- """
349
- site_types = [SiteSiteType.CROPLAND.value] + (
350
- [SiteSiteType.PERMANENT_PASTURE.value] if include_permanent_pasture else []
351
- )
352
- return site_valid_site_type(cycle.get('site', {}), site_types)
353
-
354
-
355
332
  def is_organic(cycle: dict):
356
333
  """
357
334
  Check if the `Cycle` is organic, i.e. if it contains an organic standard label `Practice`.