foxes 1.3__py3-none-any.whl → 1.5__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 (228) hide show
  1. docs/source/conf.py +3 -3
  2. examples/abl_states/run.py +2 -2
  3. examples/compare_rotors_pwakes/run.py +1 -1
  4. examples/compare_wakes/run.py +1 -2
  5. examples/dyn_wakes/run.py +29 -6
  6. examples/field_data_nc/run.py +1 -1
  7. examples/induction/run.py +3 -3
  8. examples/multi_height/run.py +1 -1
  9. examples/power_mask/run.py +2 -2
  10. examples/quickstart/run.py +0 -1
  11. examples/random_timeseries/run.py +3 -4
  12. examples/scan_row/run.py +3 -3
  13. examples/sequential/run.py +33 -10
  14. examples/single_state/run.py +3 -4
  15. examples/states_lookup_table/run.py +3 -3
  16. examples/streamline_wakes/run.py +29 -6
  17. examples/tab_file/run.py +3 -3
  18. examples/timelines/run.py +29 -5
  19. examples/timeseries/run.py +3 -3
  20. examples/timeseries_slurm/run.py +3 -3
  21. examples/wind_rose/run.py +3 -3
  22. examples/yawed_wake/run.py +19 -9
  23. foxes/__init__.py +21 -17
  24. foxes/algorithms/__init__.py +6 -6
  25. foxes/algorithms/downwind/__init__.py +2 -2
  26. foxes/algorithms/downwind/downwind.py +49 -17
  27. foxes/algorithms/downwind/models/__init__.py +6 -6
  28. foxes/algorithms/downwind/models/farm_wakes_calc.py +11 -9
  29. foxes/algorithms/downwind/models/init_farm_data.py +58 -29
  30. foxes/algorithms/downwind/models/point_wakes_calc.py +7 -13
  31. foxes/algorithms/downwind/models/set_amb_farm_results.py +1 -1
  32. foxes/algorithms/downwind/models/set_amb_point_results.py +6 -6
  33. foxes/algorithms/iterative/__init__.py +7 -3
  34. foxes/algorithms/iterative/iterative.py +1 -2
  35. foxes/algorithms/iterative/models/__init__.py +7 -3
  36. foxes/algorithms/iterative/models/farm_wakes_calc.py +9 -5
  37. foxes/algorithms/sequential/__init__.py +3 -3
  38. foxes/algorithms/sequential/models/__init__.py +2 -2
  39. foxes/algorithms/sequential/sequential.py +3 -4
  40. foxes/config/__init__.py +5 -1
  41. foxes/constants.py +16 -0
  42. foxes/core/__init__.py +45 -22
  43. foxes/core/algorithm.py +5 -6
  44. foxes/core/data.py +94 -22
  45. foxes/core/data_calc_model.py +4 -2
  46. foxes/core/engine.py +42 -53
  47. foxes/core/farm_controller.py +2 -2
  48. foxes/core/farm_data_model.py +16 -13
  49. foxes/core/ground_model.py +4 -13
  50. foxes/core/model.py +24 -6
  51. foxes/core/partial_wakes_model.py +147 -10
  52. foxes/core/point_data_model.py +21 -17
  53. foxes/core/rotor_model.py +4 -3
  54. foxes/core/states.py +2 -3
  55. foxes/core/turbine.py +2 -1
  56. foxes/core/wake_deflection.py +130 -0
  57. foxes/core/wake_model.py +222 -9
  58. foxes/core/wake_superposition.py +122 -4
  59. foxes/core/wind_farm.py +6 -6
  60. foxes/data/__init__.py +7 -2
  61. foxes/data/states/point_cloud_100.nc +0 -0
  62. foxes/data/states/weibull_cloud_4.nc +0 -0
  63. foxes/data/states/weibull_grid.nc +0 -0
  64. foxes/data/states/weibull_sectors_12.csv +13 -0
  65. foxes/data/states/weibull_sectors_12.nc +0 -0
  66. foxes/engines/__init__.py +14 -15
  67. foxes/engines/dask.py +42 -20
  68. foxes/engines/default.py +2 -2
  69. foxes/engines/numpy.py +11 -13
  70. foxes/engines/pool.py +20 -11
  71. foxes/engines/single.py +8 -6
  72. foxes/input/__init__.py +3 -3
  73. foxes/input/farm_layout/__init__.py +9 -8
  74. foxes/input/farm_layout/from_arrays.py +68 -0
  75. foxes/input/farm_layout/from_csv.py +1 -1
  76. foxes/input/farm_layout/ring.py +0 -1
  77. foxes/input/states/__init__.py +28 -12
  78. foxes/input/states/create/__init__.py +3 -2
  79. foxes/input/states/dataset_states.py +710 -0
  80. foxes/input/states/field_data.py +531 -0
  81. foxes/input/states/multi_height.py +11 -6
  82. foxes/input/states/one_point_flow.py +1 -4
  83. foxes/input/states/point_cloud_data.py +618 -0
  84. foxes/input/states/scan.py +2 -0
  85. foxes/input/states/single.py +3 -1
  86. foxes/input/states/states_table.py +23 -30
  87. foxes/input/states/weibull_sectors.py +330 -0
  88. foxes/input/states/wrg_states.py +8 -6
  89. foxes/input/yaml/__init__.py +9 -3
  90. foxes/input/yaml/dict.py +42 -41
  91. foxes/input/yaml/windio/__init__.py +10 -5
  92. foxes/input/yaml/windio/read_attributes.py +42 -29
  93. foxes/input/yaml/windio/read_farm.py +17 -15
  94. foxes/input/yaml/windio/read_fields.py +4 -2
  95. foxes/input/yaml/windio/read_outputs.py +25 -15
  96. foxes/input/yaml/windio/read_site.py +172 -11
  97. foxes/input/yaml/windio/windio.py +23 -11
  98. foxes/input/yaml/yaml.py +1 -0
  99. foxes/models/__init__.py +15 -14
  100. foxes/models/axial_induction/__init__.py +2 -2
  101. foxes/models/farm_controllers/__init__.py +1 -1
  102. foxes/models/farm_models/__init__.py +1 -1
  103. foxes/models/ground_models/__init__.py +3 -2
  104. foxes/models/ground_models/wake_mirror.py +3 -3
  105. foxes/models/model_book.py +190 -63
  106. foxes/models/partial_wakes/__init__.py +6 -6
  107. foxes/models/partial_wakes/axiwake.py +30 -5
  108. foxes/models/partial_wakes/centre.py +47 -0
  109. foxes/models/partial_wakes/rotor_points.py +41 -11
  110. foxes/models/partial_wakes/segregated.py +2 -25
  111. foxes/models/partial_wakes/top_hat.py +27 -2
  112. foxes/models/point_models/__init__.py +4 -4
  113. foxes/models/rotor_models/__init__.py +4 -3
  114. foxes/models/rotor_models/centre.py +1 -1
  115. foxes/models/rotor_models/direct_infusion.py +241 -0
  116. foxes/models/turbine_models/__init__.py +11 -11
  117. foxes/models/turbine_models/calculator.py +16 -3
  118. foxes/models/turbine_models/kTI_model.py +1 -0
  119. foxes/models/turbine_models/lookup_table.py +2 -0
  120. foxes/models/turbine_models/power_mask.py +1 -0
  121. foxes/models/turbine_models/rotor_centre_calc.py +2 -0
  122. foxes/models/turbine_models/sector_management.py +1 -0
  123. foxes/models/turbine_models/set_farm_vars.py +3 -9
  124. foxes/models/turbine_models/table_factors.py +2 -0
  125. foxes/models/turbine_models/thrust2ct.py +1 -0
  126. foxes/models/turbine_models/yaw2yawm.py +2 -0
  127. foxes/models/turbine_models/yawm2yaw.py +2 -0
  128. foxes/models/turbine_types/PCt_file.py +2 -6
  129. foxes/models/turbine_types/PCt_from_two.py +1 -2
  130. foxes/models/turbine_types/__init__.py +10 -9
  131. foxes/models/turbine_types/calculator_type.py +123 -0
  132. foxes/models/turbine_types/null_type.py +1 -0
  133. foxes/models/turbine_types/wsrho2PCt_from_two.py +2 -0
  134. foxes/models/turbine_types/wsti2PCt_from_two.py +3 -1
  135. foxes/models/vertical_profiles/__init__.py +7 -7
  136. foxes/models/wake_deflections/__init__.py +3 -0
  137. foxes/models/{wake_frames/yawed_wakes.py → wake_deflections/bastankhah2016.py} +32 -111
  138. foxes/models/wake_deflections/jimenez.py +277 -0
  139. foxes/models/wake_deflections/no_deflection.py +94 -0
  140. foxes/models/wake_frames/__init__.py +6 -7
  141. foxes/models/wake_frames/dynamic_wakes.py +12 -3
  142. foxes/models/wake_frames/rotor_wd.py +3 -1
  143. foxes/models/wake_frames/seq_dynamic_wakes.py +41 -7
  144. foxes/models/wake_frames/streamlines.py +8 -6
  145. foxes/models/wake_frames/timelines.py +9 -3
  146. foxes/models/wake_models/__init__.py +7 -7
  147. foxes/models/wake_models/dist_sliced.py +50 -84
  148. foxes/models/wake_models/gaussian.py +20 -0
  149. foxes/models/wake_models/induction/__init__.py +5 -5
  150. foxes/models/wake_models/induction/rankine_half_body.py +30 -71
  151. foxes/models/wake_models/induction/rathmann.py +65 -64
  152. foxes/models/wake_models/induction/self_similar.py +65 -68
  153. foxes/models/wake_models/induction/self_similar2020.py +0 -3
  154. foxes/models/wake_models/induction/vortex_sheet.py +71 -75
  155. foxes/models/wake_models/ti/__init__.py +2 -2
  156. foxes/models/wake_models/ti/crespo_hernandez.py +5 -3
  157. foxes/models/wake_models/ti/iec_ti.py +6 -4
  158. foxes/models/wake_models/top_hat.py +58 -7
  159. foxes/models/wake_models/wind/__init__.py +6 -4
  160. foxes/models/wake_models/wind/bastankhah14.py +25 -7
  161. foxes/models/wake_models/wind/bastankhah16.py +35 -3
  162. foxes/models/wake_models/wind/jensen.py +15 -2
  163. foxes/models/wake_models/wind/turbopark.py +28 -2
  164. foxes/models/wake_superpositions/__init__.py +18 -9
  165. foxes/models/wake_superpositions/ti_linear.py +4 -4
  166. foxes/models/wake_superpositions/ti_max.py +4 -4
  167. foxes/models/wake_superpositions/ti_pow.py +4 -4
  168. foxes/models/wake_superpositions/ti_quadratic.py +4 -4
  169. foxes/models/wake_superpositions/wind_vector.py +257 -0
  170. foxes/models/wake_superpositions/ws_linear.py +9 -10
  171. foxes/models/wake_superpositions/ws_max.py +8 -8
  172. foxes/models/wake_superpositions/ws_pow.py +8 -8
  173. foxes/models/wake_superpositions/ws_product.py +4 -4
  174. foxes/models/wake_superpositions/ws_quadratic.py +8 -8
  175. foxes/output/__init__.py +21 -19
  176. foxes/output/farm_layout.py +4 -2
  177. foxes/output/farm_results_eval.py +19 -16
  178. foxes/output/flow_plots_2d/__init__.py +2 -2
  179. foxes/output/flow_plots_2d/flow_plots.py +18 -0
  180. foxes/output/flow_plots_2d/get_fig.py +5 -2
  181. foxes/output/output.py +6 -1
  182. foxes/output/results_writer.py +1 -1
  183. foxes/output/rose_plot.py +13 -3
  184. foxes/output/rotor_point_plots.py +3 -0
  185. foxes/output/seq_plugins/__init__.py +2 -2
  186. foxes/output/seq_plugins/seq_flow_ani_plugin.py +0 -3
  187. foxes/output/seq_plugins/seq_wake_debug_plugin.py +0 -1
  188. foxes/output/state_turbine_map.py +3 -0
  189. foxes/output/turbine_type_curves.py +10 -8
  190. foxes/utils/__init__.py +37 -19
  191. foxes/utils/abl/__init__.py +4 -4
  192. foxes/utils/cubic_roots.py +1 -1
  193. foxes/utils/data_book.py +4 -3
  194. foxes/utils/dict.py +49 -37
  195. foxes/utils/exec_python.py +5 -5
  196. foxes/utils/factory.py +3 -5
  197. foxes/utils/geom2d/__init__.py +7 -5
  198. foxes/utils/geopandas_utils.py +2 -2
  199. foxes/utils/pandas_utils.py +4 -3
  200. foxes/utils/tab_files.py +0 -1
  201. foxes/utils/weibull.py +28 -0
  202. foxes/utils/wrg_utils.py +3 -1
  203. foxes/utils/xarray_utils.py +9 -2
  204. foxes/variables.py +67 -9
  205. {foxes-1.3.dist-info → foxes-1.5.dist-info}/METADATA +34 -63
  206. foxes-1.5.dist-info/RECORD +328 -0
  207. {foxes-1.3.dist-info → foxes-1.5.dist-info}/WHEEL +1 -1
  208. tests/1_verification/flappy_0_6/PCt_files/flappy/run.py +2 -3
  209. tests/1_verification/flappy_0_6/PCt_files/test_PCt_files.py +1 -1
  210. tests/1_verification/flappy_0_6/abl_states/flappy/run.py +0 -1
  211. tests/1_verification/flappy_0_6/partial_top_hat/flappy/run.py +0 -1
  212. tests/1_verification/flappy_0_6/partial_top_hat/test_partial_top_hat.py +0 -2
  213. tests/1_verification/flappy_0_6/row_Jensen_linear_centre/test_row_Jensen_linear_centre.py +0 -1
  214. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat/test_row_Jensen_linear_tophat.py +0 -1
  215. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2005/test_row_Jensen_linear_tophat_IECTI_2005.py +0 -1
  216. tests/1_verification/flappy_0_6/row_Jensen_linear_tophat_IECTI2019/test_row_Jensen_linear_tophat_IECTI_2019.py +0 -1
  217. tests/1_verification/flappy_0_6/row_Jensen_quadratic_centre/test_row_Jensen_quadratic_centre.py +0 -1
  218. tests/1_verification/flappy_0_6_2/grid_rotors/flappy/run.py +0 -2
  219. tests/1_verification/flappy_0_6_2/row_Bastankhah_Crespo/test_row_Bastankhah_Crespo.py +0 -1
  220. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/flappy/run.py +0 -1
  221. tests/1_verification/flappy_0_6_2/row_Bastankhah_linear_centre/test_row_Bastankhah_linear_centre.py +0 -1
  222. foxes/input/states/field_data_nc.py +0 -847
  223. foxes/output/round.py +0 -10
  224. foxes/utils/pandas_helpers.py +0 -178
  225. foxes-1.3.dist-info/RECORD +0 -313
  226. {foxes-1.3.dist-info → foxes-1.5.dist-info}/entry_points.txt +0 -0
  227. {foxes-1.3.dist-info → foxes-1.5.dist-info/licenses}/LICENSE +0 -0
  228. {foxes-1.3.dist-info → foxes-1.5.dist-info}/top_level.txt +0 -0
foxes/output/__init__.py CHANGED
@@ -2,24 +2,26 @@
2
2
  Output tools and functions.
3
3
  """
4
4
 
5
- from .round import round_defaults
6
- from .output import Output
7
- from .farm_layout import FarmLayoutOutput
8
- from .farm_results_eval import FarmResultsEval
9
- from .rose_plot import RosePlotOutput, StatesRosePlotOutput, WindRoseBinPlot
10
- from .results_writer import ResultsWriter
11
- from .state_turbine_map import StateTurbineMap
12
- from .turbine_type_curves import TurbineTypeCurves
13
- from .animation import Animator
14
- from .calc_points import PointCalculator
15
- from .slice_data import SliceData
16
- from .slices_data import SlicesData
17
- from .rotor_point_plots import RotorPointPlot
18
- from .state_turbine_table import StateTurbineTable
19
- from .plt import plt
5
+ from .output import Output as Output
6
+ from .farm_layout import FarmLayoutOutput as FarmLayoutOutput
7
+ from .farm_results_eval import FarmResultsEval as FarmResultsEval
8
+ from .rose_plot import RosePlotOutput as RosePlotOutput
9
+ from .rose_plot import StatesRosePlotOutput as StatesRosePlotOutput
10
+ from .rose_plot import WindRoseBinPlot as WindRoseBinPlot
11
+ from .results_writer import ResultsWriter as ResultsWriter
12
+ from .state_turbine_map import StateTurbineMap as StateTurbineMap
13
+ from .turbine_type_curves import TurbineTypeCurves as TurbineTypeCurves
14
+ from .animation import Animator as Animator
15
+ from .calc_points import PointCalculator as PointCalculator
16
+ from .slice_data import SliceData as SliceData
17
+ from .slices_data import SlicesData as SlicesData
18
+ from .rotor_point_plots import RotorPointPlot as RotorPointPlot
19
+ from .state_turbine_table import StateTurbineTable as StateTurbineTable
20
+ from .plt import plt as plt
20
21
 
21
- from .flow_plots_2d import FlowPlots2D
22
- from .seq_plugins import SeqFlowAnimationPlugin, SeqWakeDebugPlugin
22
+ from .flow_plots_2d import FlowPlots2D as FlowPlots2D
23
+ from .seq_plugins import SeqFlowAnimationPlugin as SeqFlowAnimationPlugin
24
+ from .seq_plugins import SeqWakeDebugPlugin as SeqWakeDebugPlugin
23
25
 
24
- from . import grids
25
- from . import seq_plugins
26
+ from . import grids as grids
27
+ from . import seq_plugins as seq_plugins
@@ -67,10 +67,10 @@ class FarmLayoutOutput(Output):
67
67
  self.D = D
68
68
 
69
69
  if from_results and farm_results is None:
70
- raise ValueError(f"Missing farm_results for switch from_results.")
70
+ raise ValueError("Missing farm_results for switch from_results.")
71
71
 
72
72
  if from_results and results_state is None:
73
- raise ValueError(f"Please specify results_state for switch from_results.")
73
+ raise ValueError("Please specify results_state for switch from_results.")
74
74
 
75
75
  def get_layout_data(self):
76
76
  """
@@ -186,6 +186,8 @@ class FarmLayoutOutput(Output):
186
186
  The image object
187
187
 
188
188
  """
189
+ if self.nofig:
190
+ return None, None
189
191
 
190
192
  if fig is None:
191
193
  fig = plt.figure(figsize=figsize)
@@ -25,7 +25,7 @@ class FarmResultsEval(Output):
25
25
 
26
26
  """
27
27
 
28
- def __init__(self, farm_results):
28
+ def __init__(self, farm_results, **kwargs):
29
29
  """
30
30
  Constructor.
31
31
 
@@ -33,8 +33,11 @@ class FarmResultsEval(Output):
33
33
  ----------
34
34
  farm_results: xarray.Dataset
35
35
  The farm results
36
+ kwargs: dict, optional
37
+ Additional parameters for the base class
36
38
 
37
39
  """
40
+ super().__init__(**kwargs)
38
41
  self.results = farm_results
39
42
 
40
43
  def weinsum(self, rhs, *vars):
@@ -66,9 +69,9 @@ class FarmResultsEval(Output):
66
69
  if isinstance(v, str):
67
70
  vdata = self.results[v].to_numpy()
68
71
  nns = np.sum(np.isnan(vdata))
69
- assert (
70
- nns == 0
71
- ), f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
72
+ assert nns == 0, (
73
+ f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
74
+ )
72
75
  fields.append(vdata)
73
76
  else:
74
77
  fields.append(v)
@@ -142,9 +145,9 @@ class FarmResultsEval(Output):
142
145
  for v, op in vars_op.items():
143
146
  vdata = self.results[v].to_numpy()
144
147
  nns = np.sum(np.isnan(vdata))
145
- assert (
146
- nns == 0
147
- ), f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
148
+ assert nns == 0, (
149
+ f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
150
+ )
148
151
 
149
152
  if op == "weights":
150
153
  rdata[v] = self.weinsum("t", vdata)
@@ -191,9 +194,9 @@ class FarmResultsEval(Output):
191
194
  for v, op in vars_op.items():
192
195
  vdata = self.results[v].to_numpy()
193
196
  nns = np.sum(np.isnan(vdata))
194
- assert (
195
- nns == 0
196
- ), f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
197
+ assert nns == 0, (
198
+ f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
199
+ )
197
200
 
198
201
  if op == "weights":
199
202
  rdata[v] = self.weinsum("s", vdata)
@@ -244,9 +247,9 @@ class FarmResultsEval(Output):
244
247
  for v, op in turbines_op.items():
245
248
  vdata = sdata[v].to_numpy()
246
249
  nns = np.sum(np.isnan(vdata))
247
- assert (
248
- nns == 0
249
- ), f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
250
+ assert nns == 0, (
251
+ f"Found {nns} nan values for variable '{v}' of shape {vdata.shape}"
252
+ )
250
253
 
251
254
  if op == "weights":
252
255
  if states_op[v] == "weights":
@@ -471,11 +474,11 @@ class FarmResultsEval(Output):
471
474
  duration = times[-1] - times[0] + delta_t
472
475
  duration_seconds = np.int64(duration.astype(np.int64) / 1e9)
473
476
  duration_hours = duration_seconds / 3600
474
- elif hours is None and annual == True:
477
+ elif hours is None and annual:
475
478
  duration_hours = 8760
476
479
  elif hours is None:
477
480
  raise ValueError(
478
- f"Expecting parameter 'hours' for non-timeseries data, or 'annual=True'"
481
+ "Expecting parameter 'hours' for non-timeseries data, or 'annual=True'"
479
482
  )
480
483
  else:
481
484
  duration_hours = hours
@@ -654,7 +657,7 @@ class FarmResultsEval(Output):
654
657
  else:
655
658
  hax = ax
656
659
 
657
- hax.set_xlabel(f"State")
660
+ hax.set_xlabel("State")
658
661
  hax.set_ylabel(variable)
659
662
  cc = cycler(color="bgrcmyk")
660
663
 
@@ -1,2 +1,2 @@
1
- from .flow_plots import FlowPlots2D
2
- from .get_fig import get_fig
1
+ from .flow_plots import FlowPlots2D as FlowPlots2D
2
+ from .get_fig import get_fig as get_fig
@@ -96,6 +96,9 @@ class FlowPlots2D(SliceData):
96
96
  The image data, shape: (n_x, n_y)
97
97
 
98
98
  """
99
+ if self.nofig:
100
+ return None
101
+
99
102
  variables = list(set([var] + [FV.WD, FV.WS]))
100
103
  vi = variables.index(var)
101
104
  wdi = variables.index(FV.WD)
@@ -245,6 +248,9 @@ class FlowPlots2D(SliceData):
245
248
  The image data, shape: (n_x, n_y)
246
249
 
247
250
  """
251
+ if self.nofig:
252
+ return None
253
+
248
254
  variables = list(set([var] + [FV.WD, FV.WS]))
249
255
  vi = variables.index(var)
250
256
  wdi = variables.index(FV.WD)
@@ -395,6 +401,9 @@ class FlowPlots2D(SliceData):
395
401
  The image data, shape: (n_x, n_y)
396
402
 
397
403
  """
404
+ if self.nofig:
405
+ return None
406
+
398
407
  variables = list(set([var] + [FV.WD, FV.WS]))
399
408
  vi = variables.index(var)
400
409
  wdi = variables.index(FV.WD)
@@ -547,6 +556,9 @@ class FlowPlots2D(SliceData):
547
556
  or matplotlib.QuadContourSet
548
557
 
549
558
  """
559
+ if self.nofig:
560
+ yield None
561
+
550
562
  variables = list(set([var] + [FV.WD, FV.WS]))
551
563
  vi = variables.index(var)
552
564
  wdi = variables.index(FV.WD)
@@ -735,6 +747,9 @@ class FlowPlots2D(SliceData):
735
747
  or matplotlib.QuadContourSet
736
748
 
737
749
  """
750
+ if self.nofig:
751
+ yield None
752
+
738
753
  variables = list(set([var] + [FV.WD, FV.WS]))
739
754
  vi = variables.index(var)
740
755
  wdi = variables.index(FV.WD)
@@ -921,6 +936,9 @@ class FlowPlots2D(SliceData):
921
936
  or matplotlib.QuadContourSet
922
937
 
923
938
  """
939
+ if self.nofig:
940
+ yield None
941
+
924
942
  variables = list(set([var] + [FV.WD, FV.WS]))
925
943
  vi = variables.index(var)
926
944
  wdi = variables.index(FV.WD)
@@ -96,6 +96,7 @@ def get_fig(
96
96
  or matplotlib.QuadContourSet
97
97
 
98
98
  """
99
+
99
100
  # create plot:
100
101
  if fig is None:
101
102
  hfig = plt.figure(figsize=figsize)
@@ -181,6 +182,7 @@ def get_fig(
181
182
  hax.invert_yaxis()
182
183
 
183
184
  # add rotor position:
185
+ imr = []
184
186
  if show_rotor_dict is not None:
185
187
  D = show_rotor_dict["D"]
186
188
  coords = np.zeros(shape=(2, len(D))) # array to hold change to turbine coords
@@ -211,12 +213,13 @@ def get_fig(
211
213
  turb_x2 = x[t] - coords[0, t]
212
214
  turb_y1 = y[t] + coords[1, t]
213
215
  turb_y2 = y[t] - coords[1, t]
214
- hax.plot(
216
+ imr += hax.plot(
215
217
  [turb_x1, turb_x2],
216
218
  [turb_y1, turb_y2],
217
219
  color=c,
218
220
  linestyle="-",
219
221
  linewidth=1,
222
+ animated=animated,
220
223
  )
221
224
 
222
225
  if add_bar:
@@ -233,7 +236,7 @@ def get_fig(
233
236
  if ret_state:
234
237
  out.append(si)
235
238
  if ret_im:
236
- out.append([i for i in [im, qv, ttl] if i is not None])
239
+ out.append([i for i in [im, qv, ttl] if i is not None] + imr)
237
240
  if ret_state or ret_im:
238
241
  out = tuple(out)
239
242
 
foxes/output/output.py CHANGED
@@ -17,12 +17,14 @@ class Output:
17
17
  The output file directory
18
18
  out_fname_fun: Function, optional
19
19
  Modifies file names by f(fname)
20
+ nofig: bool
21
+ Do not show figures
20
22
 
21
23
  :group: output
22
24
 
23
25
  """
24
26
 
25
- def __init__(self, out_dir=None, out_fname_fun=None):
27
+ def __init__(self, out_dir=None, out_fname_fun=None, nofig=False):
26
28
  """
27
29
  Constructor.
28
30
 
@@ -32,12 +34,15 @@ class Output:
32
34
  The output file directory
33
35
  out_fname_fun: Function, optional
34
36
  Modifies file names by f(fname)
37
+ nofig: bool
38
+ Do not show figures
35
39
 
36
40
  """
37
41
  self.out_dir = (
38
42
  get_output_path(out_dir) if out_dir is not None else config.output_dir
39
43
  )
40
44
  self.out_fname_fun = out_fname_fun
45
+ self.nofig = nofig
41
46
 
42
47
  if not self.out_dir.is_dir():
43
48
  print(f"{type(self).__name__}: Creating output dir {self.out_dir}")
@@ -46,7 +46,7 @@ class ResultsWriter(Output):
46
46
  self.data = data
47
47
  else:
48
48
  raise KeyError(
49
- f"ResultsWriter: Either give 'farm_results' or 'data' arguments"
49
+ "ResultsWriter: Either give 'farm_results' or 'data' arguments"
50
50
  )
51
51
 
52
52
  def _get_data_vars(self, variables):
foxes/output/rose_plot.py CHANGED
@@ -1,7 +1,6 @@
1
1
  import numpy as np
2
2
  import matplotlib.pyplot as plt
3
3
  from xarray import Dataset
4
- from matplotlib.cm import ScalarMappable
5
4
  from matplotlib.projections.polar import PolarAxes
6
5
  from matplotlib.lines import Line2D
7
6
 
@@ -58,7 +57,7 @@ class RosePlotOutput(Output):
58
57
  self.results = farm_results
59
58
  self._rtype = FC.TURBINE
60
59
  else:
61
- raise KeyError(f"Require either farm_results or point_results")
60
+ raise KeyError("Require either farm_results or point_results")
62
61
 
63
62
  @classmethod
64
63
  def get_data_info(cls, dname):
@@ -251,6 +250,9 @@ class RosePlotOutput(Output):
251
250
  The plot data
252
251
 
253
252
  """
253
+ if self.nofig:
254
+ return None
255
+
254
256
  data = self.get_data(wd_sectors, ws_var, ws_bins, wd_var, **kwargs)
255
257
 
256
258
  n_wsb = data.sizes[ws_var]
@@ -296,7 +298,8 @@ class RosePlotOutput(Output):
296
298
 
297
299
  llines = [Line2D([0], [0], color=c, lw=10) for c in np.flip(color_list, axis=0)]
298
300
  lleg = [
299
- f"[{ws_bins[i]:.1f}, {ws_bins[i+1]:.1f})" for i in range(n_wsb - 1, -1, -1)
301
+ f"[{ws_bins[i]:.1f}, {ws_bins[i + 1]:.1f})"
302
+ for i in range(n_wsb - 1, -1, -1)
300
303
  ]
301
304
  lpars = dict(
302
305
  loc="upper left",
@@ -337,6 +340,8 @@ class RosePlotOutput(Output):
337
340
  The wind rose data
338
341
 
339
342
  """
343
+ if self.nofig:
344
+ return None
340
345
 
341
346
  r = self.get_figure(*args, ret_data=ret_data, **kwargs)
342
347
  fpath = self.get_fpath(file_name)
@@ -560,6 +565,9 @@ class WindRoseBinPlot(Output):
560
565
  The axes object
561
566
 
562
567
  """
568
+ if self.nofig:
569
+ return None
570
+
563
571
  data = self.get_data(
564
572
  variable=variable,
565
573
  ws_bins=ws_bins,
@@ -625,6 +633,8 @@ class WindRoseBinPlot(Output):
625
633
  The wind rose data
626
634
 
627
635
  """
636
+ if self.nofig:
637
+ return None
628
638
 
629
639
  r = self.get_figure(*args, ret_data=ret_data, **kwargs)
630
640
  fpath = self.get_fpath(file_name)
@@ -77,6 +77,9 @@ class RotorPointPlot(Output):
77
77
  The plot axes
78
78
 
79
79
  """
80
+ if self.nofig:
81
+ return None
82
+
80
83
  if fig is None:
81
84
  fig = plt.figure(figsize=figsize)
82
85
  ax = fig.add_subplot(111)
@@ -1,2 +1,2 @@
1
- from .seq_flow_ani_plugin import SeqFlowAnimationPlugin
2
- from .seq_wake_debug_plugin import SeqWakeDebugPlugin
1
+ from .seq_flow_ani_plugin import SeqFlowAnimationPlugin as SeqFlowAnimationPlugin
2
+ from .seq_wake_debug_plugin import SeqWakeDebugPlugin as SeqWakeDebugPlugin
@@ -1,5 +1,3 @@
1
- from copy import deepcopy
2
-
3
1
  from foxes.algorithms.sequential import SequentialPlugin
4
2
 
5
3
  from ..flow_plots_2d.flow_plots import FlowPlots2D
@@ -116,7 +114,6 @@ class SeqFlowAnimationPlugin(SequentialPlugin):
116
114
  fig = ax.get_figure()
117
115
  gdata = None
118
116
  while len(self._data):
119
-
120
117
  fres, d = self._data.pop(0)
121
118
 
122
119
  if d[2] is not None:
@@ -109,7 +109,6 @@ class SeqWakeDebugPlugin(SequentialPlugin):
109
109
 
110
110
  """
111
111
  while len(self._data):
112
-
113
112
  dt, pts, v = self._data.pop(0)
114
113
 
115
114
  N = len(pts)
@@ -69,6 +69,9 @@ class StateTurbineMap(Output):
69
69
  The plot axis
70
70
 
71
71
  """
72
+ if self.nofig:
73
+ return None
74
+
72
75
  turbines = self.results[FC.TURBINE].to_numpy()
73
76
  states = self.results[FC.STATE].to_numpy()
74
77
 
@@ -1,4 +1,3 @@
1
- from tabnanny import verbose
2
1
  import matplotlib.pyplot as plt
3
2
  import numpy as np
4
3
  import pandas as pd
@@ -106,6 +105,9 @@ class TurbineTypeCurves(Output):
106
105
  The plot axes, one for each variable
107
106
 
108
107
  """
108
+ if self.nofig:
109
+ return None
110
+
109
111
  vars = [variables] if isinstance(variables, str) else variables
110
112
  if isinstance(titles, str):
111
113
  titles = [titles]
@@ -182,19 +184,19 @@ class TurbineTypeCurves(Output):
182
184
  t = f"{vv}, {turbine_type}" if titles[i] is None else titles[i]
183
185
  ax.set_title(t)
184
186
 
185
- l = "Wind speed [m/s]" if x_label is None else x_label
186
- ax.set_xlabel(l)
187
+ lb = "Wind speed [m/s]" if x_label is None else x_label
188
+ ax.set_xlabel(lb)
187
189
 
188
190
  if y_labels[i] is None:
189
191
  if v == FV.P:
190
- l = f"Power [kW]"
192
+ lb = "Power [kW]"
191
193
  elif v == FV.CT:
192
- l = "ct [-]"
194
+ lb = "ct [-]"
193
195
  else:
194
- l = v
196
+ lb = v
195
197
  else:
196
- l = y_labels[i]
197
- ax.set_ylabel(l)
198
+ lb = y_labels[i]
199
+ ax.set_ylabel(lb)
198
200
 
199
201
  ax.grid()
200
202
 
foxes/utils/__init__.py CHANGED
@@ -2,23 +2,41 @@
2
2
  General utilities.
3
3
  """
4
4
 
5
- from .wind_dir import wd2uv, wd2wdvec, wdvec2wd, uv2wd, delta_wd
6
- from .pandas_utils import PandasFileHelper
7
- from .xarray_utils import write_nc
8
- from .subclasses import all_subclasses, new_cls, new_instance
9
- from .dict import Dict
10
- from .factory import Factory, FDict, WakeKFactory
11
- from .data_book import DataBook
12
- from .cubic_roots import cubic_roots
13
- from .geopandas_utils import read_shp, shp2csv, read_shp_polygons, shp2geom2d
14
- from .load import import_module, load_module
15
- from .exec_python import exec_python
16
- from .regularize import sqrt_reg
17
- from .tab_files import read_tab_file
18
- from .random_xy import random_xy_square
19
- from .dev_utils import print_mem
20
- from .wrg_utils import ReaderWRG
5
+ from .wind_dir import wd2uv as wd2uv
6
+ from .wind_dir import wd2wdvec as wd2wdvec
7
+ from .wind_dir import wdvec2wd as wdvec2wd
8
+ from .wind_dir import uv2wd as uv2wd
9
+ from .wind_dir import delta_wd as delta_wd
21
10
 
22
- from . import two_circles
23
- from . import abl
24
- from . import geom2d
11
+ from .subclasses import all_subclasses as all_subclasses
12
+ from .subclasses import new_cls as new_cls
13
+ from .subclasses import new_instance as new_instance
14
+
15
+ from .factory import Factory as Factory
16
+ from .factory import FDict as FDict
17
+ from .factory import WakeKFactory as WakeKFactory
18
+
19
+ from .geopandas_utils import read_shp as read_shp
20
+ from .geopandas_utils import shp2csv as shp2csv
21
+ from .geopandas_utils import read_shp_polygons as read_shp_polygons
22
+ from .geopandas_utils import shp2geom2d as shp2geom2d
23
+
24
+ from .load import import_module as import_module
25
+ from .load import load_module as load_module
26
+
27
+ from .pandas_utils import PandasFileHelper as PandasFileHelper
28
+ from .xarray_utils import write_nc as write_nc
29
+ from .dict import Dict as Dict
30
+ from .data_book import DataBook as DataBook
31
+ from .cubic_roots import cubic_roots as cubic_roots
32
+ from .exec_python import exec_python as exec_python
33
+ from .regularize import sqrt_reg as sqrt_reg
34
+ from .tab_files import read_tab_file as read_tab_file
35
+ from .random_xy import random_xy_square as random_xy_square
36
+ from .dev_utils import print_mem as print_mem
37
+ from .wrg_utils import ReaderWRG as ReaderWRG
38
+ from .weibull import weibull_weights as weibull_weights
39
+
40
+ from . import two_circles as two_circles
41
+ from . import abl as abl
42
+ from . import geom2d as geom2d
@@ -2,7 +2,7 @@
2
2
  Atmospheric boundary layer functions.
3
3
  """
4
4
 
5
- from . import neutral
6
- from . import stable
7
- from . import unstable
8
- from . import sheared
5
+ from . import neutral as neutral
6
+ from . import stable as stable
7
+ from . import unstable as unstable
8
+ from . import sheared as sheared
@@ -104,7 +104,7 @@ def test_cubic_roots(roots, a0, a1, a2, a3=None, tol=1.0e-12):
104
104
  c2 = a2[n]
105
105
  c3 = a3[n]
106
106
 
107
- print(f"Polynomial {n}: a = {(c0,c1,c2,c3)}")
107
+ print(f"Polynomial {n}: a = {(c0, c1, c2, c3)}")
108
108
 
109
109
  rts = np.unique(roots[n])
110
110
  rts = rts[~np.isnan(rts)]
foxes/utils/data_book.py CHANGED
@@ -66,9 +66,10 @@ class DataBook:
66
66
  except AttributeError:
67
67
  contents = list(resources.contents(package))
68
68
 
69
- check_f = lambda f: any(
70
- [len(f) > len(s) and f[-len(s) :] == s for s in file_sfx]
71
- )
69
+ def check_f(f):
70
+ """little helper function to check file endings"""
71
+ return any([len(f) > len(s) and f[-len(s) :] == s for s in file_sfx])
72
+
72
73
  contents = [f for f in contents if check_f(f)]
73
74
 
74
75
  try: