foxes 0.8.2__py3-none-any.whl → 1.1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of foxes might be problematic. Click here for more details.
- docs/source/conf.py +353 -0
- examples/abl_states/run.py +160 -0
- examples/compare_rotors_pwakes/run.py +217 -0
- examples/compare_wakes/run.py +241 -0
- examples/dyn_wakes/run.py +311 -0
- examples/field_data_nc/run.py +121 -0
- examples/induction/run.py +201 -0
- examples/multi_height/run.py +113 -0
- examples/power_mask/run.py +249 -0
- examples/random_timeseries/run.py +210 -0
- examples/scan_row/run.py +193 -0
- examples/sector_management/run.py +162 -0
- examples/sequential/run.py +209 -0
- examples/single_state/run.py +201 -0
- examples/states_lookup_table/run.py +137 -0
- examples/streamline_wakes/run.py +138 -0
- examples/tab_file/run.py +142 -0
- examples/timelines/run.py +267 -0
- examples/timeseries/run.py +190 -0
- examples/timeseries_slurm/run.py +185 -0
- examples/wind_rose/run.py +141 -0
- examples/windio/run.py +29 -0
- examples/yawed_wake/run.py +196 -0
- foxes/__init__.py +4 -8
- foxes/algorithms/__init__.py +1 -1
- foxes/algorithms/downwind/downwind.py +247 -111
- foxes/algorithms/downwind/models/farm_wakes_calc.py +12 -7
- foxes/algorithms/downwind/models/init_farm_data.py +2 -2
- foxes/algorithms/downwind/models/point_wakes_calc.py +6 -7
- foxes/algorithms/downwind/models/reorder_farm_output.py +1 -2
- foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
- foxes/algorithms/downwind/models/set_amb_point_results.py +5 -3
- foxes/algorithms/iterative/iterative.py +74 -34
- foxes/algorithms/iterative/models/farm_wakes_calc.py +12 -7
- foxes/algorithms/iterative/models/urelax.py +3 -3
- foxes/algorithms/sequential/models/plugin.py +5 -5
- foxes/algorithms/sequential/models/seq_state.py +1 -1
- foxes/algorithms/sequential/sequential.py +126 -255
- foxes/constants.py +22 -7
- foxes/core/__init__.py +1 -0
- foxes/core/algorithm.py +632 -147
- foxes/core/data.py +252 -20
- foxes/core/data_calc_model.py +15 -291
- foxes/core/engine.py +640 -0
- foxes/core/farm_controller.py +38 -10
- foxes/core/farm_data_model.py +16 -1
- foxes/core/ground_model.py +2 -2
- foxes/core/model.py +249 -182
- foxes/core/partial_wakes_model.py +1 -1
- foxes/core/point_data_model.py +17 -2
- foxes/core/rotor_model.py +27 -21
- foxes/core/states.py +17 -1
- foxes/core/turbine_type.py +28 -0
- foxes/core/wake_frame.py +30 -34
- foxes/core/wake_model.py +5 -5
- foxes/core/wake_superposition.py +1 -1
- foxes/data/windio/windio_5turbines_timeseries.yaml +31 -15
- foxes/engines/__init__.py +17 -0
- foxes/engines/dask.py +982 -0
- foxes/engines/default.py +75 -0
- foxes/engines/futures.py +72 -0
- foxes/engines/mpi.py +38 -0
- foxes/engines/multiprocess.py +71 -0
- foxes/engines/numpy.py +167 -0
- foxes/engines/pool.py +249 -0
- foxes/engines/ray.py +79 -0
- foxes/engines/single.py +141 -0
- foxes/input/farm_layout/__init__.py +1 -0
- foxes/input/farm_layout/from_csv.py +4 -0
- foxes/input/farm_layout/from_json.py +2 -2
- foxes/input/farm_layout/grid.py +2 -2
- foxes/input/farm_layout/ring.py +65 -0
- foxes/input/farm_layout/row.py +2 -2
- foxes/input/states/__init__.py +7 -0
- foxes/input/states/create/random_abl_states.py +1 -1
- foxes/input/states/field_data_nc.py +158 -33
- foxes/input/states/multi_height.py +128 -14
- foxes/input/states/one_point_flow.py +577 -0
- foxes/input/states/scan_ws.py +74 -3
- foxes/input/states/single.py +1 -1
- foxes/input/states/slice_data_nc.py +681 -0
- foxes/input/states/states_table.py +204 -35
- foxes/input/windio/__init__.py +2 -2
- foxes/input/windio/get_states.py +44 -23
- foxes/input/windio/read_attributes.py +48 -17
- foxes/input/windio/read_farm.py +116 -102
- foxes/input/windio/read_fields.py +16 -6
- foxes/input/windio/read_outputs.py +71 -24
- foxes/input/windio/runner.py +31 -17
- foxes/input/windio/windio.py +41 -23
- foxes/models/farm_models/turbine2farm.py +1 -1
- foxes/models/ground_models/wake_mirror.py +10 -6
- foxes/models/model_book.py +58 -20
- foxes/models/partial_wakes/axiwake.py +3 -3
- foxes/models/partial_wakes/rotor_points.py +3 -3
- foxes/models/partial_wakes/top_hat.py +2 -2
- foxes/models/point_models/set_uniform_data.py +1 -1
- foxes/models/point_models/tke2ti.py +1 -1
- foxes/models/point_models/wake_deltas.py +1 -1
- foxes/models/rotor_models/centre.py +4 -0
- foxes/models/rotor_models/grid.py +24 -25
- foxes/models/rotor_models/levels.py +4 -5
- foxes/models/turbine_models/calculator.py +4 -6
- foxes/models/turbine_models/kTI_model.py +22 -6
- foxes/models/turbine_models/lookup_table.py +30 -4
- foxes/models/turbine_models/rotor_centre_calc.py +4 -3
- foxes/models/turbine_models/set_farm_vars.py +103 -34
- foxes/models/turbine_types/PCt_file.py +27 -3
- foxes/models/turbine_types/PCt_from_two.py +27 -3
- foxes/models/turbine_types/TBL_file.py +80 -0
- foxes/models/turbine_types/__init__.py +2 -0
- foxes/models/turbine_types/lookup.py +316 -0
- foxes/models/turbine_types/null_type.py +51 -1
- foxes/models/turbine_types/wsrho2PCt_from_two.py +29 -5
- foxes/models/turbine_types/wsti2PCt_from_two.py +31 -7
- foxes/models/vertical_profiles/__init__.py +1 -1
- foxes/models/vertical_profiles/data_profile.py +1 -1
- foxes/models/wake_frames/__init__.py +1 -0
- foxes/models/wake_frames/dynamic_wakes.py +424 -0
- foxes/models/wake_frames/farm_order.py +25 -5
- foxes/models/wake_frames/rotor_wd.py +6 -4
- foxes/models/wake_frames/seq_dynamic_wakes.py +61 -74
- foxes/models/wake_frames/streamlines.py +21 -22
- foxes/models/wake_frames/timelines.py +330 -129
- foxes/models/wake_frames/yawed_wakes.py +7 -4
- foxes/models/wake_models/dist_sliced.py +2 -4
- foxes/models/wake_models/induction/rankine_half_body.py +5 -5
- foxes/models/wake_models/induction/rathmann.py +78 -24
- foxes/models/wake_models/induction/self_similar.py +78 -28
- foxes/models/wake_models/induction/vortex_sheet.py +86 -48
- foxes/models/wake_models/ti/crespo_hernandez.py +6 -4
- foxes/models/wake_models/ti/iec_ti.py +40 -21
- foxes/models/wake_models/top_hat.py +1 -1
- foxes/models/wake_models/wind/bastankhah14.py +8 -6
- foxes/models/wake_models/wind/bastankhah16.py +17 -16
- foxes/models/wake_models/wind/jensen.py +4 -3
- foxes/models/wake_models/wind/turbopark.py +16 -13
- foxes/models/wake_superpositions/ti_linear.py +1 -1
- foxes/models/wake_superpositions/ti_max.py +1 -1
- foxes/models/wake_superpositions/ti_pow.py +1 -1
- foxes/models/wake_superpositions/ti_quadratic.py +1 -1
- foxes/models/wake_superpositions/ws_linear.py +8 -7
- foxes/models/wake_superpositions/ws_max.py +8 -7
- foxes/models/wake_superpositions/ws_pow.py +8 -7
- foxes/models/wake_superpositions/ws_product.py +5 -5
- foxes/models/wake_superpositions/ws_quadratic.py +8 -7
- foxes/output/__init__.py +4 -1
- foxes/output/farm_layout.py +16 -12
- foxes/output/farm_results_eval.py +1 -1
- foxes/output/flow_plots_2d/__init__.py +0 -1
- foxes/output/flow_plots_2d/flow_plots.py +70 -30
- foxes/output/grids.py +92 -22
- foxes/output/results_writer.py +2 -2
- foxes/output/rose_plot.py +3 -3
- foxes/output/seq_plugins/__init__.py +2 -0
- foxes/output/{flow_plots_2d → seq_plugins}/seq_flow_ani_plugin.py +64 -22
- foxes/output/seq_plugins/seq_wake_debug_plugin.py +145 -0
- foxes/output/slice_data.py +131 -111
- foxes/output/state_turbine_map.py +19 -14
- foxes/output/state_turbine_table.py +19 -19
- foxes/utils/__init__.py +1 -1
- foxes/utils/abl/neutral.py +2 -2
- foxes/utils/abl/stable.py +2 -2
- foxes/utils/abl/unstable.py +2 -2
- foxes/utils/data_book.py +1 -1
- foxes/utils/dev_utils.py +42 -0
- foxes/utils/dict.py +24 -1
- foxes/utils/exec_python.py +1 -1
- foxes/utils/factory.py +176 -53
- foxes/utils/geom2d/circle.py +1 -1
- foxes/utils/geom2d/polygon.py +1 -1
- foxes/utils/geopandas_utils.py +2 -2
- foxes/utils/load.py +2 -2
- foxes/utils/pandas_helpers.py +3 -2
- foxes/utils/wind_dir.py +0 -2
- foxes/utils/xarray_utils.py +24 -14
- foxes/variables.py +39 -2
- {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/METADATA +75 -33
- foxes-1.1.0.2.dist-info/RECORD +309 -0
- {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/WHEEL +1 -1
- foxes-1.1.0.2.dist-info/top_level.txt +4 -0
- tests/0_consistency/iterative/test_iterative.py +92 -0
- tests/0_consistency/partial_wakes/test_partial_wakes.py +90 -0
- tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +103 -0
- tests/1_verification/flappy_0_6/abl_states/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +87 -0
- tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +82 -0
- tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +82 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +93 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +96 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/flappy/run.py +94 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +122 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/flappy/run.py +94 -0
- tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +122 -0
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/flappy/run.py +92 -0
- tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +93 -0
- tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +85 -0
- tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +130 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/flappy/run.py +96 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +116 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +93 -0
- tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +99 -0
- tests/3_examples/test_examples.py +34 -0
- foxes/VERSION +0 -1
- foxes/output/flow_plots_2d.py +0 -0
- foxes/utils/geopandas_helpers.py +0 -294
- foxes/utils/runners/__init__.py +0 -1
- foxes/utils/runners/runners.py +0 -280
- foxes-0.8.2.dist-info/RECORD +0 -247
- foxes-0.8.2.dist-info/top_level.txt +0 -1
- foxes-0.8.2.dist-info/zip-safe +0 -1
- {foxes-0.8.2.dist-info → foxes-1.1.0.2.dist-info}/LICENSE +0 -0
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
from xarray import Dataset
|
|
2
2
|
|
|
3
3
|
from foxes.utils import write_nc
|
|
4
|
-
import foxes.constants as FC
|
|
4
|
+
import foxes.constants as FC
|
|
5
5
|
|
|
6
6
|
from .output import Output
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
class StateTurbineTable(Output):
|
|
9
10
|
"""
|
|
10
11
|
Creates tables of state-turbine type data
|
|
11
|
-
|
|
12
|
+
|
|
12
13
|
Attributes
|
|
13
14
|
----------
|
|
14
15
|
farm_results: xarray.Dataset
|
|
15
16
|
The farm results
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
:group: output
|
|
18
|
-
|
|
19
|
+
|
|
19
20
|
"""
|
|
21
|
+
|
|
20
22
|
def __init__(self, farm_results):
|
|
21
23
|
"""
|
|
22
24
|
Constructor.
|
|
@@ -28,17 +30,17 @@ class StateTurbineTable(Output):
|
|
|
28
30
|
|
|
29
31
|
"""
|
|
30
32
|
self.farm_results = farm_results
|
|
31
|
-
|
|
33
|
+
|
|
32
34
|
def get_dataset(
|
|
33
|
-
self,
|
|
34
|
-
variables,
|
|
35
|
-
name_map={},
|
|
36
|
-
to_file=None,
|
|
35
|
+
self,
|
|
36
|
+
variables,
|
|
37
|
+
name_map={},
|
|
38
|
+
to_file=None,
|
|
37
39
|
**kwargs,
|
|
38
|
-
|
|
40
|
+
):
|
|
39
41
|
"""
|
|
40
42
|
Creates a dataset object
|
|
41
|
-
|
|
43
|
+
|
|
42
44
|
Parameters
|
|
43
45
|
----------
|
|
44
46
|
variables: list of str
|
|
@@ -49,12 +51,12 @@ class StateTurbineTable(Output):
|
|
|
49
51
|
The output file path, if writing is desired
|
|
50
52
|
kwargs: dict, optional
|
|
51
53
|
Additional parameters for write_nc
|
|
52
|
-
|
|
54
|
+
|
|
53
55
|
Returns
|
|
54
56
|
-------
|
|
55
57
|
table: xarray.Dataset
|
|
56
58
|
The state-turbine data table
|
|
57
|
-
|
|
59
|
+
|
|
58
60
|
"""
|
|
59
61
|
state = name_map.get(FC.STATE, FC.STATE)
|
|
60
62
|
turbine = name_map.get(FC.TURBINE, FC.TURBINE)
|
|
@@ -65,14 +67,12 @@ class StateTurbineTable(Output):
|
|
|
65
67
|
turbine: self.farm_results[FC.TURBINE].to_numpy(),
|
|
66
68
|
},
|
|
67
69
|
data_vars={
|
|
68
|
-
name_map.get(v, v): (
|
|
69
|
-
(state, turbine), self.farm_results[v].to_numpy())
|
|
70
|
+
name_map.get(v, v): ((state, turbine), self.farm_results[v].to_numpy())
|
|
70
71
|
for v in variables
|
|
71
|
-
}
|
|
72
|
+
},
|
|
72
73
|
)
|
|
73
|
-
|
|
74
|
+
|
|
74
75
|
if to_file is not None:
|
|
75
76
|
write_nc(ds=ds, fpath=to_file, **kwargs)
|
|
76
|
-
|
|
77
|
+
|
|
77
78
|
return ds
|
|
78
|
-
|
foxes/utils/__init__.py
CHANGED
|
@@ -17,8 +17,8 @@ from .regularize import sqrt_reg
|
|
|
17
17
|
from .windrose_plot import TabWindroseAxes
|
|
18
18
|
from .tab_files import read_tab_file
|
|
19
19
|
from .random_xy import random_xy_square
|
|
20
|
+
from .dev_utils import print_mem
|
|
20
21
|
|
|
21
22
|
from . import two_circles
|
|
22
23
|
from . import abl
|
|
23
|
-
from . import runners
|
|
24
24
|
from . import geom2d
|
foxes/utils/abl/neutral.py
CHANGED
|
@@ -39,7 +39,7 @@ def ustar(ws_ref, h_ref, z0, kappa=0.41):
|
|
|
39
39
|
z0: float
|
|
40
40
|
The roughness length
|
|
41
41
|
kappa: float
|
|
42
|
-
The
|
|
42
|
+
The von Karman constant
|
|
43
43
|
|
|
44
44
|
Returns
|
|
45
45
|
-------
|
|
@@ -66,7 +66,7 @@ def calc_ws(height, z0, ustar, kappa=0.41):
|
|
|
66
66
|
ustar: float
|
|
67
67
|
The friction velocity
|
|
68
68
|
kappa: float
|
|
69
|
-
The
|
|
69
|
+
The von Karman constant
|
|
70
70
|
|
|
71
71
|
Returns
|
|
72
72
|
-------
|
foxes/utils/abl/stable.py
CHANGED
|
@@ -64,7 +64,7 @@ def ustar(ws_ref, h_ref, z0, mol, kappa=0.41):
|
|
|
64
64
|
mol: float
|
|
65
65
|
The Monin-Obukhov height
|
|
66
66
|
kappa: float
|
|
67
|
-
The
|
|
67
|
+
The von Karman constant
|
|
68
68
|
|
|
69
69
|
Returns
|
|
70
70
|
-------
|
|
@@ -92,7 +92,7 @@ def calc_ws(height, z0, ustar, psi, kappa=0.41):
|
|
|
92
92
|
psi: float
|
|
93
93
|
The Psi function values
|
|
94
94
|
kappa: float
|
|
95
|
-
The
|
|
95
|
+
The von Karman constant
|
|
96
96
|
|
|
97
97
|
Returns
|
|
98
98
|
-------
|
foxes/utils/abl/unstable.py
CHANGED
|
@@ -47,7 +47,7 @@ def ustar(ws_ref, h_ref, z0, mol, kappa=0.41):
|
|
|
47
47
|
mol: float
|
|
48
48
|
The Monin-Obukhov height
|
|
49
49
|
kappa: float
|
|
50
|
-
The
|
|
50
|
+
The von Karman constant
|
|
51
51
|
|
|
52
52
|
Returns
|
|
53
53
|
-------
|
|
@@ -75,7 +75,7 @@ def calc_ws(height, z0, ustar, psi, kappa=0.41):
|
|
|
75
75
|
psi: float
|
|
76
76
|
The Psi function values
|
|
77
77
|
kappa: float
|
|
78
|
-
The
|
|
78
|
+
The von Karman constant
|
|
79
79
|
|
|
80
80
|
Returns
|
|
81
81
|
-------
|
foxes/utils/data_book.py
CHANGED
foxes/utils/dev_utils.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from .load import import_module
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def print_mem(obj, min_csize=0, max_csize=None, pre_str="OBJECT SIZE"):
|
|
5
|
+
"""
|
|
6
|
+
Prints the memory consumption of a model and its components
|
|
7
|
+
|
|
8
|
+
Parmeters
|
|
9
|
+
---------
|
|
10
|
+
obj: object
|
|
11
|
+
The object to be analyzed
|
|
12
|
+
min_csize: int
|
|
13
|
+
The minimal size of a component for being shown
|
|
14
|
+
max_csize: int, optional
|
|
15
|
+
The maximal allowed size of a component
|
|
16
|
+
pre_str: str
|
|
17
|
+
String to be printed before
|
|
18
|
+
|
|
19
|
+
:group: utils
|
|
20
|
+
|
|
21
|
+
"""
|
|
22
|
+
objsize = import_module("objsize")
|
|
23
|
+
n = obj.name if hasattr(obj, "name") else ""
|
|
24
|
+
print(pre_str, type(obj).__name__, n, objsize.get_deep_size(obj))
|
|
25
|
+
for k in dir(obj):
|
|
26
|
+
o = None
|
|
27
|
+
try:
|
|
28
|
+
if (
|
|
29
|
+
hasattr(obj, k)
|
|
30
|
+
and not callable(getattr(obj, k))
|
|
31
|
+
and (len(k) < 3 or k[:2] != "__")
|
|
32
|
+
):
|
|
33
|
+
o = getattr(obj, k)
|
|
34
|
+
except ValueError:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
if o is not None:
|
|
38
|
+
s = objsize.get_deep_size(getattr(obj, k))
|
|
39
|
+
if s >= min_csize:
|
|
40
|
+
print(" ", k, s)
|
|
41
|
+
if max_csize is not None and s > max_csize:
|
|
42
|
+
raise ValueError(f"Component {k} exceeds maximal size {max_csize}")
|
foxes/utils/dict.py
CHANGED
|
@@ -28,10 +28,33 @@ class Dict(dict):
|
|
|
28
28
|
super().__init__(*args, **kwargs)
|
|
29
29
|
self.name = name if name is not None else type(self).__name__
|
|
30
30
|
|
|
31
|
+
def get_item(self, key, prnt=True):
|
|
32
|
+
"""
|
|
33
|
+
Gets an item, prints readable error if not found
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
key: immutable object
|
|
38
|
+
The key
|
|
39
|
+
prnt: bool
|
|
40
|
+
Flag for message printing
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
try:
|
|
44
|
+
return self[key]
|
|
45
|
+
except KeyError as e:
|
|
46
|
+
if prnt:
|
|
47
|
+
print(f"\n{self.name}: Cannot find key '{key}'.\n")
|
|
48
|
+
print("Known keys:")
|
|
49
|
+
for k in self.keys():
|
|
50
|
+
print(" ", k)
|
|
51
|
+
print()
|
|
52
|
+
raise e
|
|
53
|
+
|
|
31
54
|
def __getitem__(self, key):
|
|
32
55
|
try:
|
|
33
56
|
return super().__getitem__(key)
|
|
34
57
|
except KeyError:
|
|
35
|
-
k = ", ".join(sorted(
|
|
58
|
+
k = ", ".join(sorted([f"{s}" for s in self.keys()]))
|
|
36
59
|
e = f"{self.name}: Cannot find key '{key}'. Known keys: {k}"
|
|
37
60
|
raise KeyError(e)
|
foxes/utils/exec_python.py
CHANGED
|
@@ -17,7 +17,7 @@ def exec_python(s, indicator="%", newline=";", globals=globals(), locals={}):
|
|
|
17
17
|
s: list, dict or object
|
|
18
18
|
The source to by analyzed
|
|
19
19
|
indicator: str
|
|
20
|
-
The indicator that
|
|
20
|
+
The indicator that triggers python evaluation
|
|
21
21
|
newline: str
|
|
22
22
|
The new line indicator
|
|
23
23
|
globals: dict
|
foxes/utils/factory.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
1
3
|
from .dict import Dict
|
|
2
4
|
import foxes.variables as FV
|
|
3
5
|
|
|
@@ -23,6 +25,8 @@ class Factory:
|
|
|
23
25
|
hints: dict
|
|
24
26
|
Hints for print_toc, only for variables for which the
|
|
25
27
|
options are functions or missing
|
|
28
|
+
example: str
|
|
29
|
+
An example name
|
|
26
30
|
options: dict
|
|
27
31
|
For each variable, e.g. A, B or C, the list or dict
|
|
28
32
|
or function that maps a str to the actual value
|
|
@@ -39,6 +43,7 @@ class Factory:
|
|
|
39
43
|
kwargs={},
|
|
40
44
|
var2arg={},
|
|
41
45
|
hints={},
|
|
46
|
+
example_vars=None,
|
|
42
47
|
**options,
|
|
43
48
|
):
|
|
44
49
|
"""
|
|
@@ -60,6 +65,8 @@ class Factory:
|
|
|
60
65
|
hints: dict
|
|
61
66
|
Hints for print_toc, only for variables for which the
|
|
62
67
|
options are functions or missing
|
|
68
|
+
example_vars: dict, optional
|
|
69
|
+
Variable values for creating an example
|
|
63
70
|
options: dict
|
|
64
71
|
For each variable, e.g. A, B or C, the list or dict
|
|
65
72
|
or function that maps a str to the actual value
|
|
@@ -122,6 +129,30 @@ class Factory:
|
|
|
122
129
|
f"Factory '{name_template}': Variable '{v}' has option of type '{type(v).__name__}'. Only list, tuple, dict or function are supported"
|
|
123
130
|
)
|
|
124
131
|
|
|
132
|
+
exvars = dict(
|
|
133
|
+
n=5,
|
|
134
|
+
n2=9,
|
|
135
|
+
superposition="linear",
|
|
136
|
+
kTI=0.2,
|
|
137
|
+
kb=0.001,
|
|
138
|
+
step=100,
|
|
139
|
+
dx=100,
|
|
140
|
+
dt="10s",
|
|
141
|
+
)
|
|
142
|
+
if example_vars is not None:
|
|
143
|
+
exvars.update(example_vars)
|
|
144
|
+
try:
|
|
145
|
+
self.example = ""
|
|
146
|
+
for i, v in enumerate(self._vars):
|
|
147
|
+
self.example += f"{self._pre[i]}{exvars[v]}"
|
|
148
|
+
self.example += self._pre[-1]
|
|
149
|
+
if not self.check_match(self.example, error=False):
|
|
150
|
+
raise ValueError(
|
|
151
|
+
f"Example '{self.example}' does not match template '{self.name_template}'"
|
|
152
|
+
)
|
|
153
|
+
except KeyError:
|
|
154
|
+
self.example = None
|
|
155
|
+
|
|
125
156
|
@property
|
|
126
157
|
def name_prefix(self):
|
|
127
158
|
"""
|
|
@@ -171,56 +202,77 @@ class Factory:
|
|
|
171
202
|
s += f"\n {v} from {list(self.options[v])}"
|
|
172
203
|
else:
|
|
173
204
|
s += f"\n {v}={self.hints.get(v, '(value)')}"
|
|
205
|
+
if self.example is not None:
|
|
206
|
+
s += f"\nExample: {self.example}"
|
|
174
207
|
return s
|
|
175
208
|
|
|
176
|
-
def
|
|
209
|
+
def get_examples(self, **var_values):
|
|
177
210
|
"""
|
|
178
|
-
|
|
211
|
+
Create example names from given values
|
|
179
212
|
|
|
180
213
|
Parameters
|
|
181
214
|
----------
|
|
182
|
-
|
|
183
|
-
|
|
215
|
+
var_values: dict
|
|
216
|
+
Variables values. Key: Variable,
|
|
217
|
+
value: list or value
|
|
184
218
|
|
|
185
219
|
Returns
|
|
186
220
|
-------
|
|
187
|
-
|
|
188
|
-
|
|
221
|
+
examples: list of str
|
|
222
|
+
The examples
|
|
189
223
|
|
|
190
224
|
"""
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
q = self._pre[vi + 1]
|
|
201
|
-
if q != "":
|
|
202
|
-
i = data_str.find(q)
|
|
203
|
-
j = i + len(q)
|
|
204
|
-
if i < 0 or len(data_str) <= j:
|
|
205
|
-
return False
|
|
225
|
+
|
|
226
|
+
def gete(i, vals, vars, values, examples):
|
|
227
|
+
if i >= len(vars):
|
|
228
|
+
e = ""
|
|
229
|
+
for i, v in enumerate(self._vars):
|
|
230
|
+
e += f"{self._pre[i]}{vals[v]}"
|
|
231
|
+
e += self._pre[-1]
|
|
232
|
+
self.check_match(e, error=True)
|
|
233
|
+
examples.append(e)
|
|
206
234
|
else:
|
|
207
|
-
|
|
235
|
+
v = vars[i]
|
|
236
|
+
if v in self._vars:
|
|
237
|
+
vls = np.atleast_1d(values[i])
|
|
238
|
+
for x in vls:
|
|
239
|
+
vals[v] = x
|
|
240
|
+
gete(i + 1, vals, vars, values, examples)
|
|
241
|
+
else:
|
|
242
|
+
gete(i + 1, vals, vars, values, examples)
|
|
243
|
+
|
|
244
|
+
examples = []
|
|
245
|
+
gete(
|
|
246
|
+
0,
|
|
247
|
+
{},
|
|
248
|
+
list(var_values.keys()),
|
|
249
|
+
list(var_values.values()),
|
|
250
|
+
examples,
|
|
251
|
+
)
|
|
208
252
|
|
|
209
|
-
return
|
|
253
|
+
return examples
|
|
210
254
|
|
|
211
|
-
def
|
|
255
|
+
def check_match(self, name, error=False, ret_pars=False):
|
|
212
256
|
"""
|
|
213
|
-
|
|
257
|
+
Tests if a name matches the template and constructs
|
|
258
|
+
parameters
|
|
214
259
|
|
|
215
260
|
Parameters
|
|
216
261
|
----------
|
|
217
262
|
name: str
|
|
218
|
-
The name
|
|
263
|
+
The name to be checked
|
|
264
|
+
error: bool
|
|
265
|
+
Flag for raising a Value error in case of
|
|
266
|
+
mismatch
|
|
267
|
+
ret_pars: bool
|
|
268
|
+
Flag for returning the parameters
|
|
219
269
|
|
|
220
270
|
Returns
|
|
221
271
|
-------
|
|
222
|
-
|
|
223
|
-
|
|
272
|
+
success: bool
|
|
273
|
+
True if the template is matched
|
|
274
|
+
pars: dict, optional
|
|
275
|
+
The constructed parameters
|
|
224
276
|
|
|
225
277
|
"""
|
|
226
278
|
j = 0
|
|
@@ -229,9 +281,14 @@ class Factory:
|
|
|
229
281
|
if len(p) > 0:
|
|
230
282
|
i = name[j:].find(p)
|
|
231
283
|
if i < 0 or (pi == 0 and i > 0):
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
284
|
+
if error:
|
|
285
|
+
raise ValueError(
|
|
286
|
+
f"Factory '{self.name_template}': Name '{name}' not matching template"
|
|
287
|
+
)
|
|
288
|
+
elif ret_pars:
|
|
289
|
+
return False, {}
|
|
290
|
+
else:
|
|
291
|
+
return False
|
|
235
292
|
w = name[j : j + i]
|
|
236
293
|
j += i + len(p)
|
|
237
294
|
else:
|
|
@@ -239,21 +296,41 @@ class Factory:
|
|
|
239
296
|
if pi > 0:
|
|
240
297
|
wlist.append(w)
|
|
241
298
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
299
|
+
if ret_pars:
|
|
300
|
+
kwargs = {}
|
|
301
|
+
for vi, v in enumerate(self.variables):
|
|
302
|
+
w = self.var2arg.get(v, v)
|
|
303
|
+
data = wlist[vi]
|
|
304
|
+
if v in self.options:
|
|
305
|
+
o = self.options[v]
|
|
306
|
+
if hasattr(o, "__call__"):
|
|
307
|
+
kwargs[w] = o(data)
|
|
308
|
+
else:
|
|
309
|
+
kwargs[w] = self.options[v][data]
|
|
250
310
|
else:
|
|
251
|
-
kwargs[w] =
|
|
252
|
-
else:
|
|
253
|
-
kwargs[w] = data
|
|
311
|
+
kwargs[w] = data
|
|
254
312
|
|
|
255
|
-
|
|
313
|
+
kwargs.update(self.kwargs)
|
|
314
|
+
return True, kwargs
|
|
256
315
|
|
|
316
|
+
return True
|
|
317
|
+
|
|
318
|
+
def construct(self, name):
|
|
319
|
+
"""
|
|
320
|
+
Create an object of the base class.
|
|
321
|
+
|
|
322
|
+
Parameters
|
|
323
|
+
----------
|
|
324
|
+
name: str
|
|
325
|
+
The name, matching the template
|
|
326
|
+
|
|
327
|
+
Returns
|
|
328
|
+
-------
|
|
329
|
+
obj: object
|
|
330
|
+
The instance of the base class
|
|
331
|
+
|
|
332
|
+
"""
|
|
333
|
+
__, kwargs = self.check_match(name, error=True, ret_pars=True)
|
|
257
334
|
return self.base(*self.args, **kwargs)
|
|
258
335
|
|
|
259
336
|
|
|
@@ -299,14 +376,20 @@ class WakeKFactory:
|
|
|
299
376
|
i0 = name_template.find("_[wake_k]")
|
|
300
377
|
i1 = i0 + len("_[wake_k]")
|
|
301
378
|
kw = kwargs.pop("kwargs", {})
|
|
379
|
+
v2a = kwargs.pop("var2arg", {})
|
|
302
380
|
|
|
303
381
|
if i0 < 0:
|
|
304
382
|
raise ValueError(
|
|
305
383
|
f"String '_[wake_k]' not found in name template '{name_template}'"
|
|
306
384
|
)
|
|
307
385
|
|
|
386
|
+
exvars = dict(k=0.04, ka=0.2, ambka=0.4, kb=0.001)
|
|
387
|
+
if "example_vars" in kwargs:
|
|
388
|
+
exvars.update(kwargs.pop("example_vars"))
|
|
389
|
+
|
|
308
390
|
# add case ka, kb:
|
|
309
|
-
|
|
391
|
+
t0 = name_template[:i0]
|
|
392
|
+
t = t0 + "_ka<ka>_kb<kb>"
|
|
310
393
|
if len(name_template) > i1:
|
|
311
394
|
t += name_template[i1:]
|
|
312
395
|
h = hints.copy()
|
|
@@ -323,17 +406,20 @@ class WakeKFactory:
|
|
|
323
406
|
**kwargs,
|
|
324
407
|
ka=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
325
408
|
kb=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
409
|
+
example_vars=exvars,
|
|
326
410
|
)
|
|
327
411
|
)
|
|
328
412
|
|
|
329
|
-
# add case ambient
|
|
330
|
-
t = name_template[:i0] + "_ambka<
|
|
413
|
+
# add case ambient ambka, kb:
|
|
414
|
+
t = name_template[:i0] + "_ambka<ambka>_kb<kb>"
|
|
331
415
|
if len(name_template) > i1:
|
|
332
416
|
t += name_template[i1:]
|
|
333
417
|
h = hints.copy()
|
|
334
|
-
h["
|
|
418
|
+
h["ambka"] = "(Value, e.g. 04 for 0.4)"
|
|
335
419
|
h["kb"] = "(Value, e.g. 001 for 0.01)"
|
|
336
420
|
kw["ti_var"] = FV.AMB_TI
|
|
421
|
+
hv2a = v2a.copy()
|
|
422
|
+
hv2a["ambka"] = "ka"
|
|
337
423
|
self.factories.append(
|
|
338
424
|
Factory(
|
|
339
425
|
base,
|
|
@@ -341,9 +427,11 @@ class WakeKFactory:
|
|
|
341
427
|
*args,
|
|
342
428
|
hints=h,
|
|
343
429
|
kwargs=kw.copy(),
|
|
430
|
+
var2arg=hv2a,
|
|
344
431
|
**kwargs,
|
|
345
|
-
|
|
432
|
+
ambka=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
346
433
|
kb=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
434
|
+
example_vars=exvars,
|
|
347
435
|
)
|
|
348
436
|
)
|
|
349
437
|
|
|
@@ -363,16 +451,19 @@ class WakeKFactory:
|
|
|
363
451
|
kwargs=kw.copy(),
|
|
364
452
|
**kwargs,
|
|
365
453
|
ka=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
454
|
+
example_vars=exvars,
|
|
366
455
|
)
|
|
367
456
|
)
|
|
368
457
|
|
|
369
|
-
# add case
|
|
370
|
-
t = name_template[:i0] + "_ambka<
|
|
458
|
+
# add case ambka:
|
|
459
|
+
t = name_template[:i0] + "_ambka<ambka>"
|
|
371
460
|
if len(name_template) > i1:
|
|
372
461
|
t += name_template[i1:]
|
|
373
462
|
h = hints.copy()
|
|
374
|
-
h["
|
|
463
|
+
h["ambka"] = "(Value, e.g. 04 for 0.4)"
|
|
375
464
|
kw["ti_var"] = FV.AMB_TI
|
|
465
|
+
hv2a = v2a.copy()
|
|
466
|
+
hv2a["ambka"] = "ka"
|
|
376
467
|
self.factories.append(
|
|
377
468
|
Factory(
|
|
378
469
|
base,
|
|
@@ -380,8 +471,10 @@ class WakeKFactory:
|
|
|
380
471
|
*args,
|
|
381
472
|
hints=h,
|
|
382
473
|
kwargs=kw.copy(),
|
|
474
|
+
var2arg=hv2a,
|
|
383
475
|
**kwargs,
|
|
384
|
-
|
|
476
|
+
ambka=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
477
|
+
example_vars=exvars,
|
|
385
478
|
)
|
|
386
479
|
)
|
|
387
480
|
|
|
@@ -401,6 +494,7 @@ class WakeKFactory:
|
|
|
401
494
|
kwargs=kw.copy(),
|
|
402
495
|
**kwargs,
|
|
403
496
|
k=lambda x: float(f"0.{x[1:]}" if x[0] == "0" else float(x)),
|
|
497
|
+
example_vars=exvars,
|
|
404
498
|
)
|
|
405
499
|
)
|
|
406
500
|
|
|
@@ -417,6 +511,7 @@ class WakeKFactory:
|
|
|
417
511
|
hints=hints,
|
|
418
512
|
kwargs=kw.copy(),
|
|
419
513
|
**kwargs,
|
|
514
|
+
example_vars=exvars,
|
|
420
515
|
)
|
|
421
516
|
)
|
|
422
517
|
|
|
@@ -523,6 +618,35 @@ class FDict(Dict):
|
|
|
523
618
|
return True
|
|
524
619
|
return found
|
|
525
620
|
|
|
621
|
+
def get_item(self, key, prnt=True):
|
|
622
|
+
"""
|
|
623
|
+
Gets an item, prints readable error if not found
|
|
624
|
+
|
|
625
|
+
Parameters
|
|
626
|
+
----------
|
|
627
|
+
key: immutable object
|
|
628
|
+
The key
|
|
629
|
+
prnt: bool
|
|
630
|
+
Flag for message printing
|
|
631
|
+
|
|
632
|
+
"""
|
|
633
|
+
try:
|
|
634
|
+
return self[key]
|
|
635
|
+
except KeyError as e:
|
|
636
|
+
if prnt:
|
|
637
|
+
print(
|
|
638
|
+
f"\n{self.name}: Cannot find key '{key}', also no factory matches.\n"
|
|
639
|
+
)
|
|
640
|
+
print("Known keys:")
|
|
641
|
+
for k in self.keys():
|
|
642
|
+
print(" ", k)
|
|
643
|
+
if len(self.factories):
|
|
644
|
+
print("\nKnown factories:")
|
|
645
|
+
for f in self.factories:
|
|
646
|
+
print(" ", f.name_template)
|
|
647
|
+
print()
|
|
648
|
+
raise e
|
|
649
|
+
|
|
526
650
|
def __getitem__(self, key):
|
|
527
651
|
try:
|
|
528
652
|
return super().__getitem__(key)
|
|
@@ -535,7 +659,6 @@ class FDict(Dict):
|
|
|
535
659
|
return obj
|
|
536
660
|
except ValueError:
|
|
537
661
|
pass
|
|
538
|
-
|
|
539
662
|
k = ", ".join(sorted(list(self.keys())))
|
|
540
663
|
e = f"{self.name}: Cannot find key '{key}', also no factory matches. Known keys: {k}. Known factories: {[f.name_template for f in self.factories]}"
|
|
541
664
|
raise KeyError(e)
|
foxes/utils/geom2d/circle.py
CHANGED
foxes/utils/geom2d/polygon.py
CHANGED
foxes/utils/geopandas_utils.py
CHANGED
|
@@ -50,7 +50,7 @@ def check_import_utm():
|
|
|
50
50
|
|
|
51
51
|
def read_shp(fname, **kwargs):
|
|
52
52
|
"""
|
|
53
|
-
Read a
|
|
53
|
+
Read a shapefile file
|
|
54
54
|
|
|
55
55
|
Parameters
|
|
56
56
|
----------
|
|
@@ -74,7 +74,7 @@ def read_shp(fname, **kwargs):
|
|
|
74
74
|
|
|
75
75
|
def shp2csv(ifile, ofile, in_kwargs={}, out_kwargs={}, verbosity=1):
|
|
76
76
|
"""
|
|
77
|
-
Read
|
|
77
|
+
Read shapefile file, write csv file
|
|
78
78
|
|
|
79
79
|
Parameters
|
|
80
80
|
----------
|