foxes 1.1.1__py3-none-any.whl → 1.2.1__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.

Files changed (155) hide show
  1. docs/source/conf.py +3 -1
  2. examples/abl_states/run.py +5 -5
  3. examples/dyn_wakes/run.py +2 -2
  4. examples/induction/run.py +5 -5
  5. examples/random_timeseries/run.py +13 -13
  6. examples/scan_row/run.py +12 -7
  7. examples/sector_management/run.py +11 -7
  8. examples/single_state/run.py +5 -5
  9. examples/tab_file/run.py +1 -1
  10. examples/timelines/run.py +1 -1
  11. examples/timeseries/run.py +5 -5
  12. examples/timeseries_slurm/run.py +5 -5
  13. examples/wind_rose/run.py +1 -1
  14. examples/yawed_wake/run.py +5 -5
  15. foxes/__init__.py +13 -2
  16. foxes/algorithms/downwind/downwind.py +21 -6
  17. foxes/algorithms/downwind/models/init_farm_data.py +5 -2
  18. foxes/algorithms/downwind/models/point_wakes_calc.py +0 -1
  19. foxes/algorithms/iterative/iterative.py +1 -1
  20. foxes/algorithms/sequential/sequential.py +5 -4
  21. foxes/config/__init__.py +1 -0
  22. foxes/config/config.py +134 -0
  23. foxes/constants.py +15 -6
  24. foxes/core/algorithm.py +46 -30
  25. foxes/core/axial_induction_model.py +18 -0
  26. foxes/core/data.py +2 -1
  27. foxes/core/engine.py +43 -49
  28. foxes/core/farm_controller.py +22 -3
  29. foxes/core/farm_data_model.py +6 -2
  30. foxes/core/ground_model.py +19 -0
  31. foxes/core/model.py +2 -1
  32. foxes/core/partial_wakes_model.py +9 -21
  33. foxes/core/point_data_model.py +22 -2
  34. foxes/core/rotor_model.py +9 -21
  35. foxes/core/states.py +2 -17
  36. foxes/core/turbine_model.py +2 -18
  37. foxes/core/turbine_type.py +2 -18
  38. foxes/core/vertical_profile.py +8 -20
  39. foxes/core/wake_frame.py +9 -25
  40. foxes/core/wake_model.py +24 -20
  41. foxes/core/wake_superposition.py +19 -0
  42. foxes/data/__init__.py +1 -1
  43. foxes/data/static_data.py +0 -7
  44. foxes/engines/dask.py +4 -3
  45. foxes/engines/single.py +1 -1
  46. foxes/input/__init__.py +1 -1
  47. foxes/input/farm_layout/from_csv.py +3 -1
  48. foxes/input/farm_layout/from_file.py +10 -10
  49. foxes/input/farm_layout/from_json.py +4 -3
  50. foxes/input/farm_layout/grid.py +3 -3
  51. foxes/input/states/__init__.py +1 -1
  52. foxes/input/states/create/random_abl_states.py +5 -3
  53. foxes/input/states/field_data_nc.py +36 -15
  54. foxes/input/states/multi_height.py +26 -15
  55. foxes/input/states/one_point_flow.py +6 -5
  56. foxes/input/states/{scan_ws.py → scan.py} +42 -52
  57. foxes/input/states/single.py +15 -6
  58. foxes/input/states/slice_data_nc.py +18 -12
  59. foxes/input/states/states_table.py +17 -10
  60. foxes/input/yaml/__init__.py +3 -0
  61. foxes/input/yaml/dict.py +381 -0
  62. foxes/input/yaml/windio/__init__.py +4 -0
  63. foxes/input/{windio → yaml/windio}/get_states.py +7 -7
  64. foxes/input/{windio → yaml/windio}/read_attributes.py +61 -40
  65. foxes/input/{windio → yaml/windio}/read_farm.py +34 -43
  66. foxes/input/{windio → yaml/windio}/read_fields.py +11 -10
  67. foxes/input/yaml/windio/read_outputs.py +147 -0
  68. foxes/input/yaml/windio/windio.py +269 -0
  69. foxes/input/yaml/yaml.py +103 -0
  70. foxes/models/partial_wakes/axiwake.py +7 -6
  71. foxes/models/partial_wakes/centre.py +3 -2
  72. foxes/models/partial_wakes/segregated.py +5 -2
  73. foxes/models/point_models/set_uniform_data.py +5 -3
  74. foxes/models/rotor_models/centre.py +2 -2
  75. foxes/models/rotor_models/grid.py +5 -5
  76. foxes/models/rotor_models/levels.py +6 -6
  77. foxes/models/turbine_models/kTI_model.py +3 -1
  78. foxes/models/turbine_models/lookup_table.py +7 -4
  79. foxes/models/turbine_models/power_mask.py +14 -8
  80. foxes/models/turbine_models/sector_management.py +4 -2
  81. foxes/models/turbine_models/set_farm_vars.py +53 -23
  82. foxes/models/turbine_models/table_factors.py +8 -7
  83. foxes/models/turbine_models/yaw2yawm.py +0 -1
  84. foxes/models/turbine_models/yawm2yaw.py +0 -1
  85. foxes/models/turbine_types/CpCt_file.py +6 -3
  86. foxes/models/turbine_types/CpCt_from_two.py +6 -3
  87. foxes/models/turbine_types/PCt_file.py +7 -6
  88. foxes/models/turbine_types/PCt_from_two.py +11 -2
  89. foxes/models/turbine_types/TBL_file.py +3 -4
  90. foxes/models/turbine_types/wsrho2PCt_from_two.py +19 -11
  91. foxes/models/turbine_types/wsti2PCt_from_two.py +19 -11
  92. foxes/models/vertical_profiles/abl_log_neutral_ws.py +1 -1
  93. foxes/models/vertical_profiles/abl_log_stable_ws.py +1 -1
  94. foxes/models/vertical_profiles/abl_log_unstable_ws.py +1 -1
  95. foxes/models/vertical_profiles/abl_log_ws.py +1 -1
  96. foxes/models/wake_frames/dynamic_wakes.py +17 -9
  97. foxes/models/wake_frames/farm_order.py +4 -3
  98. foxes/models/wake_frames/rotor_wd.py +3 -1
  99. foxes/models/wake_frames/seq_dynamic_wakes.py +14 -7
  100. foxes/models/wake_frames/streamlines.py +9 -6
  101. foxes/models/wake_frames/timelines.py +21 -14
  102. foxes/models/wake_frames/yawed_wakes.py +3 -1
  103. foxes/models/wake_models/induction/vortex_sheet.py +0 -1
  104. foxes/models/wake_models/ti/crespo_hernandez.py +2 -1
  105. foxes/models/wake_models/wind/bastankhah14.py +3 -2
  106. foxes/models/wake_models/wind/bastankhah16.py +2 -1
  107. foxes/models/wake_models/wind/turbopark.py +9 -7
  108. foxes/models/wake_superpositions/ws_product.py +0 -1
  109. foxes/output/__init__.py +2 -1
  110. foxes/output/calc_points.py +7 -4
  111. foxes/output/farm_layout.py +30 -18
  112. foxes/output/farm_results_eval.py +61 -38
  113. foxes/output/grids.py +8 -7
  114. foxes/output/output.py +9 -20
  115. foxes/output/plt.py +19 -0
  116. foxes/output/results_writer.py +10 -11
  117. foxes/output/rose_plot.py +448 -224
  118. foxes/output/rotor_point_plots.py +7 -3
  119. foxes/output/slice_data.py +1 -1
  120. foxes/output/state_turbine_map.py +5 -1
  121. foxes/output/state_turbine_table.py +7 -3
  122. foxes/output/turbine_type_curves.py +7 -2
  123. foxes/utils/__init__.py +1 -2
  124. foxes/utils/dict.py +107 -3
  125. foxes/utils/geopandas_utils.py +3 -2
  126. foxes/utils/subclasses.py +69 -0
  127. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/METADATA +18 -18
  128. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/RECORD +145 -145
  129. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/WHEEL +1 -1
  130. foxes-1.2.1.dist-info/entry_points.txt +3 -0
  131. tests/0_consistency/iterative/test_iterative.py +65 -67
  132. tests/0_consistency/partial_wakes/test_partial_wakes.py +58 -61
  133. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +56 -53
  134. tests/1_verification/flappy_0_6/abl_states/test_abl_states.py +41 -41
  135. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +34 -34
  136. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +57 -52
  137. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +58 -54
  138. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +80 -76
  139. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +80 -76
  140. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +58 -51
  141. tests/1_verification/flappy_0_6_2/grid_rotors/test_grid_rotors.py +101 -103
  142. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +67 -64
  143. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +58 -54
  144. examples/windio/run.py +0 -29
  145. foxes/data/states/windio_timeseries_5000.nc +0 -0
  146. foxes/data/windio/DTU_10MW_turbine.yaml +0 -10
  147. foxes/data/windio/__init__.py +0 -0
  148. foxes/data/windio/windio_5turbines_timeseries.yaml +0 -79
  149. foxes/input/windio/__init__.py +0 -11
  150. foxes/input/windio/read_outputs.py +0 -172
  151. foxes/input/windio/runner.py +0 -183
  152. foxes/input/windio/windio.py +0 -193
  153. foxes/utils/windrose_plot.py +0 -152
  154. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/LICENSE +0 -0
  155. {foxes-1.1.1.dist-info → foxes-1.2.1.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  from abc import abstractmethod
2
2
 
3
+ from foxes.utils import new_instance
3
4
  import foxes.constants as FC
4
- from foxes.utils import all_subclasses
5
5
 
6
6
  from .turbine_model import TurbineModel
7
7
 
@@ -127,20 +127,4 @@ class TurbineType(TurbineModel):
127
127
  Additional parameters for constructor
128
128
 
129
129
  """
130
-
131
- if ttype_type is None:
132
- return None
133
-
134
- allc = all_subclasses(cls)
135
- found = ttype_type in [scls.__name__ for scls in allc]
136
-
137
- if found:
138
- for scls in allc:
139
- if scls.__name__ == ttype_type:
140
- return scls(*args, **kwargs)
141
-
142
- else:
143
- estr = "Turbine type class '{}' is not defined, available types are \n {}".format(
144
- ttype_type, sorted([i.__name__ for i in allc])
145
- )
146
- raise KeyError(estr)
130
+ return new_instance(cls, ttype_type, *args, **kwargs)
@@ -1,7 +1,7 @@
1
1
  from abc import abstractmethod
2
2
 
3
3
  from .model import Model
4
- from foxes.utils import all_subclasses
4
+ from foxes.utils import new_instance
5
5
 
6
6
 
7
7
  class VerticalProfile(Model):
@@ -48,30 +48,18 @@ class VerticalProfile(Model):
48
48
  pass
49
49
 
50
50
  @classmethod
51
- def new(cls, profile_type, **kwargs):
51
+ def new(cls, profile_type, *args, **kwargs):
52
52
  """
53
- Run-time profile factory.
53
+ Run-time vertical profile factory.
54
54
 
55
55
  Parameters
56
56
  ----------
57
57
  profile_type: str
58
58
  The selected derived class name
59
+ args: tuple, optional
60
+ Additional parameters for the constructor
61
+ kwargs: dict, optional
62
+ Additional parameters for the constructor
59
63
 
60
64
  """
61
-
62
- if profile_type is None:
63
- return None
64
-
65
- allc = all_subclasses(cls)
66
- found = profile_type in [scls.__name__ for scls in allc]
67
-
68
- if found:
69
- for scls in allc:
70
- if scls.__name__ == profile_type:
71
- return scls(**kwargs)
72
-
73
- else:
74
- estr = "Vertical profile type '{}' is not defined, available types are \n {}".format(
75
- profile_type, sorted([i.__name__ for i in allc])
76
- )
77
- raise KeyError(estr)
65
+ return new_instance(cls, profile_type, *args, **kwargs)
foxes/core/wake_frame.py CHANGED
@@ -2,9 +2,10 @@ from abc import abstractmethod
2
2
  import numpy as np
3
3
  from scipy.interpolate import interpn
4
4
 
5
- from foxes.utils import all_subclasses
6
- import foxes.constants as FC
5
+ from foxes.utils import new_instance
6
+ from foxes.config import config
7
7
  import foxes.variables as FV
8
+ import foxes.constants as FC
8
9
 
9
10
  from .data import TData
10
11
  from .model import Model
@@ -243,7 +244,7 @@ class WakeFrame(Model):
243
244
  n_steps += 1
244
245
  n_ix = n_steps + 1
245
246
  xs = np.arange(xmin, xmin + n_ix * dx, dx)
246
- xpts = np.zeros((n_states, n_steps), dtype=FC.DTYPE)
247
+ xpts = np.zeros((n_states, n_steps), dtype=config.dtype_double)
247
248
  xpts[:] = xs[None, 1:]
248
249
  pts = self.get_centreline_points(algo, mdata, fdata, downwind_index, xpts)
249
250
 
@@ -251,7 +252,8 @@ class WakeFrame(Model):
251
252
  tdata = TData.from_points(
252
253
  pts,
253
254
  data={
254
- v: np.full((n_states, n_steps, 1), np.nan, dtype=FC.DTYPE) for v in vrs
255
+ v: np.full((n_states, n_steps, 1), np.nan, dtype=config.dtype_double)
256
+ for v in vrs
255
257
  },
256
258
  dims={v: (FC.STATE, FC.TARGET, FC.TPOINT) for v in vrs},
257
259
  )
@@ -280,13 +282,13 @@ class WakeFrame(Model):
280
282
  del wcalc, res
281
283
 
282
284
  # collect integration results:
283
- iresults = np.zeros((n_states, n_ix, n_vars), dtype=FC.DTYPE)
285
+ iresults = np.zeros((n_states, n_ix, n_vars), dtype=config.dtype_double)
284
286
  for vi, v in enumerate(variables):
285
287
  for i in range(n_steps):
286
288
  iresults[:, i + 1, vi] = iresults[:, i, vi] + tdata[v][:, i, 0] * dx
287
289
 
288
290
  # interpolate to x of interest:
289
- qts = np.zeros((n_states, n_points, 2), dtype=FC.DTYPE)
291
+ qts = np.zeros((n_states, n_points, 2), dtype=config.dtype_double)
290
292
  qts[:, :, 0] = np.arange(n_states)[:, None]
291
293
  qts[:, :, 1] = x
292
294
  qts = qts.reshape(n_states * n_points, 2)
@@ -316,22 +318,4 @@ class WakeFrame(Model):
316
318
  Additional parameters for constructor
317
319
 
318
320
  """
319
-
320
- if wframe_type is None:
321
- return None
322
-
323
- allc = all_subclasses(cls)
324
- found = wframe_type in [scls.__name__ for scls in allc]
325
-
326
- if found:
327
- for scls in allc:
328
- if scls.__name__ == wframe_type:
329
- return scls(*args, **kwargs)
330
-
331
- else:
332
- estr = (
333
- "Wake frame type '{}' is not defined, available types are \n {}".format(
334
- wframe_type, sorted([i.__name__ for i in allc])
335
- )
336
- )
337
- raise KeyError(estr)
321
+ return new_instance(cls, wframe_type, *args, **kwargs)
foxes/core/wake_model.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from abc import abstractmethod
2
2
  import numpy as np
3
3
 
4
- from foxes.utils import all_subclasses, Factory
4
+ from foxes.utils import new_instance
5
5
  import foxes.variables as FV
6
6
  import foxes.constants as FC
7
7
 
@@ -141,25 +141,7 @@ class WakeModel(Model):
141
141
  Additional parameters for constructor
142
142
 
143
143
  """
144
-
145
- if wmodel_type is None:
146
- return None
147
-
148
- allc = all_subclasses(cls)
149
- found = wmodel_type in [scls.__name__ for scls in allc]
150
-
151
- if found:
152
- for scls in allc:
153
- if scls.__name__ == wmodel_type:
154
- return scls(*args, **kwargs)
155
-
156
- else:
157
- estr = (
158
- "Wake model type '{}' is not defined, available types are \n {}".format(
159
- wmodel_type, sorted([i.__name__ for i in allc])
160
- )
161
- )
162
- raise KeyError(estr)
144
+ return new_instance(cls, wmodel_type, *args, **kwargs)
163
145
 
164
146
 
165
147
  class TurbineInductionModel(WakeModel):
@@ -184,6 +166,23 @@ class TurbineInductionModel(WakeModel):
184
166
  """
185
167
  return False
186
168
 
169
+ @classmethod
170
+ def new(cls, induction_type, *args, **kwargs):
171
+ """
172
+ Run-time turbine induction model factory.
173
+
174
+ Parameters
175
+ ----------
176
+ induction_type: str
177
+ The selected derived class name
178
+ args: tuple, optional
179
+ Additional parameters for constructor
180
+ kwargs: dict, optional
181
+ Additional parameters for constructor
182
+
183
+ """
184
+ return new_instance(cls, induction_type, *args, **kwargs)
185
+
187
186
 
188
187
  class WakeK(Model):
189
188
  """
@@ -259,6 +258,11 @@ class WakeK(Model):
259
258
  s = f"k_var={self.k_var}"
260
259
  return s
261
260
 
261
+ @property
262
+ def is_kTI(self):
263
+ """Flag for ka != 0"""
264
+ return self._ka is not None and self._ka != 0
265
+
262
266
  @property
263
267
  def all_none(self):
264
268
  """Flag for k=ka=kb=None"""
@@ -1,5 +1,7 @@
1
1
  from abc import abstractmethod
2
2
 
3
+ from foxes.utils import new_instance
4
+
3
5
  from .model import Model
4
6
 
5
7
 
@@ -106,3 +108,20 @@ class WakeSuperposition(Model):
106
108
 
107
109
  """
108
110
  pass
111
+
112
+ @classmethod
113
+ def new(cls, superp_type, *args, **kwargs):
114
+ """
115
+ Run-time wake superposition model factory.
116
+
117
+ Parameters
118
+ ----------
119
+ superp_type: str
120
+ The selected derived class name
121
+ args: tuple, optional
122
+ Additional parameters for constructor
123
+ kwargs: dict, optional
124
+ Additional parameters for constructor
125
+
126
+ """
127
+ return new_instance(cls, superp_type, *args, **kwargs)
foxes/data/__init__.py CHANGED
@@ -3,4 +3,4 @@ Static data collection.
3
3
  """
4
4
 
5
5
  from .parse import parse_Pct_file_name, parse_Pct_two_files
6
- from .static_data import FARM, STATES, PCTCURVE, WINDIO, StaticData
6
+ from .static_data import FARM, STATES, PCTCURVE, StaticData
foxes/data/static_data.py CHANGED
@@ -3,7 +3,6 @@ from foxes.utils import DataBook
3
3
  from . import farms
4
4
  from . import states
5
5
  from . import power_ct_curves
6
- from . import windio
7
6
 
8
7
  FARM = "farm"
9
8
  """ Static wind farm data identifier
@@ -20,11 +19,6 @@ PCTCURVE = "power_ct_curve"
20
19
  :group: data
21
20
  """
22
21
 
23
- WINDIO = "windio"
24
- """ Static windio data identifier
25
- :group: data
26
- """
27
-
28
22
 
29
23
  class StaticData(DataBook):
30
24
  """
@@ -41,4 +35,3 @@ class StaticData(DataBook):
41
35
  self.add_data_package(FARM, farms, ".csv")
42
36
  self.add_data_package(STATES, states, [".csv", ".csv.gz", ".nc", ".tab"])
43
37
  self.add_data_package(PCTCURVE, power_ct_curves, ".csv")
44
- self.add_data_package(WINDIO, windio, ".yaml")
foxes/engines/dask.py CHANGED
@@ -5,6 +5,7 @@ from tqdm import tqdm
5
5
 
6
6
  from foxes.core import Engine, MData, FData, TData
7
7
  from foxes.utils import import_module
8
+ from foxes.config import config
8
9
  import foxes.variables as FV
9
10
  import foxes.constants as FC
10
11
 
@@ -212,7 +213,7 @@ def _run_as_ufunc(
212
213
  odims = {v: tuple(out_coords) for v in out_vars}
213
214
  odata = {
214
215
  v: (
215
- np.full(oshape, np.nan, dtype=FC.DTYPE)
216
+ np.full(oshape, np.nan, dtype=config.dtype_double)
216
217
  if v not in init_vars
217
218
  else prev[init_vars.index(v)].copy()
218
219
  )
@@ -264,7 +265,7 @@ def _run_as_ufunc(
264
265
 
265
266
  # create output:
266
267
  n_vars = len(out_vars)
267
- data = np.zeros(oshape + [n_vars], dtype=FC.DTYPE)
268
+ data = np.zeros(oshape + [n_vars], dtype=config.dtype_double)
268
269
  for v in out_vars:
269
270
  data[..., out_vars.index(v)] = results[v]
270
271
 
@@ -449,7 +450,7 @@ class XArrayEngine(DaskBaseEngine):
449
450
  *ldata,
450
451
  input_core_dims=[[]] + iidims + icdims,
451
452
  output_core_dims=[out_core_vars],
452
- output_dtypes=[FC.DTYPE],
453
+ output_dtypes=[config.dtype_double],
453
454
  dask="parallelized",
454
455
  dask_gufunc_kwargs=dargs,
455
456
  kwargs=wargs,
foxes/engines/single.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from xarray import Dataset
2
2
 
3
- import foxes.constants as FC
4
3
  from foxes.core import Engine
4
+ import foxes.constants as FC
5
5
 
6
6
 
7
7
  class SingleChunkEngine(Engine):
foxes/input/__init__.py CHANGED
@@ -4,4 +4,4 @@ Functions and classes for input data definition.
4
4
 
5
5
  from . import farm_layout
6
6
  from . import states
7
- from . import windio
7
+ from . import yaml
@@ -1,6 +1,7 @@
1
1
  import pandas as pd
2
2
 
3
3
  from foxes.core import Turbine
4
+ from foxes.config import get_path
4
5
 
5
6
 
6
7
  def add_from_csv(
@@ -75,7 +76,8 @@ def add_from_csv(
75
76
  else:
76
77
  if verbosity:
77
78
  print("Reading file", data_source)
78
- data = pd.read_csv(data_source, index_col=col_index)
79
+ pth = get_path(data_source)
80
+ data = pd.read_csv(pth, index_col=col_index)
79
81
 
80
82
  tmodels = turbine_parameters.pop("turbine_models", [])
81
83
  H = turbine_parameters.pop("H", None)
@@ -1,6 +1,6 @@
1
- from pathlib import Path
2
-
3
1
  from foxes.data import FARM, StaticData
2
+ from foxes.config import get_path
3
+
4
4
  from .from_json import add_from_json
5
5
  from .from_csv import add_from_csv
6
6
 
@@ -31,24 +31,24 @@ def add_from_file(farm, file_path, *args, verbosity=1, dbook=None, **kwargs):
31
31
 
32
32
  """
33
33
 
34
- fpath = Path(file_path)
34
+ fpath = get_path(file_path)
35
35
  dbook = StaticData() if dbook is None else dbook
36
36
 
37
37
  if not fpath.is_file():
38
38
  if verbosity:
39
39
  print(f"Reading static data '{fpath.name}' from context '{FARM}'")
40
- fpath = dbook.get_file_path(FARM, fpath.name, check_raw=False)
40
+ file_path = dbook.get_file_path(FARM, fpath.name, check_raw=False)
41
41
 
42
42
  if fpath.suffix == ".json":
43
- add_from_json(farm, fpath, *args, **kwargs)
43
+ add_from_json(farm, file_path, *args, **kwargs)
44
44
  elif (
45
45
  fpath.suffix == ".csv"
46
- or (len(fpath) > 7 and fpath[-7:] == ".csv.gz")
47
- or (len(fpath) > 8 and fpath[-8:] == ".csv.bz2")
48
- or (len(fpath) > 8 and fpath[-8:] == ".csv.zip")
46
+ or (len(file_path) > 7 and file_path[-7:] == ".csv.gz")
47
+ or (len(file_path) > 8 and file_path[-8:] == ".csv.bz2")
48
+ or (len(file_path) > 8 and file_path[-8:] == ".csv.zip")
49
49
  ):
50
- add_from_csv(farm, fpath, *args, verbosity=verbosity, **kwargs)
50
+ add_from_csv(farm, file_path, *args, verbosity=verbosity, **kwargs)
51
51
  else:
52
52
  raise KeyError(
53
- f"Unsupported file suffix: '{fpath}'. Please provide any of: json, csv, csv.gz, csv.bz2, csv.zip"
53
+ f"Unsupported file suffix: '{file_path}'. Please provide any of: json, csv, csv.gz, csv.bz2, csv.zip"
54
54
  )
@@ -3,6 +3,7 @@ import numpy as np
3
3
  from copy import deepcopy
4
4
 
5
5
  from foxes.core import Turbine
6
+ from foxes.config import get_path
6
7
 
7
8
 
8
9
  def add_from_json(
@@ -27,10 +28,10 @@ def add_from_json(
27
28
  :group: input.farm_layout
28
29
 
29
30
  """
30
-
31
+ fpath = get_path(file_path)
31
32
  if verbosity:
32
- print("Reading file", file_path)
33
- with open(file_path) as f:
33
+ print("Reading file", fpath)
34
+ with open(fpath) as f:
34
35
  dict = json.load(f)
35
36
 
36
37
  keys = list(dict.keys())
@@ -1,7 +1,7 @@
1
1
  import numpy as np
2
2
 
3
3
  from foxes.core import Turbine
4
- import foxes.constants as FC
4
+ from foxes.config import config
5
5
 
6
6
 
7
7
  def add_grid(
@@ -44,8 +44,8 @@ def add_grid(
44
44
  inds = list(np.ndindex(*steps))
45
45
  n_turbines = len(inds)
46
46
 
47
- xy_base = np.array(xy_base, dtype=FC.DTYPE)
48
- step_vectors = np.array(step_vectors, dtype=FC.DTYPE)
47
+ xy_base = np.array(xy_base, dtype=config.dtype_double)
48
+ step_vectors = np.array(step_vectors, dtype=config.dtype_double)
49
49
 
50
50
  for i in range(n_turbines):
51
51
  xi, yi = inds[i]
@@ -3,7 +3,7 @@ Atmospheric input states.
3
3
  """
4
4
 
5
5
  from .single import SingleStateStates
6
- from .scan_ws import ScanWS
6
+ from .scan import ScanStates
7
7
  from .states_table import StatesTable, Timeseries, TabStates
8
8
  from .field_data_nc import FieldDataNC
9
9
  from .slice_data_nc import SliceDataNC
@@ -1,6 +1,7 @@
1
1
  import pandas as pd
2
2
  import numpy as np
3
3
 
4
+ from foxes.config import config, get_path
4
5
  import foxes.variables as FV
5
6
  import foxes.constants as FC
6
7
 
@@ -41,7 +42,7 @@ def create_random_abl_states(
41
42
 
42
43
  for v, mm in cols_minmax.items():
43
44
  data[v] = np.random.uniform(low=mm[0], high=mm[1], size=(n_states,)).astype(
44
- FC.DTYPE
45
+ config.dtype_double
45
46
  )
46
47
 
47
48
  cmol = var2col.get(FV.MOL, FV.MOL)
@@ -98,8 +99,9 @@ def write_random_abl_states(
98
99
 
99
100
  """
100
101
 
102
+ fpath = get_path(file_path)
101
103
  if verbosity:
102
- print("Writing file", file_path)
104
+ print("Writing file", fpath)
103
105
 
104
106
  data = create_random_abl_states(
105
107
  n_states, cols_minmax, var2col, mol_abs_range, normalize
@@ -130,4 +132,4 @@ def write_random_abl_states(
130
132
  if d is not None:
131
133
  data[v] = data[v].round(d)
132
134
 
133
- data.to_csv(file_path, **kwargs)
135
+ data.to_csv(fpath, **kwargs)
@@ -2,13 +2,13 @@ import numpy as np
2
2
  import pandas as pd
3
3
  import xarray as xr
4
4
  from scipy.interpolate import interpn
5
- from pathlib import Path
6
5
 
7
6
  from foxes.core import States
8
7
  from foxes.utils import wd2uv, uv2wd, import_module
9
8
  from foxes.data import STATES, StaticData
10
9
  import foxes.variables as FV
11
10
  import foxes.constants as FC
11
+ from foxes.config import config, get_path
12
12
 
13
13
 
14
14
  class FieldDataNC(States):
@@ -150,9 +150,11 @@ class FieldDataNC(States):
150
150
  if "*" in str(self.data_source):
151
151
  pass
152
152
  else:
153
- self.__data_source = StaticData().get_file_path(
154
- STATES, self.data_source, check_raw=True
155
- )
153
+ self.__data_source = get_path(self.data_source)
154
+ if not self.data_source.is_file():
155
+ self.__data_source = StaticData().get_file_path(
156
+ STATES, self.data_source.name, check_raw=False
157
+ )
156
158
  if verbosity:
157
159
  if pre_load:
158
160
  print(
@@ -164,13 +166,14 @@ class FieldDataNC(States):
164
166
  )
165
167
 
166
168
  def _read_ds():
167
- if Path(self.data_source).is_file():
168
- return xr.open_dataset(self.data_source)
169
+ fpath = get_path(self.data_source)
170
+ if fpath.is_file():
171
+ return xr.open_dataset(fpath)
169
172
  else:
170
173
  # try to read multiple files, needs dask:
171
174
  try:
172
175
  return xr.open_mfdataset(
173
- str(self.data_source),
176
+ str(fpath),
174
177
  parallel=False,
175
178
  concat_dim=self.states_coord,
176
179
  combine="nested",
@@ -182,8 +185,7 @@ class FieldDataNC(States):
182
185
  import_module("dask", hint="pip install dask")
183
186
  raise e
184
187
 
185
- with _read_ds() as ds:
186
- self.__data_source = ds
188
+ self.__data_source = _read_ds()
187
189
 
188
190
  if sel is not None:
189
191
  self.__data_source = self.data_source.sel(self.sel)
@@ -258,30 +260,45 @@ class FieldDataNC(States):
258
260
 
259
261
  cor_shxy = (self.states_coord, self.h_coord, self.x_coord, self.y_coord)
260
262
  cor_shyx = (self.states_coord, self.h_coord, self.y_coord, self.x_coord)
263
+ cor_sxy = (self.states_coord, self.x_coord, self.y_coord)
264
+ cor_syx = (self.states_coord, self.y_coord, self.x_coord)
261
265
  cor_sh = (self.states_coord, self.h_coord)
262
266
  cor_s = (self.states_coord,)
263
267
  vars_shyx = []
268
+ vars_syx = []
264
269
  vars_sh = []
265
270
  vars_s = []
266
271
  for v, ncv in self.var2ncvar.items():
267
272
  if ds[ncv].dims == cor_shyx or ds[ncv].dims == cor_shxy:
268
273
  vars_shyx.append(v)
274
+ elif ds[ncv].dims == cor_syx or ds[ncv].dims == cor_sxy:
275
+ vars_syx.append(v)
269
276
  elif ds[ncv].dims == cor_sh:
270
277
  vars_sh.append(v)
271
278
  elif ds[ncv].dims == cor_s:
272
279
  vars_s.append(v)
273
280
  else:
274
281
  raise ValueError(
275
- f"States '{self.name}': Wrong coordinate order for variable '{ncv}': Found {ds[ncv].dims}, expecting {cor_shxy}, {cor_shyx}, {cor_sh} or {cor_s}"
282
+ f"States '{self.name}': Wrong coordinate order for variable '{ncv}': Found {ds[ncv].dims}, expecting {cor_shxy}, {cor_shyx}, {cor_sxy}, {cor_syx}, {cor_sh} or {cor_s}"
276
283
  )
277
284
 
278
- data = np.zeros((n_sts, n_h, n_y, n_x, len(self.var2ncvar)), dtype=FC.DTYPE)
285
+ data = np.zeros(
286
+ (n_sts, n_h, n_y, n_x, len(self.var2ncvar)), dtype=config.dtype_double
287
+ )
279
288
  for v in vars_shyx:
280
289
  ncv = self.var2ncvar[v]
281
290
  if ds[ncv].dims == cor_shyx:
282
291
  data[..., self._dkys[v]] = ds[ncv][:]
283
292
  else:
284
293
  data[..., self._dkys[v]] = np.swapaxes(ds[ncv].to_numpy(), 2, 3)
294
+ for v in vars_syx:
295
+ ncv = self.var2ncvar[v]
296
+ if ds[ncv].dims == cor_syx:
297
+ data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, None]
298
+ else:
299
+ data[..., self._dkys[v]] = np.swapaxes(ds[ncv].to_numpy(), 1, 2)[
300
+ :, None
301
+ ]
285
302
  for v in vars_sh:
286
303
  ncv = self.var2ncvar[v]
287
304
  data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, :, None, None]
@@ -290,7 +307,9 @@ class FieldDataNC(States):
290
307
  data[..., self._dkys[v]] = ds[ncv].to_numpy()[:, None, None, None]
291
308
  if FV.WD in self.fixed_vars:
292
309
  data[..., self._dkys[FV.WD]] = np.full(
293
- (n_sts, n_h, n_y, n_x), self.fixed_vars[FV.WD], dtype=FC.DTYPE
310
+ (n_sts, n_h, n_y, n_x),
311
+ self.fixed_vars[FV.WD],
312
+ dtype=config.dtype_double,
294
313
  )
295
314
 
296
315
  if verbosity > 1:
@@ -365,7 +384,7 @@ class FieldDataNC(States):
365
384
 
366
385
  if self.__weights is None:
367
386
  self.__weights = np.full(
368
- (self._N, algo.n_turbines), 1.0 / self._N, dtype=FC.DTYPE
387
+ (self._N, algo.n_turbines), 1.0 / self._N, dtype=config.dtype_double
369
388
  )
370
389
 
371
390
  idata = super().load_data(algo, verbosity)
@@ -608,7 +627,9 @@ class FieldDataNC(States):
608
627
 
609
628
  # prepare points:
610
629
  sts = np.arange(n_states)
611
- pts = np.append(points, np.zeros((n_states, n_pts, 1), dtype=FC.DTYPE), axis=2)
630
+ pts = np.append(
631
+ points, np.zeros((n_states, n_pts, 1), dtype=config.dtype_double), axis=2
632
+ )
612
633
  pts[:, :, 3] = sts[:, None]
613
634
  pts = pts.reshape(n_states * n_pts, 4)
614
635
  pts = np.flip(pts, axis=1)
@@ -697,7 +718,7 @@ class FieldDataNC(States):
697
718
  out[v] = data[..., self._dkys[v]]
698
719
  else:
699
720
  out[v] = np.full(
700
- (n_states, n_pts), self.fixed_vars[v], dtype=FC.DTYPE
721
+ (n_states, n_pts), self.fixed_vars[v], dtype=config.dtype_double
701
722
  )
702
723
 
703
724
  return {v: d.reshape(n_states, n_targets, n_tpoints) for v, d in out.items()}