holobench 1.3.4__tar.gz → 1.3.5__tar.gz

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.
Files changed (75) hide show
  1. {holobench-1.3.4 → holobench-1.3.5}/PKG-INFO +1 -2
  2. {holobench-1.3.4 → holobench-1.3.5}/bencher/__init__.py +1 -1
  3. {holobench-1.3.4 → holobench-1.3.5}/bencher/bench_cfg.py +8 -1
  4. {holobench-1.3.4 → holobench-1.3.5}/bencher/bencher.py +19 -7
  5. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_video.py +40 -14
  6. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/bench_result.py +3 -6
  7. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/bench_result_base.py +6 -2
  8. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/holoview_result.py +65 -8
  9. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/optuna_result.py +22 -0
  10. {holobench-1.3.4 → holobench-1.3.5}/bencher/utils.py +17 -0
  11. {holobench-1.3.4 → holobench-1.3.5}/bencher/variables/inputs.py +1 -1
  12. holobench-1.3.5/bencher/video_writer.py +30 -0
  13. {holobench-1.3.4 → holobench-1.3.5}/pyproject.toml +1 -2
  14. holobench-1.3.4/bencher/video_writer.py +0 -17
  15. {holobench-1.3.4 → holobench-1.3.5}/README.md +0 -0
  16. {holobench-1.3.4 → holobench-1.3.5}/bencher/bench_plot_server.py +0 -0
  17. {holobench-1.3.4 → holobench-1.3.5}/bencher/bench_report.py +0 -0
  18. {holobench-1.3.4 → holobench-1.3.5}/bencher/bench_runner.py +0 -0
  19. {holobench-1.3.4 → holobench-1.3.5}/bencher/caching.py +0 -0
  20. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/__init__.py +0 -0
  21. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/benchmark_data.py +0 -0
  22. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_all.py +0 -0
  23. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_categorical.py +0 -0
  24. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_custom_sweep.py +0 -0
  25. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_docs.py +0 -0
  26. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_float3D.py +0 -0
  27. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_float_cat.py +0 -0
  28. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_floats.py +0 -0
  29. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_floats2D.py +0 -0
  30. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_holosweep.py +0 -0
  31. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_holosweep_objects.py +0 -0
  32. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_holosweep_tap.py +0 -0
  33. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_image.py +0 -0
  34. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_levels.py +0 -0
  35. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_pareto.py +0 -0
  36. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_sample_cache.py +0 -0
  37. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_sample_cache_context.py +0 -0
  38. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_simple.py +0 -0
  39. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_simple_bool.py +0 -0
  40. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_simple_cat.py +0 -0
  41. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_simple_float.py +0 -0
  42. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_strings.py +0 -0
  43. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_time_event.py +0 -0
  44. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/example_workflow.py +0 -0
  45. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_bokeh_plotly.py +0 -0
  46. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_hover_ex.py +0 -0
  47. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_hvplot_explorer.py +0 -0
  48. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_interactive.py +0 -0
  49. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_streamnd.py +0 -0
  50. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_streams.py +0 -0
  51. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_template.py +0 -0
  52. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_updates.py +0 -0
  53. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/experimental/example_vector.py +0 -0
  54. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/meta/example_meta.py +0 -0
  55. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/meta/example_meta_cat.py +0 -0
  56. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/meta/example_meta_float.py +0 -0
  57. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/meta/example_meta_levels.py +0 -0
  58. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/optuna/example_optuna.py +0 -0
  59. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/shelved/example_float2D_scatter.py +0 -0
  60. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/shelved/example_float3D_cone.py +0 -0
  61. {holobench-1.3.4 → holobench-1.3.5}/bencher/example/shelved/example_kwargs.py +0 -0
  62. {holobench-1.3.4 → holobench-1.3.5}/bencher/job.py +0 -0
  63. {holobench-1.3.4 → holobench-1.3.5}/bencher/optuna_conversions.py +0 -0
  64. {holobench-1.3.4 → holobench-1.3.5}/bencher/plotting/__init__.py +0 -0
  65. {holobench-1.3.4 → holobench-1.3.5}/bencher/plotting/plot_filter.py +0 -0
  66. {holobench-1.3.4 → holobench-1.3.5}/bencher/plotting/plt_cnt_cfg.py +0 -0
  67. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/__init__.py +0 -0
  68. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/float_formatter.py +0 -0
  69. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/panel_result.py +0 -0
  70. {holobench-1.3.4 → holobench-1.3.5}/bencher/results/plotly_result.py +0 -0
  71. {holobench-1.3.4 → holobench-1.3.5}/bencher/variables/parametrised_sweep.py +0 -0
  72. {holobench-1.3.4 → holobench-1.3.5}/bencher/variables/results.py +0 -0
  73. {holobench-1.3.4 → holobench-1.3.5}/bencher/variables/sweep_base.py +0 -0
  74. {holobench-1.3.4 → holobench-1.3.5}/bencher/variables/time.py +0 -0
  75. {holobench-1.3.4 → holobench-1.3.5}/bencher/worker_job.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: holobench
3
- Version: 1.3.4
3
+ Version: 1.3.5
4
4
  Summary: A package for benchmarking the performance of arbitrary functions
5
5
  Author-email: Austin Gregg-Smith <blooop@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -21,7 +21,6 @@ Requires-Dist: strenum>=0.4.0,<=0.4.15
21
21
  Requires-Dist: scikit-learn>=1.2,<=1.3.2
22
22
  Requires-Dist: str2bool>=1.1,<=1.1
23
23
  Requires-Dist: scoop>=0.7.0,<=0.7.2.0
24
- Requires-Dist: ffmpeg-downloader>=0.3.0,<=0.3.0
25
24
  Requires-Dist: moviepy>=1.0.3,<=1.0.3
26
25
  Requires-Dist: black>=23,<=23.12.1 ; extra == "test"
27
26
  Requires-Dist: pylint>=2.16,<=3.0.3 ; extra == "test"
@@ -38,4 +38,4 @@ from .results.panel_result import PanelResult
38
38
  from .results.holoview_result import ReduceType, HoloviewResult
39
39
  from .bench_report import BenchReport
40
40
  from .job import Executors
41
- from .video_writer import VideoWriter
41
+ from .video_writer import VideoWriter, add_image
@@ -164,7 +164,14 @@ class BenchRunCfg(BenchPlotSrvCfg):
164
164
  doc="The function can be run serially or in parallel with different futures executors",
165
165
  )
166
166
 
167
- plot_size = param.Integer(default=None)
167
+ plot_size = param.Integer(default=None, doc="Sets the width and height of the plot")
168
+ plot_width = param.Integer(
169
+ default=None,
170
+ doc="Sets with width of the plots, this will ovverride the plot_size parameter",
171
+ )
172
+ plot_height = param.Integer(
173
+ default=None, doc="Sets the height of the plot, this will ovverride the plot_size parameter"
174
+ )
168
175
 
169
176
  @staticmethod
170
177
  def from_cmd_line() -> BenchRunCfg: # pragma: no cover
@@ -200,7 +200,7 @@ class Bench(BenchPlotServer):
200
200
  run_cfg: BenchRunCfg = None,
201
201
  plot: bool = False,
202
202
  ) -> BenchResult:
203
- title = "Sweeping " + " vs ".join([i.name for i in input_vars])
203
+ title = "Sweeping " + " vs ".join([self.get_name(i) for i in input_vars])
204
204
  return self.plot_sweep(
205
205
  title,
206
206
  input_vars=input_vars,
@@ -217,6 +217,7 @@ class Bench(BenchPlotServer):
217
217
 
218
218
  def sweep_sequential(
219
219
  self,
220
+ title="",
220
221
  input_vars: List[ParametrizedSweep] = None,
221
222
  result_vars: List[ParametrizedSweep] = None,
222
223
  const_vars: List[ParametrizedSweep] = None,
@@ -231,12 +232,14 @@ class Bench(BenchPlotServer):
231
232
  relationship_cb = combinations
232
233
  for it in range(iterations):
233
234
  for input_group in relationship_cb(input_vars, group_size):
234
- title = "Sweeping " + " vs ".join([i.name for i in input_vars])
235
+ title_gen = (
236
+ title + "Sweeping " + " vs ".join([self.get_name(i) for i in input_group])
237
+ )
235
238
  if iterations > 1:
236
- title += f" iteration:{it}"
239
+ title_gen += f" iteration:{it}"
237
240
  res = self.plot_sweep(
238
- title=title,
239
- input_vars=input_group,
241
+ title=title_gen,
242
+ input_vars=list(input_group),
240
243
  result_vars=result_vars,
241
244
  const_vars=const_vars,
242
245
  run_cfg=run_cfg,
@@ -313,6 +316,10 @@ class Bench(BenchPlotServer):
313
316
  input_vars[i] = self.convert_vars_to_params(input_vars[i], "input")
314
317
  for i in range(len(result_vars)):
315
318
  result_vars[i] = self.convert_vars_to_params(result_vars[i], "result")
319
+
320
+ if isinstance(const_vars, dict):
321
+ const_vars = list(const_vars.items())
322
+
316
323
  for i in range(len(const_vars)):
317
324
  # consts come as tuple pairs
318
325
  cv_list = list(const_vars[i])
@@ -338,8 +345,8 @@ class Bench(BenchPlotServer):
338
345
  elif len(const_vars) > 0:
339
346
  title = "Constant Value"
340
347
  if len(const_vars) > 1:
341
- title += "es"
342
- title += ": " + " ".join([f"{c[0].name}={c[1]}" for c in const_vars])
348
+ title += "s"
349
+ title += ": " + ", ".join([f"{c[0].name}={c[1]}" for c in const_vars])
343
350
  else:
344
351
  raise RuntimeError("you must pass a title, or define inputs or consts")
345
352
 
@@ -444,6 +451,11 @@ class Bench(BenchPlotServer):
444
451
  self.results.append(bench_res)
445
452
  return bench_res
446
453
 
454
+ def get_name(self, var):
455
+ if isinstance(var, param.Parameter):
456
+ return var.name
457
+ return var
458
+
447
459
  def convert_vars_to_params(self, variable: param.Parameter, var_type: str):
448
460
  """check that a variable is a subclass of param
449
461
 
@@ -1,7 +1,7 @@
1
1
  import bencher as bch
2
2
  import numpy as np
3
3
  import matplotlib.pyplot as plt
4
- from matplotlib.animation import ArtistAnimation
4
+ import panel as pn
5
5
 
6
6
 
7
7
  # code from https://ipython-books.github.io/124-simulating-a-partial-differential-equation-reaction-diffusion-systems-and-turing-patterns/
@@ -11,11 +11,12 @@ class TuringPattern(bch.ParametrizedSweep):
11
11
  tau = bch.FloatSweep(default=0.1, bounds=(0.01, 0.5))
12
12
  k = bch.FloatSweep(default=-0.005, bounds=(-0.01, 0.01))
13
13
 
14
- size = bch.IntSweep(default=50, bounds=(30, 200), doc="size of the 2D grid")
14
+ size = bch.IntSweep(default=30, bounds=(30, 200), doc="size of the 2D grid")
15
15
  time = bch.FloatSweep(default=20.0, bounds=(1, 100), doc="total time of simulation")
16
16
  dt = bch.FloatSweep(default=0.001, doc="simulation time step")
17
17
 
18
18
  video = bch.ResultVideo()
19
+ score = bch.ResultVar()
19
20
 
20
21
  def laplacian(self, Z, dx):
21
22
  Ztop = Z[0:-2, 1:-1]
@@ -57,20 +58,18 @@ class TuringPattern(bch.ParametrizedSweep):
57
58
  fig, ax = plt.subplots(frameon=False, figsize=(2, 2))
58
59
  fig.set_tight_layout(True)
59
60
  ax.set_axis_off()
60
-
61
- artists = []
62
-
61
+ vid_writer = bch.VideoWriter()
63
62
  for i in range(n):
64
63
  self.update(U, V, dx)
65
64
  if i % 500 == 0:
66
- artists.append([ax.imshow(U)])
67
-
68
- ani = ArtistAnimation(fig=fig, artists=artists, interval=60, blit=True)
69
- path = bch.gen_video_path("turing", ".mp4")
70
- # path = self.gen_path("turing", "vid", ".gif")
71
- print(f"saving {len(artists)} frames")
72
- ani.save(path)
73
- self.video = path
65
+ ax.imshow(U)
66
+ fig.canvas.draw()
67
+ rgb = np.array(fig.canvas.renderer.buffer_rgba())
68
+ vid_writer.append(rgb)
69
+
70
+ self.video = vid_writer.write()
71
+
72
+ self.score = self.alpha + self.beta
74
73
  return super().__call__()
75
74
 
76
75
 
@@ -91,8 +90,35 @@ def example_video(
91
90
  return bench
92
91
 
93
92
 
93
+ def example_video_tap(
94
+ run_cfg: bch.BenchRunCfg = bch.BenchRunCfg(), report: bch.BenchReport = bch.BenchReport()
95
+ ) -> bch.Bench: # pragma: no cover
96
+ tp = TuringPattern()
97
+
98
+ run_cfg.use_sample_cache = False
99
+ # run_cfg.use_optuna = True
100
+ run_cfg.auto_plot = False
101
+ run_cfg.run_tag = "3"
102
+ bench = tp.to_bench(run_cfg=run_cfg, report=report)
103
+
104
+ res = bench.plot_sweep(
105
+ "phase",
106
+ input_vars=["alpha", "beta"],
107
+ # result_vars=["video","score"],
108
+ run_cfg=run_cfg,
109
+ )
110
+
111
+ bench.report.append(res.describe_sweep())
112
+ bench.report.append(
113
+ res.to_heatmap(tp.param.score, tap_var=tp.param.video, tap_container=pn.pane.Video)
114
+ )
115
+
116
+ return bench
117
+
118
+
94
119
  if __name__ == "__main__":
95
120
  run_cfg_ex = bch.BenchRunCfg()
96
121
  run_cfg_ex.level = 2
97
122
 
98
- example_video(run_cfg_ex).report.show()
123
+ # example_video(run_cfg_ex).report.show()
124
+ example_video_tap(run_cfg_ex).report.show()
@@ -47,6 +47,8 @@ class BenchResult(PlotlyResult, HoloviewResult):
47
47
  for p in remove_plots:
48
48
  plot_list.remove(p)
49
49
 
50
+ kwargs = self.set_plot_size(**kwargs)
51
+
50
52
  row = EmptyContainer(pn.Row())
51
53
  for plot_callback in plot_list:
52
54
  if self.plt_cnt_cfg.print_debug:
@@ -61,9 +63,6 @@ class BenchResult(PlotlyResult, HoloviewResult):
61
63
  )
62
64
  return row.pane
63
65
 
64
- def to_auto_da(self):
65
- pass
66
-
67
66
  def to_auto_plots(self, **kwargs) -> List[pn.panel]:
68
67
  """Given the dataset result of a benchmark run, automatically dedeuce how to plot the data based on the types of variables that were sampled
69
68
 
@@ -73,9 +72,7 @@ class BenchResult(PlotlyResult, HoloviewResult):
73
72
  Returns:
74
73
  pn.pane: A panel containing plot results
75
74
  """
76
- if self.bench_cfg.plot_size is not None:
77
- kwargs["width"] = self.bench_cfg.plot_size
78
- kwargs["height"] = self.bench_cfg.plot_size
75
+
79
76
  plot_cols = pn.Column()
80
77
  plot_cols.append(self.to_sweep_summary(name="Plots View"))
81
78
  plot_cols.append(self.to_auto(**kwargs))
@@ -5,7 +5,7 @@ import xarray as xr
5
5
  from param import Parameter
6
6
  import holoviews as hv
7
7
  from functools import partial
8
- from bencher.utils import int_to_col, color_tuple_to_css
8
+ from bencher.utils import int_to_col, color_tuple_to_css, callable_name
9
9
 
10
10
  from bencher.variables.parametrised_sweep import ParametrizedSweep
11
11
  from bencher.variables.results import OptDir
@@ -241,6 +241,8 @@ class BenchResultBase(OptunaResult):
241
241
  if hv_dataset is None:
242
242
  hv_dataset = self.to_hv_dataset()
243
243
  row = EmptyContainer(pn.Row())
244
+
245
+ # kwargs= self.set_plot_size(**kwargs)
244
246
  for rv in self.get_results_var_list(result_var):
245
247
  if result_types is None or isinstance(rv, result_types):
246
248
  row.append(
@@ -279,7 +281,7 @@ class BenchResultBase(OptunaResult):
279
281
  repeats_range=repeats_range,
280
282
  input_range=input_range,
281
283
  )
282
- matches_res = plot_filter.matches_result(self.plt_cnt_cfg, plot_callback.__name__)
284
+ matches_res = plot_filter.matches_result(self.plt_cnt_cfg, callable_name(plot_callback))
283
285
  if matches_res.overall:
284
286
  return self.map_plot_panes(
285
287
  plot_callback=plot_callback,
@@ -300,6 +302,8 @@ class BenchResultBase(OptunaResult):
300
302
  **kwargs,
301
303
  ):
302
304
  dims = len(hv_dataset.dimensions())
305
+ if target_dimension is None:
306
+ target_dimension = dims
303
307
  return self._to_panes_da(
304
308
  hv_dataset.data,
305
309
  plot_callback=plot_callback,
@@ -8,7 +8,7 @@ from functools import partial
8
8
  import hvplot.xarray # noqa pylint: disable=duplicate-code,unused-import
9
9
  import xarray as xr
10
10
 
11
- from bencher.utils import hmap_canonical_input, get_nearest_coords
11
+ from bencher.utils import hmap_canonical_input, get_nearest_coords, get_nearest_coords1D
12
12
  from bencher.results.panel_result import PanelResult
13
13
  from bencher.results.bench_result_base import ReduceType
14
14
 
@@ -173,13 +173,27 @@ class HoloviewResult(PanelResult):
173
173
  return pt.opts(legend_position="right").overlay()
174
174
  return pt.opts(legend_position="right")
175
175
 
176
- def to_heatmap(self, result_var: Parameter = None, **kwargs) -> Optional[pn.panel]:
176
+ def to_heatmap(
177
+ self,
178
+ result_var: Parameter = None,
179
+ tap_var=None,
180
+ tap_container=None,
181
+ target_dimension=2,
182
+ **kwargs,
183
+ ) -> Optional[pn.panel]:
184
+ if tap_var is None:
185
+ heatmap_cb = self.to_heatmap_ds
186
+ else:
187
+ heatmap_cb = partial(
188
+ self.to_heatmap_container_tap_ds, result_var_plot=tap_var, container=tap_container
189
+ )
190
+
177
191
  return self.filter(
178
- self.to_heatmap_ds,
192
+ heatmap_cb,
179
193
  float_range=VarRange(2, None),
180
194
  cat_range=VarRange(0, None),
181
195
  input_range=VarRange(1, None),
182
- target_dimension=2,
196
+ target_dimension=target_dimension,
183
197
  result_var=result_var,
184
198
  result_types=(ResultVar),
185
199
  **kwargs,
@@ -189,9 +203,6 @@ class HoloviewResult(PanelResult):
189
203
  self, dataset: xr.Dataset, result_var: Parameter, **kwargs
190
204
  ) -> Optional[hv.HeatMap]:
191
205
  if len(dataset.dims) >= 2:
192
- # dims = [d for d in da.sizes]
193
- # x = dims[0]
194
- # y = dims[1]
195
206
  x = self.plt_cnt_cfg.float_vars[0].name
196
207
  y = self.plt_cnt_cfg.float_vars[1].name
197
208
  C = result_var.name
@@ -200,6 +211,50 @@ class HoloviewResult(PanelResult):
200
211
  return dataset.hvplot.heatmap(x=x, y=y, C=C, cmap="plasma", **time_args, **kwargs)
201
212
  return None
202
213
 
214
+ def to_heatmap_container_tap_ds(
215
+ self,
216
+ dataset: xr.Dataset,
217
+ result_var: Parameter,
218
+ result_var_plot: Parameter,
219
+ container: pn.pane.panel = pn.pane.panel,
220
+ **kwargs,
221
+ ) -> pn.Row:
222
+ htmap = self.to_heatmap_ds(dataset, result_var).opts(tools=["hover", "tap"], **kwargs)
223
+ htmap_posxy = hv.streams.Tap(source=htmap, x=0, y=0)
224
+
225
+ container_instance = container(**kwargs)
226
+ title = pn.pane.Markdown("Selected: None")
227
+
228
+ def tap_plot(x, y): # pragma: no cover
229
+ x_nearest = get_nearest_coords1D(
230
+ x, dataset.coords[self.bench_cfg.input_vars[0].name].data
231
+ )
232
+ y_nearest = get_nearest_coords1D(
233
+ y, dataset.coords[self.bench_cfg.input_vars[1].name].data
234
+ )
235
+ kdims = {}
236
+ kdims[self.bench_cfg.input_vars[0].name] = x_nearest
237
+ kdims[self.bench_cfg.input_vars[1].name] = y_nearest
238
+
239
+ if hasattr(htmap, "current_key"):
240
+ for d, k in zip(htmap.kdims, htmap.current_key):
241
+ kdims[d.name] = k
242
+
243
+ ds = dataset[result_var_plot.name]
244
+ val = ds.sel(**kdims)
245
+ item = self.zero_dim_da_to_val(val)
246
+ title.object = "Selected: " + ", ".join([f"{k}:{v}" for k, v in kdims.items()])
247
+ container_instance.object = item
248
+ if hasattr(container, "autoplay"): # container is a video, set to autoplay
249
+ container_instance.paused = False
250
+ container_instance.time = 0
251
+ container_instance.loop = True
252
+ container_instance.autoplay = True
253
+
254
+ htmap_posxy.add_subscriber(tap_plot)
255
+ bound_plot = pn.Column(title, container_instance)
256
+ return pn.Row(htmap, bound_plot)
257
+
203
258
  def to_error_bar(self) -> hv.Bars:
204
259
  return self.to_hv_dataset(ReduceType.REDUCE).to(hv.ErrorBars)
205
260
 
@@ -312,7 +367,9 @@ class HoloviewResult(PanelResult):
312
367
  # return matches.to_panel()
313
368
 
314
369
  def to_scatter_jitter(
315
- self, result_var: Parameter = None, **kwargs # pylint: disable=unused-argument
370
+ self,
371
+ result_var: Parameter = None,
372
+ **kwargs, # pylint: disable=unused-argument
316
373
  ) -> List[hv.Scatter]:
317
374
  return self.overlay_plots(partial(self.to_scatter_jitter_single, **kwargs))
318
375
 
@@ -1,5 +1,7 @@
1
1
  from __future__ import annotations
2
2
  from typing import List
3
+ from copy import deepcopy
4
+
3
5
  import numpy as np
4
6
  import optuna
5
7
  import panel as pn
@@ -330,3 +332,23 @@ class OptunaResult:
330
332
  # for it, rv in enumerate(bench_cfg.result_vars):
331
333
  # bench_cfg.ds[rv.name].loc[t.params] = t.values[it]
332
334
  # return bench_cfg
335
+
336
+ def deep(self) -> OptunaResult: # pragma: no cover
337
+ """Return a deep copy of these results"""
338
+ return deepcopy(self)
339
+
340
+ def set_plot_size(self, **kwargs) -> dict:
341
+ if "width" not in kwargs:
342
+ if self.bench_cfg.plot_size is not None:
343
+ kwargs["width"] = self.bench_cfg.plot_size
344
+ # specific width overrrides general size
345
+ if self.bench_cfg.plot_width is not None:
346
+ kwargs["width"] = self.bench_cfg.plot_width
347
+
348
+ if "height" not in kwargs:
349
+ if self.bench_cfg.plot_size is not None:
350
+ kwargs["height"] = self.bench_cfg.plot_size
351
+ # specific height overrrides general size
352
+ if self.bench_cfg.plot_height is not None:
353
+ kwargs["height"] = self.bench_cfg.plot_height
354
+ return kwargs
@@ -7,6 +7,8 @@ import math
7
7
  from colorsys import hsv_to_rgb
8
8
  from pathlib import Path
9
9
  from uuid import uuid4
10
+ from functools import partial
11
+ from typing import Callable, Any
10
12
 
11
13
 
12
14
  def hmap_canonical_input(dic: dict) -> tuple:
@@ -55,6 +57,12 @@ def get_nearest_coords(dataset: xr.Dataset, collapse_list=False, **kwargs) -> di
55
57
  return cd2
56
58
 
57
59
 
60
+ def get_nearest_coords1D(val: Any, coords) -> Any:
61
+ if isinstance(val, (int, float)):
62
+ return min(coords, key=lambda x_: abs(x_ - val))
63
+ return val
64
+
65
+
58
66
  def hash_sha1(var: any) -> str:
59
67
  """A hash function that avoids the PYTHONHASHSEED 'feature' which returns a different hash value each time the program is run"""
60
68
  return hashlib.sha1(str(var).encode("ASCII")).hexdigest()
@@ -129,3 +137,12 @@ def gen_video_path(video_name: str, extension: str = ".webm") -> str:
129
137
 
130
138
  def gen_image_path(image_name: str, filetype=".png") -> str:
131
139
  return gen_path(image_name, "img", filetype)
140
+
141
+
142
+ def callable_name(any_callable: Callable[..., Any]) -> str:
143
+ if isinstance(any_callable, partial):
144
+ return any_callable.func.__name__
145
+ try:
146
+ return any_callable.__name__
147
+ except AttributeError:
148
+ return str(any_callable)
@@ -72,7 +72,7 @@ class EnumSweep(SweepSelector):
72
72
  __slots__ = shared_slots
73
73
 
74
74
  def __init__(
75
- self, enum_type: Enum | List[Enum], units="", samples=None, samples_debug=2, **params
75
+ self, enum_type: Enum | List[Enum], units=" ", samples=None, samples_debug=2, **params
76
76
  ):
77
77
  # The enum can either be an Enum type or a list of enums
78
78
  list_of_enums = isinstance(enum_type, list)
@@ -0,0 +1,30 @@
1
+ from bencher import gen_video_path, gen_image_path
2
+ from PIL import Image
3
+ import numpy as np
4
+
5
+
6
+ class VideoWriter:
7
+ def __init__(self, filename: str = "vid") -> None:
8
+ self.images = []
9
+ self.filename = gen_video_path(filename)
10
+
11
+ def append(self, img):
12
+ self.images.append(img)
13
+
14
+ def write(self, bitrate: int = 1500) -> str:
15
+ import moviepy.video.io.ImageSequenceClip
16
+
17
+ # todo
18
+ # if len(self.images[0.shape) == 2:
19
+ # for i in range(len(self.images)):
20
+ # self.images[i] = np.expand_dims(self.images[i], 2)
21
+
22
+ clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(self.images, fps=30)
23
+ clip.write_videofile(self.filename, bitrate=f"{bitrate}k", logger=None)
24
+ return self.filename
25
+
26
+
27
+ def add_image(np_array: np.ndarray, name: str = "img"):
28
+ filename = gen_image_path(name)
29
+ Image.fromarray(np_array).save(filename)
30
+ return filename
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "holobench"
3
- version = "1.3.4"
3
+ version = "1.3.5"
4
4
 
5
5
  authors = [{ name = "Austin Gregg-Smith", email = "blooop@gmail.com" }]
6
6
  description = "A package for benchmarking the performance of arbitrary functions"
@@ -26,7 +26,6 @@ dependencies = [
26
26
  "scikit-learn>=1.2,<=1.3.2",
27
27
  "str2bool>=1.1,<=1.1",
28
28
  "scoop>=0.7.0,<=0.7.2.0",
29
- "ffmpeg-downloader>=0.3.0,<=0.3.0",
30
29
  "moviepy>=1.0.3,<=1.0.3",
31
30
  ]
32
31
 
@@ -1,17 +0,0 @@
1
- from bencher import gen_video_path
2
-
3
-
4
- class VideoWriter:
5
- def __init__(self, filename: str) -> None:
6
- self.images = []
7
- self.filename = gen_video_path(filename)
8
-
9
- def append(self, img):
10
- self.images.append(img)
11
-
12
- def write(self, bitrate: int = 1500) -> str:
13
- import moviepy.video.io.ImageSequenceClip
14
-
15
- clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(self.images, fps=30)
16
- clip.write_videofile(self.filename, bitrate=f"{bitrate}k")
17
- return self.filename
File without changes
File without changes
File without changes