figpack 0.3.2__tar.gz → 0.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.
- {figpack-0.3.2/figpack.egg-info → figpack-0.3.5}/PKG-INFO +2 -2
- {figpack-0.3.2 → figpack-0.3.5}/README.md +1 -1
- {figpack-0.3.2 → figpack-0.3.5}/figpack/__init__.py +1 -1
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_bundle_utils.py +11 -3
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_save_figure.py +17 -3
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_show_view.py +5 -2
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_view_figure.py +1 -3
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/figpack_view.py +14 -4
- figpack-0.3.5/figpack/core/zarr.py +129 -0
- figpack-0.3.5/figpack/figpack-figure-dist/assets/index-P3Ni9vtI.js +394 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/figpack-figure-dist/index.html +1 -1
- figpack-0.3.5/figpack/utils/__init__.py +24 -0
- {figpack-0.3.2 → figpack-0.3.5/figpack.egg-info}/PKG-INFO +2 -2
- {figpack-0.3.2 → figpack-0.3.5}/figpack.egg-info/SOURCES.txt +2 -1
- {figpack-0.3.2 → figpack-0.3.5}/pyproject.toml +1 -1
- figpack-0.3.2/figpack/core/zarr.py +0 -61
- figpack-0.3.2/figpack/figpack-figure-dist/assets/index-ST_DU17U.js +0 -95
- {figpack-0.3.2 → figpack-0.3.5}/LICENSE +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/MANIFEST.in +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/cli.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/__init__.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_file_handler.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_server_manager.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_upload_bundle.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/_zarr_consolidate.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/config.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/extension_view.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/core/figpack_extension.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/extensions.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/figpack-figure-dist/assets/index-V5m_wCvw.css +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/figpack-figure-dist/assets/neurosift-logo-CLsuwLMO.png +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/Box.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/CaptionedView.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/DataFrame.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/Gallery.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/GalleryItem.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/Iframe.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/Image.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/LayoutItem.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/Markdown.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/MatplotlibFigure.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/MountainLayout.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/MountainLayoutItem.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/MultiChannelTimeseries.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/PlotlyExtension/PlotlyExtension.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/PlotlyExtension/__init__.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/PlotlyExtension/_plotly_extension.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/PlotlyExtension/plotly_view.js +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/Spectrogram.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/Splitter.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/TabLayout.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/TabLayoutItem.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/TimeseriesGraph.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack/views/__init__.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack-serve/worker/container/app.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack.egg-info/dependency_links.txt +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack.egg-info/entry_points.txt +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack.egg-info/requires.txt +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/figpack.egg-info/top_level.txt +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/setup.cfg +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_box.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_cli.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_core.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_dataframe.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_extension_system.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_figpack_view.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_file_handler.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_gallery.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_image.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_markdown.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_matplotlib_figure.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_multichannel_timeseries.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_plotly_figure.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_server_manager.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_spectrogram.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_splitter.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_tablayout.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_timeseries_graph.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_upload_bundle.py +0 -0
- {figpack-0.3.2 → figpack-0.3.5}/tests/test_view_figure.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: figpack
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: A Python package for creating shareable, interactive visualizations in the browser
|
|
5
5
|
Author-email: Jeremy Magland <jmagland@flatironinstitute.org>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -133,7 +133,7 @@ If you use figpack in your research, please cite it:
|
|
|
133
133
|
|
|
134
134
|
Or in APA format:
|
|
135
135
|
|
|
136
|
-
> Magland, J. (2025). figpack (Version 0.3.
|
|
136
|
+
> Magland, J. (2025). figpack (Version 0.3.5) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.17419621
|
|
137
137
|
|
|
138
138
|
## Contributing
|
|
139
139
|
|
|
@@ -57,7 +57,7 @@ If you use figpack in your research, please cite it:
|
|
|
57
57
|
|
|
58
58
|
Or in APA format:
|
|
59
59
|
|
|
60
|
-
> Magland, J. (2025). figpack (Version 0.3.
|
|
60
|
+
> Magland, J. (2025). figpack (Version 0.3.5) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.17419621
|
|
61
61
|
|
|
62
62
|
## Contributing
|
|
63
63
|
|
|
@@ -15,7 +15,12 @@ thisdir = pathlib.Path(__file__).parent.resolve()
|
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def prepare_figure_bundle(
|
|
18
|
-
view: FigpackView,
|
|
18
|
+
view: FigpackView,
|
|
19
|
+
tmpdir: str,
|
|
20
|
+
*,
|
|
21
|
+
title: str,
|
|
22
|
+
description: Optional[str] = None,
|
|
23
|
+
script: Optional[str] = None,
|
|
19
24
|
) -> None:
|
|
20
25
|
"""
|
|
21
26
|
Prepare a figure bundle in the specified temporary directory.
|
|
@@ -31,6 +36,7 @@ def prepare_figure_bundle(
|
|
|
31
36
|
tmpdir: The temporary directory to prepare the bundle in
|
|
32
37
|
title: Title for the figure (required)
|
|
33
38
|
description: Optional description for the figure (markdown supported)
|
|
39
|
+
script: Optional script text used to generate the figure
|
|
34
40
|
"""
|
|
35
41
|
html_dir = thisdir / ".." / "figpack-figure-dist"
|
|
36
42
|
if not os.path.exists(html_dir):
|
|
@@ -61,10 +67,12 @@ def prepare_figure_bundle(
|
|
|
61
67
|
zarr_group = Group(zarr_group)
|
|
62
68
|
view.write_to_zarr_group(zarr_group)
|
|
63
69
|
|
|
64
|
-
# Add title and description as attributes on the top-level zarr group
|
|
70
|
+
# Add title and description and script as attributes on the top-level zarr group
|
|
65
71
|
zarr_group.attrs["title"] = title
|
|
66
|
-
if description
|
|
72
|
+
if description:
|
|
67
73
|
zarr_group.attrs["description"] = description
|
|
74
|
+
if script:
|
|
75
|
+
zarr_group.attrs["script"] = script
|
|
68
76
|
|
|
69
77
|
# Discover and write extension JavaScript files
|
|
70
78
|
required_extensions = _discover_required_extensions(view)
|
|
@@ -6,7 +6,12 @@ from .figpack_view import FigpackView
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def _save_figure(
|
|
9
|
-
view: FigpackView,
|
|
9
|
+
view: FigpackView,
|
|
10
|
+
output_path: str,
|
|
11
|
+
*,
|
|
12
|
+
title: str,
|
|
13
|
+
description: str = "",
|
|
14
|
+
script: str = "",
|
|
10
15
|
) -> None:
|
|
11
16
|
"""
|
|
12
17
|
Save the figure to a folder or a .tar.gz file
|
|
@@ -14,6 +19,9 @@ def _save_figure(
|
|
|
14
19
|
Args:
|
|
15
20
|
view: FigpackView instance to save
|
|
16
21
|
output_path: Output path (destination folder or .tar.gz file path)
|
|
22
|
+
title: Title for the figure
|
|
23
|
+
description: Description text with markdown support
|
|
24
|
+
script: Optional script text used to generate the figure
|
|
17
25
|
"""
|
|
18
26
|
output_path_2 = pathlib.Path(output_path)
|
|
19
27
|
if (output_path_2.suffix == ".gz" and output_path_2.suffixes[-2] == ".tar") or (
|
|
@@ -21,7 +29,9 @@ def _save_figure(
|
|
|
21
29
|
):
|
|
22
30
|
# It's a .tar.gz file
|
|
23
31
|
with tempfile.TemporaryDirectory(prefix="figpack_save_") as tmpdir:
|
|
24
|
-
prepare_figure_bundle(
|
|
32
|
+
prepare_figure_bundle(
|
|
33
|
+
view, tmpdir, title=title, description=description, script=script
|
|
34
|
+
)
|
|
25
35
|
# Create tar.gz file
|
|
26
36
|
import tarfile
|
|
27
37
|
|
|
@@ -31,5 +41,9 @@ def _save_figure(
|
|
|
31
41
|
# It's a folder
|
|
32
42
|
output_path_2.mkdir(parents=True, exist_ok=True)
|
|
33
43
|
prepare_figure_bundle(
|
|
34
|
-
view,
|
|
44
|
+
view,
|
|
45
|
+
str(output_path_2),
|
|
46
|
+
title=title,
|
|
47
|
+
description=description,
|
|
48
|
+
script=script,
|
|
35
49
|
)
|
|
@@ -91,6 +91,7 @@ def _show_view(
|
|
|
91
91
|
ephemeral: bool,
|
|
92
92
|
title: str,
|
|
93
93
|
description: Union[str, None],
|
|
94
|
+
script: Union[str, None],
|
|
94
95
|
inline: bool,
|
|
95
96
|
inline_height: int,
|
|
96
97
|
wait_for_input: bool,
|
|
@@ -99,7 +100,9 @@ def _show_view(
|
|
|
99
100
|
if upload:
|
|
100
101
|
# Upload behavior: create temporary directory for this upload only
|
|
101
102
|
with tempfile.TemporaryDirectory(prefix="figpack_upload_") as tmpdir:
|
|
102
|
-
prepare_figure_bundle(
|
|
103
|
+
prepare_figure_bundle(
|
|
104
|
+
view, tmpdir, title=title, description=description, script=script
|
|
105
|
+
)
|
|
103
106
|
|
|
104
107
|
# Check for API key - required for regular uploads, optional for ephemeral
|
|
105
108
|
api_key = os.environ.get("FIGPACK_API_KEY")
|
|
@@ -143,7 +146,7 @@ def _show_view(
|
|
|
143
146
|
|
|
144
147
|
# Prepare the figure bundle in the subdirectory
|
|
145
148
|
prepare_figure_bundle(
|
|
146
|
-
view, str(figure_dir), title=title, description=description
|
|
149
|
+
view, str(figure_dir), title=title, description=description, script=script
|
|
147
150
|
)
|
|
148
151
|
|
|
149
152
|
# Start or get existing server
|
|
@@ -131,9 +131,7 @@ def view_figure(figure_path: str, port: Union[int, None] = None) -> None:
|
|
|
131
131
|
)
|
|
132
132
|
return
|
|
133
133
|
|
|
134
|
-
if not
|
|
135
|
-
figure_pathlib
|
|
136
|
-
).endswith(".tar.gz"):
|
|
134
|
+
if not figure_path.endswith(".tar.gz") and not figure_path.endswith(".tgz"):
|
|
137
135
|
print(f"Error: Archive file must be a .tar.gz file: {figure_path}")
|
|
138
136
|
sys.exit(1)
|
|
139
137
|
|
|
@@ -20,6 +20,7 @@ class FigpackView:
|
|
|
20
20
|
*,
|
|
21
21
|
title: str,
|
|
22
22
|
description: Optional[str] = None,
|
|
23
|
+
script: Optional[str] = None,
|
|
23
24
|
port: Optional[int] = None,
|
|
24
25
|
open_in_browser: Optional[bool] = None,
|
|
25
26
|
upload: Optional[bool] = None,
|
|
@@ -29,7 +30,7 @@ class FigpackView:
|
|
|
29
30
|
allow_origin: Optional[str] = None,
|
|
30
31
|
wait_for_input: Optional[bool] = None,
|
|
31
32
|
_dev: Optional[bool] = None,
|
|
32
|
-
)
|
|
33
|
+
):
|
|
33
34
|
"""
|
|
34
35
|
Display a figpack view component with intelligent environment detection and flexible display options.
|
|
35
36
|
See https://flatironinstitute.github.io/figpack/show_function.html for complete documentation.
|
|
@@ -41,6 +42,7 @@ class FigpackView:
|
|
|
41
42
|
Args:
|
|
42
43
|
title: Title for browser tab and figure (required)
|
|
43
44
|
description: Description text with markdown support (optional)
|
|
45
|
+
script: Optional script text used to generate the figure
|
|
44
46
|
port: Local server port, random if None
|
|
45
47
|
open_in_browser: Auto-open in browser, auto-detects by environment
|
|
46
48
|
upload: Upload figure to figpack servers, auto-detects by environment
|
|
@@ -161,7 +163,7 @@ class FigpackView:
|
|
|
161
163
|
)
|
|
162
164
|
print("")
|
|
163
165
|
|
|
164
|
-
_show_view(
|
|
166
|
+
return _show_view(
|
|
165
167
|
self,
|
|
166
168
|
port=port,
|
|
167
169
|
open_in_browser=open_in_browser,
|
|
@@ -170,21 +172,29 @@ class FigpackView:
|
|
|
170
172
|
ephemeral=ephemeral,
|
|
171
173
|
title=title,
|
|
172
174
|
description=description,
|
|
175
|
+
script=script,
|
|
173
176
|
inline=inline,
|
|
174
177
|
inline_height=inline_height,
|
|
175
178
|
wait_for_input=wait_for_input,
|
|
176
179
|
_local_figure_name=_local_figure_name if _dev else None,
|
|
177
180
|
)
|
|
178
181
|
|
|
179
|
-
def save(
|
|
182
|
+
def save(
|
|
183
|
+
self, output_path: str, *, title: str, description: str = "", script: str = ""
|
|
184
|
+
) -> None:
|
|
180
185
|
"""
|
|
181
186
|
Save as figure either to a folder or to a .tar.gz file
|
|
182
187
|
Args:
|
|
183
188
|
output_path: Output path (destination folder or .tar.gz file path)
|
|
189
|
+
title: Title for the figure
|
|
190
|
+
description: Description text with markdown support
|
|
191
|
+
script: Optional script text used to generate the figure
|
|
184
192
|
"""
|
|
185
193
|
from ._save_figure import _save_figure
|
|
186
194
|
|
|
187
|
-
_save_figure(
|
|
195
|
+
_save_figure(
|
|
196
|
+
self, output_path, title=title, description=description, script=script
|
|
197
|
+
)
|
|
188
198
|
|
|
189
199
|
def write_to_zarr_group(self, group: Group) -> None:
|
|
190
200
|
"""
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
from typing import Any, Dict
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
_UNSPECIFIED = object()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Group:
|
|
9
|
+
def __init__(self, zarr_group):
|
|
10
|
+
self._zarr_group = zarr_group
|
|
11
|
+
|
|
12
|
+
def create_group(self, name: str) -> "Group":
|
|
13
|
+
return Group(self._zarr_group.create_group(name))
|
|
14
|
+
|
|
15
|
+
def create_dataset(
|
|
16
|
+
self,
|
|
17
|
+
name: str,
|
|
18
|
+
*,
|
|
19
|
+
data=_UNSPECIFIED,
|
|
20
|
+
dtype=_UNSPECIFIED,
|
|
21
|
+
chunks=_UNSPECIFIED,
|
|
22
|
+
compressor=_UNSPECIFIED,
|
|
23
|
+
) -> None:
|
|
24
|
+
kwargs = {}
|
|
25
|
+
if data is not _UNSPECIFIED:
|
|
26
|
+
kwargs["data"] = data
|
|
27
|
+
if dtype is not _UNSPECIFIED:
|
|
28
|
+
kwargs["dtype"] = dtype
|
|
29
|
+
if chunks is not _UNSPECIFIED:
|
|
30
|
+
kwargs["chunks"] = chunks
|
|
31
|
+
else:
|
|
32
|
+
if data is not _UNSPECIFIED:
|
|
33
|
+
chunks2 = _get_optimal_chunk_size(data.shape, data.dtype)
|
|
34
|
+
if chunks2 is not _UNSPECIFIED:
|
|
35
|
+
kwargs["chunks"] = chunks2
|
|
36
|
+
if compressor is not _UNSPECIFIED:
|
|
37
|
+
kwargs["compressor"] = compressor
|
|
38
|
+
if _check_zarr_version() == 2:
|
|
39
|
+
self._zarr_group.create_dataset(name, **kwargs)
|
|
40
|
+
elif _check_zarr_version() == 3:
|
|
41
|
+
self._zarr_group.create_array(name, **kwargs) # type: ignore
|
|
42
|
+
else:
|
|
43
|
+
raise RuntimeError("Unsupported Zarr version")
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def attrs(self) -> Dict[str, Any]:
|
|
47
|
+
return self._zarr_group.attrs # type: ignore
|
|
48
|
+
|
|
49
|
+
def __getitem__(self, key: str) -> Any:
|
|
50
|
+
return self._zarr_group[key]
|
|
51
|
+
|
|
52
|
+
# implement in operator
|
|
53
|
+
def __contains__(self, key: str) -> bool:
|
|
54
|
+
return key in self._zarr_group
|
|
55
|
+
|
|
56
|
+
def __iter__(self):
|
|
57
|
+
return iter(self._zarr_group)
|
|
58
|
+
|
|
59
|
+
def __reversed__(self):
|
|
60
|
+
return reversed(self._zarr_group)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _check_zarr_version():
|
|
64
|
+
import zarr
|
|
65
|
+
|
|
66
|
+
version = zarr.__version__
|
|
67
|
+
major_version = int(version.split(".")[0])
|
|
68
|
+
return major_version
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _get_optimal_chunk_size(shape: tuple, dtype) -> tuple:
|
|
72
|
+
"""Compute an optimal chunk shape targeting ~5 MB per chunk,
|
|
73
|
+
chunking along only one dimension and avoiding mostly empty chunks.
|
|
74
|
+
"""
|
|
75
|
+
target_bytes = 5 * 1024 * 1024 # 5 MB
|
|
76
|
+
|
|
77
|
+
if np.prod(shape) <= 1:
|
|
78
|
+
# all dimensions are zero or one
|
|
79
|
+
# return shape of unspecified to let zarr choose on this edge case
|
|
80
|
+
return _UNSPECIFIED
|
|
81
|
+
|
|
82
|
+
# Ensure dtype is a numpy dtype to get itemsize
|
|
83
|
+
if isinstance(dtype, str):
|
|
84
|
+
dtype = np.dtype(dtype)
|
|
85
|
+
|
|
86
|
+
itemsize = np.dtype(dtype).itemsize
|
|
87
|
+
|
|
88
|
+
# Total array size in bytes
|
|
89
|
+
total_bytes = np.prod(shape) * itemsize
|
|
90
|
+
if total_bytes <= target_bytes:
|
|
91
|
+
# Entire array fits comfortably in one chunk
|
|
92
|
+
return shape
|
|
93
|
+
|
|
94
|
+
# Choose the first non-singleton dimension to chunk along
|
|
95
|
+
for axis, dim in enumerate(shape):
|
|
96
|
+
if dim > 1:
|
|
97
|
+
break
|
|
98
|
+
else:
|
|
99
|
+
return shape # all singleton
|
|
100
|
+
|
|
101
|
+
# Compute how many elements fit in target_bytes
|
|
102
|
+
target_elements = target_bytes // itemsize
|
|
103
|
+
|
|
104
|
+
# Compute product of all other dimensions (fixed)
|
|
105
|
+
other_size = np.prod(shape) // shape[axis]
|
|
106
|
+
|
|
107
|
+
# Determine chunk length along chosen axis
|
|
108
|
+
chunk_len = max(1, min(shape[axis], target_elements // other_size))
|
|
109
|
+
|
|
110
|
+
# Construct chunk shape
|
|
111
|
+
chunk_shape = list(shape)
|
|
112
|
+
chunk_shape[axis] = chunk_len
|
|
113
|
+
|
|
114
|
+
return tuple([int(c) for c in chunk_shape])
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
if __name__ == "__main__":
|
|
118
|
+
# Test the _get_optimal_chunk_size function for a variety of shapes and dtypes
|
|
119
|
+
test_cases = [
|
|
120
|
+
((1000, 1000), np.float32),
|
|
121
|
+
((5000, 2000), np.uint8),
|
|
122
|
+
((100, 100, 100), np.float64),
|
|
123
|
+
((10, 30, 30, 1500), np.int16),
|
|
124
|
+
((1, 1, 1), np.float32),
|
|
125
|
+
]
|
|
126
|
+
|
|
127
|
+
for shape, dtype in test_cases:
|
|
128
|
+
chunk_size = _get_optimal_chunk_size(shape, dtype)
|
|
129
|
+
print(f"Optimal chunk size for shape {shape} and dtype {dtype}: {chunk_size}")
|