radiuma-suv 0.0.0__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.
Potentially problematic release.
This version of radiuma-suv might be problematic. Click here for more details.
- radiuma_suv-0.0.0/LICENSE +21 -0
- radiuma_suv-0.0.0/LICENSE.txt +21 -0
- radiuma_suv-0.0.0/PKG-INFO +520 -0
- radiuma_suv-0.0.0/README.md +501 -0
- radiuma_suv-0.0.0/pyproject.toml +22 -0
- radiuma_suv-0.0.0/setup.cfg +4 -0
- radiuma_suv-0.0.0/src/radiuma_suv/__init__.py +11 -0
- radiuma_suv-0.0.0/src/radiuma_suv/core.py +1785 -0
- radiuma_suv-0.0.0/src/radiuma_suv.egg-info/PKG-INFO +520 -0
- radiuma_suv-0.0.0/src/radiuma_suv.egg-info/SOURCES.txt +12 -0
- radiuma_suv-0.0.0/src/radiuma_suv.egg-info/dependency_links.txt +1 -0
- radiuma_suv-0.0.0/src/radiuma_suv.egg-info/requires.txt +3 -0
- radiuma_suv-0.0.0/src/radiuma_suv.egg-info/top_level.txt +1 -0
- radiuma_suv-0.0.0/tests/test_import.py +89 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 CPSC210-2025S
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 CPSC210-2025S
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: radiuma-suv
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Python library for PET DICOM to SUVbw conversion
|
|
5
|
+
Author: Mohammad Salmanpour
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Classifier: Intended Audience :: Science/Research
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
|
|
10
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
11
|
+
Requires-Python: >=3.10
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
License-File: LICENSE.txt
|
|
15
|
+
Requires-Dist: numpy
|
|
16
|
+
Requires-Dist: pydicom
|
|
17
|
+
Requires-Dist: SimpleITK
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# Radiuma_SUV: PET to SUVbw Conversion β Python Script and Library
|
|
21
|
+
|
|
22
|
+

|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
**Radiuma_SUV** is the proposed library name for the PET-to-SUVbw conversion engine in `Radiuma_SUV.ipynb`. The code converts PET pixels to **body-weight-normalized standardized uptake values (SUVbw)** using DICOM acquisition and radiopharmaceutical metadata. It supports conventional single-frame PET, Enhanced multi-frame PET, NumPy arrays with matching DICOM metadata, and folders containing one or several PET series. In-memory results are floating-point arrays; DICOM results are newly written, calibrated derived images.
|
|
26
|
+
|
|
27
|
+
**Publication note:** The notebook itself does not create a package named `radiuma_suv`. This README assumes the conversion functions have been placed in an installable `radiuma_suv` Python package exposing `Radiuma_SUV`, `Radiuma_SUV_from_input`, and `RadiumaSUVLoader`. `pip install radiuma-suv` applies only after that package has actually been published under the distribution name `radiuma-suv`.
|
|
28
|
+
|
|
29
|
+
**Scientific caution:** `parameter_estimation="ON"` can fill missing metadata with notebook-configured values, including patient weight, radionuclide activity, timing, and other acquisition details. Those values must not be assumed correct for another patient. Prefer `"OFF"` with complete verified source DICOM metadata. No clinical validation is established by the notebook.
|
|
30
|
+
|
|
31
|
+
## π Table of Contents
|
|
32
|
+
|
|
33
|
+
- [π₯ YouTube Tutorials](#-youtube-tutorials)
|
|
34
|
+
- [π§© IBSI Standardization](#-ibsi-standardization)
|
|
35
|
+
- [β¨ Key Features](#-key-features)
|
|
36
|
+
- [π Library Usage](#-library-usage)
|
|
37
|
+
- [π Single File Processing](#-single-file-processing)
|
|
38
|
+
- [π§ In-Memory Array Processing](#-in-memory-array-processing)
|
|
39
|
+
- [β‘ Parallel Batch Processing](#-parallel-batch-processing)
|
|
40
|
+
- [π€ Deep Features Extraction](#-deep-features-extraction)
|
|
41
|
+
- [π§ Advanced Configuration](#-advanced-configuration)
|
|
42
|
+
- [π₯ Installation](#-installation)
|
|
43
|
+
- [π Data Structure Requirements](#-data-structure-requirements)
|
|
44
|
+
- [π Radiuma_SUV Parameters Reference](#-radiuma_suv-parameters-reference)
|
|
45
|
+
- [π Parameter Compatibility](#-parameter-compatibility)
|
|
46
|
+
- [π API Reference](#-api-reference)
|
|
47
|
+
- [π Output Structure](#-output-structure)
|
|
48
|
+
- [π Supported File Formats](#-supported-file-formats)
|
|
49
|
+
- [π― Library Examples](#-library-examples)
|
|
50
|
+
- [β‘ Performance Tips](#-performance-tips)
|
|
51
|
+
- [π» Integration of Radiuma_SUV to GUI](#-integration-of-radiuma_suv-to-gui)
|
|
52
|
+
- [β Troubleshooting](#-troubleshooting)
|
|
53
|
+
- [π Version History](#-version-history)
|
|
54
|
+
- [π¬ Contact](#-contact)
|
|
55
|
+
- [π₯ Authors](#-authors)
|
|
56
|
+
- [π Citation](#-citation)
|
|
57
|
+
- [π Acknowledgment](#-acknowledgment)
|
|
58
|
+
- [π License](#-license)
|
|
59
|
+
|
|
60
|
+
## π₯ YouTube Tutorials
|
|
61
|
+
|
|
62
|
+
No Radiuma_SUV-specific tutorial channel or videos are documented in `Radiuma_SUV.ipynb`. Add verified links here when available. The heading is retained to match the PySERA README section structure.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## π§© IBSI Standardization
|
|
66
|
+
|
|
67
|
+
The Radiuma_SUV performs PET intensity conversion based on IBSI radiomics feature extraction.
|
|
68
|
+
|
|
69
|
+
## β¨ Key Features
|
|
70
|
+
|
|
71
|
+
- **PET-to-SUVbw conversion** using PET image pixels and matching DICOM metadata.
|
|
72
|
+
- **Conventional PET DICOM**: single-frame PET images and conventional PET slice series.
|
|
73
|
+
- **Enhanced PET DICOM**: multi-frame images with functional group metadata.
|
|
74
|
+
- **NumPy arrays**: convert in memory using a corresponding DICOM metadata dictionary.
|
|
75
|
+
- **Hierarchical PET directories**: recursively identify PET DICOM groups and process independent series separately.
|
|
76
|
+
- **Type-preserving API**: NumPy input returns a NumPy array; DICOM input creates derived DICOM outputs.
|
|
77
|
+
- **Optional metadata completion**: `parameter_estimation="ON"` fills selected missing values using notebook settings.
|
|
78
|
+
- **Derived DICOM output**: new DICOM identifiers, calibrated signed 16-bit pixels, and output validation against computed SUVbw values.
|
|
79
|
+
- **Source protection**: output paths are checked to avoid overwriting original DICOM files.
|
|
80
|
+
- **Object-oriented convenience wrapper**: `RadiumaSUVLoader`.
|
|
81
|
+
|
|
82
|
+
These are implementation capabilities, not independent quantitative or clinical validation claims.
|
|
83
|
+
|
|
84
|
+
### π¦ Library Installation via pip
|
|
85
|
+
|
|
86
|
+
After publishing the intended package under the distribution name `radiuma-suv`:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
python -m pip install radiuma-suv
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For local development in the directory containing `pyproject.toml`:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
python -m pip install -e .
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## π Library Usage
|
|
99
|
+
|
|
100
|
+
### π Single File Processing
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from radiuma_suv import Radiuma_SUV_from_input
|
|
104
|
+
|
|
105
|
+
output_path, metadata = Radiuma_SUV_from_input(
|
|
106
|
+
image_input="pet_scan.dcm",
|
|
107
|
+
parameter_estimation="OFF",
|
|
108
|
+
output_path="pet_suvbw.dcm",
|
|
109
|
+
)
|
|
110
|
+
print(output_path)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Supported single-file DICOM inputs are conventional single-frame PET or Enhanced multi-frame PET. Non-Enhanced multi-frame PET files are explicitly rejected.
|
|
114
|
+
|
|
115
|
+
### π§ In-Memory Array Processing
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
import json
|
|
119
|
+
import numpy as np
|
|
120
|
+
from radiuma_suv import Radiuma_SUV
|
|
121
|
+
|
|
122
|
+
pet_pixels = np.load("pet_pixels.npy")
|
|
123
|
+
with open("pet_dicom_metadata.json", "r", encoding="utf-8") as file:
|
|
124
|
+
metadata = json.load(file)
|
|
125
|
+
|
|
126
|
+
suv_array, output_metadata = Radiuma_SUV(
|
|
127
|
+
input_array=pet_pixels,
|
|
128
|
+
input_metadata=metadata,
|
|
129
|
+
parameter_estimation="OFF",
|
|
130
|
+
)
|
|
131
|
+
np.save("pet_suvbw.npy", suv_array)
|
|
132
|
+
print(suv_array.shape)
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The JSON must be the actual metadata corresponding to the PET image, not an arbitrary placeholder. In-memory output is floating-point SUVbw without DICOM pixel quantization.
|
|
136
|
+
|
|
137
|
+
The convenience input API accepts the same representation:
|
|
138
|
+
|
|
139
|
+
```python
|
|
140
|
+
from radiuma_suv import Radiuma_SUV_from_input
|
|
141
|
+
suv, meta = Radiuma_SUV_from_input(
|
|
142
|
+
image_input=pet_pixels,
|
|
143
|
+
metadata_json=metadata,
|
|
144
|
+
parameter_estimation="OFF",
|
|
145
|
+
)
|
|
146
|
+
```
|
|
147
|
+
NumPy input cannot specify `output_path`; saving a `.npy` file is the caller's responsibility.
|
|
148
|
+
|
|
149
|
+
`parameter_estimation` controls metadata replacement:
|
|
150
|
+
|
|
151
|
+
| Option | Behavior |
|
|
152
|
+
|---|---|
|
|
153
|
+
| `"OFF"` | Does not fill missing parameters from the configured notebook defaults. |
|
|
154
|
+
| `"ON"` | Inserts eligible missing or invalid DICOM fields using configured values. |
|
|
155
|
+
|
|
156
|
+
The notebook has configurable values for patient weight, age, height, sex; administered dose, half-life and radiopharmaceutical timing; acquisition and series times; PET units; SUV type; decay correction; rescale slope and intercept; image geometry; and other fields. These settings are **not additional keyword arguments** of `Radiuma_SUV_from_input`.
|
|
157
|
+
|
|
158
|
+
The source implements unit conversion paths involving `BQML`, `GML`, `CM2ML`, and `CNTS`. Successful processing depends on the necessary metadata and calibration factors. The `BQML` converter handles `DecayCorrection` values `ADMIN`, `START`, and `NONE` with different reference-time logic. The source also includes body-composition helper functions used for certain `GML` SUV normalization variants.
|
|
159
|
+
|
|
160
|
+
**Never reuse the notebook's example patient or dose values for a different person.** Review any derived output in the original DICOM context.
|
|
161
|
+
|
|
162
|
+
## π₯ Installation
|
|
163
|
+
|
|
164
|
+
Dependencies imported by the notebook are `numpy`, `pydicom`, and `SimpleITK`; other referenced Python modules are standard-library modules. In the original notebook the installation line is `%pip install numpy pydicom SimpleITK`; for a published library, declare these in `pyproject.toml` instead.
|
|
165
|
+
|
|
166
|
+
### π GitHub Installation
|
|
167
|
+
|
|
168
|
+
https://git.talkfluent.ir/admin/Radiuma-SUV/src/branch/main
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
git clone https://github.com/YOUR_USERNAME/radiuma_suv.git
|
|
172
|
+
cd radiuma_suv
|
|
173
|
+
python -m pip install -e .
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### macOS/Linux Installation
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
python3 -m venv .venv
|
|
180
|
+
source .venv/bin/activate
|
|
181
|
+
python -m pip install --upgrade pip
|
|
182
|
+
python -m pip install -e .
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Windows Setup
|
|
186
|
+
|
|
187
|
+
In PowerShell inside the project directory:
|
|
188
|
+
|
|
189
|
+
```powershell
|
|
190
|
+
python -m venv .venv
|
|
191
|
+
.venv\Scripts\Activate.ps1
|
|
192
|
+
python -m pip install --upgrade pip
|
|
193
|
+
python -m pip install -e .
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### π» Python Script - Command Line Interface (CLI)
|
|
197
|
+
|
|
198
|
+
The notebook contains an example `if __name__ == "__main__":` block but **does not implement an argument-parsing CLI or a `radiuma_suv` terminal command**. Create a short Python script when you want command-line execution:
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
# convert_pet.py
|
|
202
|
+
from radiuma_suv import Radiuma_SUV_from_input
|
|
203
|
+
path, headers = Radiuma_SUV_from_input("pet_scan.dcm", parameter_estimation="OFF")
|
|
204
|
+
print(path)
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
python convert_pet.py
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### π¦ Library Installation via pip
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
python -m pip install radiuma-suv
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
This will install the intended project **only after it is actually published** under that name on PyPI.
|
|
218
|
+
|
|
219
|
+
## π Data Structure Requirements
|
|
220
|
+
|
|
221
|
+
The notebook processes PET DICOM input **without masks**. Examples of appropriate layouts:
|
|
222
|
+
|
|
223
|
+
**Single PET image:**
|
|
224
|
+
|
|
225
|
+
```text
|
|
226
|
+
PET/
|
|
227
|
+
βββ scan.dcm
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Conventional PET image series:**
|
|
231
|
+
|
|
232
|
+
```text
|
|
233
|
+
PET_Series/
|
|
234
|
+
βββ slice_001.dcm
|
|
235
|
+
βββ slice_002.dcm
|
|
236
|
+
βββ slice_003.dcm
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Hierarchical directory:**
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
Patients/
|
|
243
|
+
βββ patient_001/
|
|
244
|
+
β βββ PET/
|
|
245
|
+
β βββ slice_001.dcm
|
|
246
|
+
β βββ slice_002.dcm
|
|
247
|
+
βββ patient_002/
|
|
248
|
+
βββ PET/
|
|
249
|
+
βββ enhanced_pet.dcm
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The source searches directories recursively, reads DICOM headers, selects `Modality=PT`, and groups series by their `SeriesInstanceUID` and folder. A DICOM series spanning different source folders is rejected by the writer. The corresponding output folders preserve relative structure with `_processed` naming.
|
|
253
|
+
|
|
254
|
+
**Output must not be inside the source directory.** Existing destinations are not overwritten. Non-DICOM files may be skipped during directory discovery, but `.nii`, `.nii.gz`, `.nrrd`, and `.nhdr` are not valid Radiuma_SUV PET inputs. For NumPy, pass an in-memory `ndarray` and DICOM metadata; a `.npy` *path* is not accepted by `Radiuma_SUV_from_input`.
|
|
255
|
+
|
|
256
|
+
## π Radiuma_SUV Parameters Reference
|
|
257
|
+
|
|
258
|
+
### Public function parameters
|
|
259
|
+
|
|
260
|
+
| Parameter | Type | Default | Description |
|
|
261
|
+
|---|---|---|---|
|
|
262
|
+
| `input_array` | `numpy.ndarray` | Required | PET array passed to `Radiuma_SUV`. |
|
|
263
|
+
| `input_metadata` | `dict` | Required | Corresponding PET DICOM metadata dictionary. |
|
|
264
|
+
| `image_input` | `numpy.ndarray`, string, path-like | Required | NumPy array, PET DICOM file, or PET DICOM directory. |
|
|
265
|
+
| `metadata_json` | `dict` or `None` | `None` | Matching metadata for NumPy input; optional for DICOM input. |
|
|
266
|
+
| `parameter_estimation` | `str` | `"OFF"` | `"ON"` or `"OFF"` only. |
|
|
267
|
+
| `output_path` | string / path-like / `None` | `None` | Destination for DICOM outputs; not valid with NumPy input. |
|
|
268
|
+
| `pet_metadata` | `dict` or `None` | `None` | `RadiumaSUVLoader` metadata for a NumPy input. |
|
|
269
|
+
|
|
270
|
+
### Selected configured DICOM fields
|
|
271
|
+
|
|
272
|
+
These are **example literal settings present in the notebook**, not a universal dataset or recommended patient parameters.
|
|
273
|
+
|
|
274
|
+
| Metadata field | Notebook setting | Meaning |
|
|
275
|
+
|---|---|---|
|
|
276
|
+
| `PatientWeight` | `"75.5"` | Patient weight, kg |
|
|
277
|
+
| `PatientAge` | `"045Y"` | Age in DICOM AS format |
|
|
278
|
+
| `PatientSize` | `"1.75"` | Height, m |
|
|
279
|
+
| `PatientSex` | `"M"` | DICOM sex code |
|
|
280
|
+
| `RadionuclideTotalDose` | `"370000000"` | Radionuclide activity; representation-specific unit handling must be verified |
|
|
281
|
+
| `RadionuclideHalfLife` | `"6586.2"` | Half-life, s |
|
|
282
|
+
| `RadiopharmaceuticalStartDateTime` | `"20261010093015"` | Radiopharmaceutical administration start |
|
|
283
|
+
| `ActualFrameDuration` | `"180000"` | Frame duration, ms |
|
|
284
|
+
| `FrameReferenceTime` | `"90000"` | Frame reference time, ms |
|
|
285
|
+
| `AcquisitionDate` | `"20261010"` | DICOM DA |
|
|
286
|
+
| `AcquisitionTime` | `"100000"` | DICOM TM |
|
|
287
|
+
| `Units` | `"BQML"` | PET units |
|
|
288
|
+
| `SUVType` | `"BW"` | SUV normalization type |
|
|
289
|
+
| `DecayCorrection` | `"START"` | Decay reference |
|
|
290
|
+
| `RescaleSlope` | `"1.0"` | Pixel calibration slope |
|
|
291
|
+
| `RescaleIntercept` | `"0.0"` | Pixel calibration intercept |
|
|
292
|
+
| `Rows`, `Columns` | `256`, `256` | Example image size |
|
|
293
|
+
| `PixelSpacing` | `[4.0, 4.0]` | Row/column spacing, mm |
|
|
294
|
+
| `SliceThickness` | `"3.0"` | Slice thickness, mm |
|
|
295
|
+
| `ImagePositionPatient` | `[0.0, 0.0, 0.0]` | Image coordinates, mm |
|
|
296
|
+
| `ImageOrientationPatient` | `[1, 0, 0, 0, 1, 0]` | Orientation cosines |
|
|
297
|
+
|
|
298
|
+
The source defines many additional correction, geometry, timing, and vendor-related fields. Consult the notebook's **User Controlled Parameters** section for the complete set. These values should not be inferred or substituted without acquisition-specific evidence.
|
|
299
|
+
|
|
300
|
+
## π Parameter Compatibility
|
|
301
|
+
|
|
302
|
+
| Feature / argument | NumPy + metadata | Single PET DICOM | DICOM directory |
|
|
303
|
+
|---|---:|---:|---:|
|
|
304
|
+
| `parameter_estimation` | β | β | β |
|
|
305
|
+
| `metadata_json` / `input_metadata` | Required | No | No |
|
|
306
|
+
| `output_path` | Not allowed | β | β |
|
|
307
|
+
| Floating-point array return | β | No | No |
|
|
308
|
+
| Derived DICOM output | No | β | β |
|
|
309
|
+
| Independent series grouping | No | No | β |
|
|
310
|
+
| `mask_input` | No | No | No |
|
|
311
|
+
| `num_workers` | No | No | No |
|
|
312
|
+
| Deep-learning model selection | No | No | No |
|
|
313
|
+
|
|
314
|
+
## π API Reference
|
|
315
|
+
|
|
316
|
+
### `Radiuma_SUV(input_array, input_metadata, parameter_estimation="OFF")`
|
|
317
|
+
|
|
318
|
+
Converts an in-memory PET NumPy array to SUVbw. Returns `(suv_array, output_metadata)`.
|
|
319
|
+
|
|
320
|
+
### `Radiuma_SUV(input_array, input_metadata, parameter_estimation="ON")`
|
|
321
|
+
|
|
322
|
+
Converts an in-memory PET NumPy array to SUVbw, it replace missed parameters in input image DICOM header with default vlues defined in code. Returns `(suv_array, output_metadata)`.
|
|
323
|
+
|
|
324
|
+
### `Radiuma_SUV_from_input(image_input, metadata_json=None, parameter_estimation="OFF", output_path=None)`
|
|
325
|
+
|
|
326
|
+
Detects input representation and returns a matching result: a NumPy array or a new DICOM output file/folder path, plus corresponding metadata. DICOM source objects are not deliberately overwritten.
|
|
327
|
+
|
|
328
|
+
### `Radiuma_SUV_from_input(image_input, metadata_json=None, parameter_estimation="ON", output_path=None)`
|
|
329
|
+
Detects input representation and returns a matching result: a new DICOM output file/folder path, it replace missed parameters in input image DICOM header with default vlues defined in code. DICOM source objects are not deliberately overwritten.
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
from radiuma_suv import RadiumaSUVLoader
|
|
333
|
+
converter = RadiumaSUVLoader(parameter_estimation="OFF", output_path="pet_output.dcm")
|
|
334
|
+
output, metadata = converter.convert("pet_input.dcm")
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
The source also defines `main(input_array, input_metadata, parameter_estimation="OFF")` as an in-memory alias. Its availability as a package-level import depends on your `__init__.py` exports.
|
|
338
|
+
|
|
339
|
+
## π Output Structure
|
|
340
|
+
|
|
341
|
+
| Input | First return value | Second return value |
|
|
342
|
+
|---|---|---|
|
|
343
|
+
| NumPy array | Floating-point SUVbw NumPy array | Metadata dictionary |
|
|
344
|
+
| Single PET DICOM file | New DICOM file path | Output header dictionary |
|
|
345
|
+
| PET DICOM folder, one series | Output directory path | List of header dictionaries |
|
|
346
|
+
| Folder, multiple series | Output root directory path | Nested header lists |
|
|
347
|
+
|
|
348
|
+
**DICOM representation:** The source encodes SUVbw into calibrated **signed 16-bit pixels**. For conventional PET, the output `RescaleSlope` is needed to recover actual SUVbw. For Enhanced PET, use its real-world value mapping. The writer checks the saved file's pixel shape and reconstruction against calculated values within quantization tolerance. This is not an independent reference SUV validation.
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
## π’ Feature Extraction Modes
|
|
352
|
+
|
|
353
|
+
The source does not implement feature extraction. Its relevant modes are input/conversion paths:
|
|
354
|
+
|
|
355
|
+
1. Conventional PET intensity rescaling and unit conversion to SUVbw.
|
|
356
|
+
2. Enhanced PET per-frame mapping and SUVbw conversion.
|
|
357
|
+
3. In-memory floating-point NumPy return.
|
|
358
|
+
4. Calibrated derived DICOM output.
|
|
359
|
+
|
|
360
|
+
The implementation includes unit conversion helpers for `BQML`, `GML`, `CM2ML`, and `CNTS`, plus body-composition normalization helpers used in certain transformations. Supported paths require valid metadata; they are not guaranteed for every scanner-specific DICOM object.
|
|
361
|
+
|
|
362
|
+
## π Supported File Formats
|
|
363
|
+
|
|
364
|
+
| Format | Supported | Notes |
|
|
365
|
+
|---|---|---|
|
|
366
|
+
| Conventional PET DICOM `.dcm` | Yes | Single frame |
|
|
367
|
+
| Enhanced PET DICOM `.dcm` | Yes | Multi-frame Enhanced PET SOP class |
|
|
368
|
+
| Extensionless DICOM in a folder | Detected if readable | Must identify as PET (`Modality=PT`) |
|
|
369
|
+
| PET DICOM directory | Yes | Recursive series grouping |
|
|
370
|
+
| In-memory NumPy `ndarray` | Yes | Must provide matching DICOM metadata |
|
|
371
|
+
| `.npy` path | No | Load with `np.load()` and pass array |
|
|
372
|
+
|
|
373
|
+
## π― Library Examples
|
|
374
|
+
|
|
375
|
+
### Example 1: Single DICOM
|
|
376
|
+
|
|
377
|
+
```python
|
|
378
|
+
from radiuma_suv import Radiuma_SUV_from_input
|
|
379
|
+
result, meta = Radiuma_SUV_from_input("pet.dcm", parameter_estimation="OFF")
|
|
380
|
+
print(result)
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
### Example 2: Multiple PET folders
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
from radiuma_suv import Radiuma_SUV_from_input
|
|
387
|
+
out, headers = Radiuma_SUV_from_input(
|
|
388
|
+
"PET_Input", parameter_estimation="OFF", output_path="SUV_Output"
|
|
389
|
+
)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Example 3: NumPy data
|
|
393
|
+
|
|
394
|
+
```python
|
|
395
|
+
import numpy as np
|
|
396
|
+
from radiuma_suv import Radiuma_SUV
|
|
397
|
+
pixels = np.load("pet_pixels.npy")
|
|
398
|
+
# Load the genuine DICOM metadata for the same scan.
|
|
399
|
+
suv, meta = Radiuma_SUV(pixels, matching_pet_dicom_metadata, "OFF")
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
The `matching_pet_dicom_metadata` variable must be defined using actual DICOM metadata before executing this example.
|
|
403
|
+
|
|
404
|
+
## β‘ Performance Tips
|
|
405
|
+
|
|
406
|
+
1. Use the folder interface when processing multiple PET DICOM series.
|
|
407
|
+
2. Keep output outside the input directory and ensure the output path does not exist.
|
|
408
|
+
3. Avoid making unnecessary copies of large arrays when working with NumPy.
|
|
409
|
+
4. Do not assume parallel acceleration: no multiprocessing API is implemented.
|
|
410
|
+
5. Use real acquisition-specific metadata for correct dose and decay calculations.
|
|
411
|
+
6. Validate numerical values after conversion and DICOM quantization.
|
|
412
|
+
7. The notebook contains no benchmarking results, so no speed claims are made here.
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
```python
|
|
416
|
+
from radiuma_suv import Radiuma_SUV_from_input
|
|
417
|
+
|
|
418
|
+
def process_selected_pet(source, destination):
|
|
419
|
+
return Radiuma_SUV_from_input(
|
|
420
|
+
image_input=source,
|
|
421
|
+
output_path=destination,
|
|
422
|
+
parameter_estimation="OFF",
|
|
423
|
+
)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
## β Troubleshooting
|
|
428
|
+
|
|
429
|
+
| Message / problem | Recommended check |
|
|
430
|
+
|---|---|
|
|
431
|
+
| `ModuleNotFoundError: No module named 'radiuma_suv'` | Confirm the package was created, installed, and imported from the active Python environment. |
|
|
432
|
+
| `NumPy PET input requires associated DICOM metadata_json` | Pass matching DICOM metadata with the NumPy array. |
|
|
433
|
+
| `parameter_estimation must be "ON" or "OFF"` | Use the exact supported values. |
|
|
434
|
+
| `Input must be PET DICOM (Modality=PT)` | Confirm the file really contains PET DICOM. |
|
|
435
|
+
| `Non-Enhanced multi-frame PET is unsupported` | Input format is outside the implemented multi-frame path. |
|
|
436
|
+
| `No PET DICOM series found` | Verify DICOM readability, modality, and folder contents. |
|
|
437
|
+
| `Output directory must not be nested within input folder` | Choose an independent output directory. |
|
|
438
|
+
| `Refusing to overwrite existing output` | Choose another destination. |
|
|
439
|
+
| Missing activity, weight, half-life, or timing | Review source metadata; do not blindly apply configured defaults. |
|
|
440
|
+
| Unexpected SUVbw values | Recheck units, calibration, corrected dose, decay time, and actual acquisition data. |
|
|
441
|
+
|
|
442
|
+
### Get Help
|
|
443
|
+
|
|
444
|
+
- **Examples**: Run `python examples/basic_usage.py`
|
|
445
|
+
|
|
446
|
+
## π Version History
|
|
447
|
+
|
|
448
|
+
The uploaded notebook does not state a release history or published Radiuma_SUV version. Suggested initial entry **after an actual package release**:
|
|
449
|
+
|
|
450
|
+
```text
|
|
451
|
+
v0.0.0 β proposed first Radiuma_SUV library release
|
|
452
|
+
- Conventional PET DICOM to SUVbw
|
|
453
|
+
- Enhanced multi-frame PET to SUVbw
|
|
454
|
+
- NumPy input and metadata output
|
|
455
|
+
- Recursive DICOM series processing
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## π¬ Contact
|
|
459
|
+
|
|
460
|
+
Radiuma_SUV is available **free of charge**.
|
|
461
|
+
For access, questions, or feedback:
|
|
462
|
+
|
|
463
|
+
**Dr. Mohammad R. Salmanpour (Team Lead)**
|
|
464
|
+
π§[msalman@bccrc.ca](mailto:msalman@bccrc.ca) | [m.salmanpoor66@gmail.com](mailto:m.salmanpoor66@gmail.com), [m.salmanpour@ubc.ca](mailto:m.salmanpour@ubc.ca)
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
## π οΈ Maintenance
|
|
468
|
+
|
|
469
|
+
For technical support and maintenance inquiries, please contact:
|
|
470
|
+
|
|
471
|
+
**Dr. Mohammad R. Salmanpour (Team Lead)**
|
|
472
|
+
msalman@bccrc.ca β m.salmanpoor66@gmail.com β m.salmanpour@ubc.ca
|
|
473
|
+
|
|
474
|
+
**Ramin Afrah**
|
|
475
|
+
## π₯ Authors
|
|
476
|
+
|
|
477
|
+
- **Dr. Mohammad R. Salmanpour (Team Lead, Fund Provider, Evaluator, Medical Imaging Expert, Backend Development, Code Refactoring, Debugging, Library Management, IBSI Standardization, and Activation of the PySERA Library, and GUI Development in 3D Slicer)** β [msalman@bccrc.ca](mailto:msalman@bccrc.ca), [m.salmanpoor66@gmail.com](mailto:m.salmanpoor66@gmail.com), [m.salmanpour@ubc.ca](mailto:m.salmanpour@ubc.ca)
|
|
478
|
+
- **Ramin Afrah (Development, Code Refactoring, Debugging, and Library Management)**
|
|
479
|
+
- **Yasaman Salehi (Testing)**
|
|
480
|
+
- **Sonya Falahati (Tesing)**
|
|
481
|
+
- **Dr. Mehrdad Oveisi (Evaluator, Software Engineer, and Advisor)**
|
|
482
|
+
- **Dr. Arman Rahmim (Fund Provider, Medical Imaging Expert, Evaluator, and Advisor)**
|
|
483
|
+
|
|
484
|
+
## π Citation
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
```bibtex
|
|
488
|
+
@misc{salmanpour2026Radiua_SUVpython,
|
|
489
|
+
title={Radiuma_SUV: Open-Source Standardized Python Library for PET-to-SUVbw conversion},
|
|
490
|
+
author={Mohammad R. Salmanpour and Ramin Afrah and Mehrdad Oveisi and Arman Rahmim},
|
|
491
|
+
year={2026},
|
|
492
|
+
eprint={2511.15963},
|
|
493
|
+
archivePrefix={arXiv},
|
|
494
|
+
primaryClass={physics.med-ph},
|
|
495
|
+
url={https://arxiv.org/abs/2511.15963},
|
|
496
|
+
}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
## π License
|
|
500
|
+
|
|
501
|
+
This open-source software is released under the **MIT License**, which grants permission to use, modify, and distribute it for any purpose, including research or commercial use, without requiring modified versions to be shared as open source. See the [LICENSE](LICENSE) file for details.
|
|
502
|
+
|
|
503
|
+
## Support
|
|
504
|
+
|
|
505
|
+
|
|
506
|
+
- **Issues**: [GitHub Issues](https://github.com/radiuma-com/Radiuma_SUV/issues)
|
|
507
|
+
- **Documentation**: This README and the included guides
|
|
508
|
+
- **Examples**: See `examples/basic_usage.py`
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
## Acknowledgment
|
|
512
|
+
|
|
513
|
+
- [π¬ **Qu**antitative **R**adiomolecular **I**maging and **T**herapy (Qurit) Lab, University of British Columbia, Vancouver, BC, Canada](https://www.qurit.ca)
|
|
514
|
+
- [π₯ BC Cancer Research Institute, Department of Basic and Translational Research, Vancouver, BC, Canada](https://www.bccrc.ca/)
|
|
515
|
+
- [π» **Vir**tual **Collab**oration (VirCollab) Group, Vancouver, BC, Canada](https://vircollab.com/#/)
|
|
516
|
+
- [π **Tec**hnological **Vi**rtual **Co**llaboration **Corp**oration (TECVICO Corp.), Vancouver, BC, Canada](https://www.tecvico.com)
|
|
517
|
+
We gratefully acknowledge funding from theπ° Natural Sciences and Engineering Research Council of Canada (**NSERC**) Idea to Innovation [**I2I**] Grant **GR034192**.
|
|
518
|
+
---
|
|
519
|
+
|
|
520
|
+
*Radiuma_SUV: PET-to-SUVbw conversion for NumPy arrays and DICOM images.*
|