dicube 0.1.4__cp311-cp311-macosx_11_0_arm64.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.
@@ -0,0 +1,271 @@
1
+ Metadata-Version: 2.2
2
+ Name: dicube
3
+ Version: 0.1.4
4
+ Summary: Medical Image Storage Library with DICOM compatibility
5
+ Author: Fangzhou Liao
6
+ License: MIT
7
+ Classifier: Development Status :: 4 - Beta
8
+ Classifier: Intended Audience :: Healthcare Industry
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Project-URL: Homepage, https://github.com/fastdiag-toolbox/dicube
21
+ Project-URL: Bug Reports, https://github.com/fastdiag-toolbox/dicube/issues
22
+ Project-URL: Source, https://github.com/fastdiag-toolbox/dicube
23
+ Requires-Python: >=3.8
24
+ Requires-Dist: numpy>=1.21.0
25
+ Requires-Dist: pydicom>=2.3.0
26
+ Requires-Dist: zstandard>=0.18.0
27
+ Requires-Dist: spacetransformer-core>=0.1.0
28
+ Provides-Extra: jph
29
+ Requires-Dist: pybind11>=2.10.0; extra == "jph"
30
+ Provides-Extra: nifti
31
+ Requires-Dist: nibabel>=3.2.0; extra == "nifti"
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
34
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
35
+ Requires-Dist: black>=22.0.0; extra == "dev"
36
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
37
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
38
+ Requires-Dist: build>=0.8.0; extra == "dev"
39
+ Requires-Dist: pylibjpeg>=2.0; extra == "dev"
40
+ Requires-Dist: pylibjpeg-openjpeg>=2.0; extra == "dev"
41
+ Provides-Extra: all
42
+ Requires-Dist: pybind11>=2.10.0; extra == "all"
43
+ Requires-Dist: nibabel>=3.2.0; extra == "all"
44
+ Description-Content-Type: text/markdown
45
+
46
+ # DiCube: Medical Image Storage Library
47
+
48
+ DiCube is a Python library for efficient storage and processing of 3D medical images with complete DICOM metadata preservation. It provides a high-compression, single-file format that combines DICOM compatibility with modern compression techniques.
49
+
50
+ ## Overview
51
+
52
+ DiCube was extracted from the larger DICOMCube project to focus specifically on medical image storage. It works alongside:
53
+ - **spacetransformer**: For 3D spatial transformations and coordinate systems
54
+ - **medmask**: For medical image segmentation mask processing
55
+
56
+ ## Why DiCube?
57
+
58
+ Although the DICOM standard is indispensable for clinical interoperability, it was never designed for today’s high-volume, AI-driven workflows. In practice it exposes four chronic pain-points:
59
+
60
+ 1. **Fragmented storage → slow I/O** A single CT/MR study can contain hundreds of small `.dcm` files. Traversing the file system and parsing each header one-by-one wastes precious milliseconds that quickly add up when training deep-learning models/ building realtime application.
61
+ 2. **Redundant metadata** Every slice repeats identical patient/study/series tags, inflating storage size and network traffic with no benefit.
62
+ 3. **Too many transfer syntaxes** Vendors ship proprietary or rarely-used encodings; no open-source decoder reliably supports *all* of them, so pipelines break on edge-cases.
63
+
64
+ DiCube mitigates these issues by:
65
+
66
+ * **Single-file design** All slices, metadata and spatial information are consolidated into one `.dcbs` file, eliminating filesystem overhead.
67
+ * **Deduplicated metadata** A compact JSON schema separates *shared* and *per-slice* tags, then compresses them with Zstandard.
68
+ * **Conservative codec policy** Only codecs that pass extensive performance and stability tests are adopted. Currently `.dcbs` uses HTJ2K for fast, lossless compression. Archive (`.dcba`) and lossy (`.dcbl`) variants are planned but not yet released. This package is a self-contained lib, users do not need to install codecs independently.
69
+ * **Round-trip safety** Every DiCube file can always be converted back to standard DICOM, preserving full clinical fidelity.
70
+
71
+ > In typical benchmarks DiCube cuts CT series load time from ~150 ms (PyDICOM) to <40 ms and shrinks storage by up to **3×**, all while remaining 100 % DICOM-compatible.
72
+
73
+ ## Architecture
74
+
75
+ ### Core Modules
76
+
77
+ ```
78
+ dicube/
79
+ ├── core/ # Core data structures
80
+ │ ├── image.py # DicomCubeImage (main interface)
81
+ | ├── io.py # DicomCubeImageIO (from and to many file formats)
82
+ │ └── pixel_header.py # PixelDataHeader (image metadata)
83
+ ├── storage/ # File storage formats
84
+ │ ├── dcb_file.py # DCB file format implementations
85
+ │ └── pixel_utils.py # Pixel processing utilities
86
+ ├── dicom/ # DICOM functionality
87
+ │ ├── dicom_meta.py # DicomMeta (metadata container)
88
+ │ ├── dicom_status.py # DICOM consistency checking
89
+ │ ├── dicom_tags.py # DICOM tag definitions
90
+ │ ├── dicom_io.py # DICOM file I/O
91
+ │ └── merge_utils.py # Metadata merging utilities
92
+ ├── codecs/ # Compression codecs
93
+ │ └── jph/ # HTJ2K codec (dcbs format)
94
+ └── exceptions.py # Custom exceptions
95
+ ```
96
+
97
+ ## File Formats
98
+
99
+ DiCube defines three file format specifications for different use cases:
100
+
101
+ ### .dcbs (Speed format) - **Currently Implemented**
102
+ - **Magic**: `DCMCUBES`
103
+ - **Target**: I/O speed suitable for deep learning training while high compression ratio.
104
+ - **Codec**: High Throughput JPEG 2000 (HTJ2K)
105
+ - **Use case**: High-speed encoding/decoding for processing pipelines
106
+ - **Features**: Optimized for throughput, lossless compression
107
+
108
+ ### .dcba (Archive format) - **Placeholder**
109
+ - **Magic**: `DCMCUBEA`
110
+ - **Target**: 20% better compression ratio than dcbs
111
+ - **Use case**: Long-term storage and archiving
112
+ - **Status**: Awaiting suitable codec that meets compression targets
113
+
114
+ ### .dcbl (Lossy format) - **Placeholder**
115
+ - **Magic**: `DCMCUBEL`
116
+ - **Target**: 60%+ compression ratio with imperceptible quality loss
117
+ - **Use case**: High-compression scenarios where minor quality trade-offs are acceptable
118
+ - **Status**: Awaiting suitable codec that meets quality/compression targets
119
+
120
+ > **Codec Selection Philosophy**: We take a conservative approach to codec adoption, requiring extensive testing and clear performance benefits before implementation. This avoids the complexity issues seen in DICOM's numerous format variations.
121
+
122
+ ## Key Classes and Interfaces
123
+
124
+ ### DicomCubeImage
125
+ Main interface for medical image handling:
126
+
127
+ ```python
128
+ import dicube
129
+
130
+ # Create from DICOM directory
131
+ image = dicube.load_from_dicom_folder('path/to/dicom/')
132
+
133
+ # Create from NIfTI file
134
+ image = dicube.load_from_nifti('image.nii.gz')
135
+
136
+ # Save to compressed format (currently only dcbs is implemented)
137
+ dicube.save(image, 'output.dcbs', file_type='s') # HTJ2K (Speed format)
138
+
139
+ # Load from file
140
+ loaded_image = dicube.load('output.dcbs')
141
+
142
+ # Export back to DICOM
143
+ dicube.save_to_dicom_folder(image, 'output_dicom/')
144
+
145
+ # Get pixel data
146
+ pixel_data = image.get_fdata() # Returns float array
147
+ raw_data = image.raw_image # Returns original dtype
148
+ ```
149
+
150
+ ### DicomMeta
151
+ DICOM metadata container with efficient shared/non-shared value handling:
152
+
153
+ ```python
154
+ from dicube import DicomMeta, read_dicom_dir
155
+
156
+ # Read DICOM directory
157
+ meta = read_dicom_dir('dicom_folder/')
158
+
159
+ # Access shared values (same across all slices)
160
+ patient_name = meta.get('PatientName') # Returns single value
161
+
162
+ # Access non-shared values (different per slice)
163
+ positions = meta.get('ImagePositionPatient') # Returns list
164
+
165
+ # Check status
166
+ from dicube import get_dicom_status
167
+ status = get_dicom_status(meta)
168
+ ```
169
+
170
+
171
+
172
+ ## Integration with spacetransformer
173
+
174
+ DiCube uses `spacetransformer.Space` for 3D coordinate system handling:
175
+
176
+ ```python
177
+ from spacetransformer import Space, warp_image
178
+
179
+ # DicomCubeImage automatically creates Space from DICOM
180
+ image = dicube.load_from_dicom_folder('dicom/')
181
+ space = image.space # spacetransformer.Space object
182
+
183
+ # Apply spatial transformations
184
+ space2 = space.apply_flip(axis=2)
185
+ space2 = space2.apply_rotate(axis=0, angle=90, unit='degree')
186
+
187
+ # Update image with new space
188
+ image2 = warp_image(image, space, space2)
189
+ ```
190
+
191
+ ## DICOM Status Checking
192
+
193
+ DiCube provides comprehensive DICOM consistency checking:
194
+
195
+ ```python
196
+ from dicube import DicomStatus, get_dicom_status
197
+
198
+ status = get_dicom_status(meta)
199
+
200
+ # Possible status values:
201
+ # DicomStatus.CONSISTENT - All checks pass
202
+ # DicomStatus.MISSING_SERIES_UID - No series UID
203
+ # DicomStatus.DUPLICATE_INSTANCE_NUMBERS - Non-unique instance numbers
204
+ # DicomStatus.NON_UNIFORM_SPACING - Inconsistent pixel spacing
205
+ # DicomStatus.GAP_LOCATION - Missing slices in Z direction
206
+ # ... and more
207
+ ```
208
+
209
+ ## Compression Codecs
210
+
211
+ ### HTJ2K (jph/)
212
+ - **Status**: Currently implemented for .dcbs format
213
+ - **Files**: `_encode.py`, `_decode.py`, pybind11 bindings
214
+ - **Functions**: `imencode_jph()`, `imdecode_jph()`
215
+ - **Build**: Uses pybind11 for C++ bindings to OpenJPH library
216
+ - **Performance**: Optimized for high-speed encoding/decoding
217
+
218
+ ## Best Practices
219
+
220
+ ### For Medical Images
221
+ 1. Always preserve DICOM metadata when possible
222
+ 2. Currently use `.dcbs` format for all storage needs (fast HTJ2K)
223
+ 3. Check DICOM status before processing: `get_dicom_status(meta)`
224
+ 4. Monitor for updates as `.dcba` and `.dcbl` formats become available
225
+
226
+ ### For Integration
227
+ 1. Use spacetransformer for all spatial operations
228
+ 2. Use medmask for segmentation mask processing
229
+ 3. Convert coordinates between voxel and world space using `Space` transforms
230
+ 4. Validate file format compatibility with `dicube.load()`
231
+
232
+ ### Performance Tips
233
+ 1. Use `num_threads` parameter for parallel compression
234
+ 2. For large datasets, process in chunks to manage memory
235
+ 3. Check DicomStatus before processing to avoid corrupted data
236
+ 4. Use HTJ2K's high-speed capabilities for processing pipelines
237
+
238
+ ## Error Handling
239
+
240
+ ```python
241
+ from dicube.exceptions import (
242
+ DicomCubeError,
243
+ InvalidCubeFileError,
244
+ CodecError,
245
+ MetaDataError,
246
+ DataConsistencyError
247
+ )
248
+
249
+ try:
250
+ image = dicube.load('corrupted.dcbs')
251
+ except InvalidCubeFileError:
252
+ print("Not a valid DiCube file")
253
+ except CodecError:
254
+ print("Compression/decompression failed")
255
+ except MetaDataError:
256
+ print("Missing or invalid metadata")
257
+ ```
258
+
259
+ ## Dependencies
260
+
261
+ ### Required
262
+ - numpy: Array operations
263
+ - pydicom: DICOM file handling
264
+ - spacetransformer: Spatial transformations
265
+ - zstandard: Metadata compression
266
+
267
+ ### Optional (for full functionality)
268
+ - OpenJPH library: For .dcbs format implementation
269
+ - nibabel: For NIfTI file support
270
+
271
+
@@ -0,0 +1,33 @@
1
+ dicube/__init__.py,sha256=QRyaQXqrzwSo8utXhGsbToE_lCEsjlzdzwFwVHINS8I,4189
2
+ dicube/exceptions.py,sha256=YrwBD93oWI4yhvFfO-SOPCNMQ4z_1FSVL2gCVSnx-LU,6689
3
+ dicube/validation.py,sha256=Edmx3yKhRShdzvM7uRK6N9j58GNV8rUv_k9w43JcaMs,12478
4
+ dicube/codecs/__init__.py,sha256=NNus-iAv4JXsNH1kALf5vnLYnESFBoYaN72yJ7kQoqk,3754
5
+ dicube/codecs/jph/ojph_complete.cpython-39-darwin.so,sha256=VIPp4NMamuf3zbUMsgHadBm0Y7Sl2nRLm9tzwkdgGRs,432048
6
+ dicube/codecs/jph/__init__.py,sha256=wLwzqAHCKT_7CdNrcEUtM2AyfvYgPJOj9nsm5CC_3F0,392
7
+ dicube/codecs/jph/ojph_complete.cpython-38-darwin.so,sha256=Bv7L0i6T1u8AUa7uKHpxCfp6HGX_2eyLEpmSB59pLgY,431872
8
+ dicube/codecs/jph/ojph_complete.cpython-310-darwin.so,sha256=XYpfkPuUinxZbE2T6jvrA1Jv0wBzpuJ9fiEy0ha-N_s,432048
9
+ dicube/codecs/jph/ojph_decode_complete.cpython-38-darwin.so,sha256=HHzNB5C3xZ0yhBA_tnzvAHlRdxZ7SBzbwbgjRWvNQ_g,448712
10
+ dicube/codecs/jph/ojph_decode_complete.cpython-310-darwin.so,sha256=QGryn2an05KfDHa9-WDSp5Z1MbZFNTO0WEiWxLGEyUY,448968
11
+ dicube/codecs/jph/ojph_complete.cpython-311-darwin.so,sha256=SmXvkyjn1iCLHfLcmavDWakNC5qE_P4dkMqlNu4dJBc,432144
12
+ dicube/codecs/jph/ojph_decode_complete.cpython-311-darwin.so,sha256=1aXbLZWb6nDX4e2S73dcWW8BnMUytk5AtWIzyxt4aiM,449096
13
+ dicube/codecs/jph/ojph_decode_complete.cpython-39-darwin.so,sha256=OMAfYyAQra6xF_Zv5Y-LGBkg68MYpTK4qwB8lWqlf6U,448968
14
+ dicube/codecs/jph/codec.py,sha256=d4bAoVAatSrWiC1k7gQLzWODZZTGo_1xeRRXO0NAtqo,5460
15
+ dicube/core/io.py,sha256=9Wg9dmVCnZpXQH5fKiS152sKDyy4vOO7ChYpgRL-vzE,13763
16
+ dicube/core/__init__.py,sha256=tU9vaPHbTkF8V78T8D6werr0nC7k6bMPIlatEIEdHU4,656
17
+ dicube/core/pixel_header.py,sha256=M-zu5hFG0BWj0chWgxyGFAQP7oH7r-1iN44acKOLm7k,3929
18
+ dicube/core/image.py,sha256=5XafyshOQbife6M8_G3vmrensjc1jTjyeUkAfAOCKiI,14182
19
+ dicube/utils/__init__.py,sha256=m3pYJfuk4hISVes_cfG2eDjTyGF-y40xbxV07IOjbi0,149
20
+ dicube/storage/__init__.py,sha256=q36sJqdI9acURBXjOW_g3QiyHw0XLGFCukMsQ-qioZc,465
21
+ dicube/storage/dcb_file.py,sha256=Gsb_LXHAm7DqAdrh4Kgo0rrj1mUuz7sY6tVt8HiKXyI,30379
22
+ dicube/storage/pixel_utils.py,sha256=thyYO-YNtWEvg1ROPLC-zPWqa37O0vJ8e26h3aF6dXM,5136
23
+ dicube/dicom/dcb_streaming.py,sha256=6HUmk5QEdg8WhkaiiUDjdX8yMwQxABjmaXaDjxwQuQU,9042
24
+ dicube/dicom/dicom_meta.py,sha256=Iv-kEcV39vhK2qgSqGpqDhgg28RuUm8ddzSdpToIVPc,26813
25
+ dicube/dicom/dicom_io.py,sha256=P-arcQu-CUB0Uf5daLku_Wf-3D3NpY3PiWHaosoe3dA,4941
26
+ dicube/dicom/dicom_status.py,sha256=NXi-sj3mhyaFGfpechewTjhI201vziVsyfLotsLr3Fs,10117
27
+ dicube/dicom/__init__.py,sha256=9b7liSXx5vlpEYAr59GZGkcUw16kULELTX5SlLfcXPw,371
28
+ dicube/dicom/merge_utils.py,sha256=6flzoK_6gzpvv4WSTaWq4SjVdr1gh3gtUPMsRfKDSNM,9312
29
+ dicube/dicom/space_from_meta.py,sha256=__B7UTmvgV1N-LMJg9O_ObHgNWa39mbRF4ZSkQXm3Vs,2420
30
+ dicube/dicom/dicom_tags.py,sha256=sOjrK9SoAhGqynF0e3YH70j8wbtvwGRezV-tM0wp40Q,3945
31
+ dicube-0.1.4.dist-info/RECORD,,
32
+ dicube-0.1.4.dist-info/WHEEL,sha256=11XKa4Dev4vCpAj_5tDGngF8FY4Lo7Z3Hr9WVz5BJMc,114
33
+ dicube-0.1.4.dist-info/METADATA,sha256=lLPPqXaJcIOIHhGuU3buJPhmi3GCMeKi5KW0FhlY0nk,10581
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: scikit-build-core 0.11.5
3
+ Root-Is-Purelib: false
4
+ Tag: cp311-cp311-macosx_11_0_arm64
5
+