neurovolume 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.
- neurovolume-0.0.0/PKG-INFO +116 -0
- neurovolume-0.0.0/README.md +104 -0
- neurovolume-0.0.0/pyproject.toml +18 -0
- neurovolume-0.0.0/src/neurovolume/__init__.py +1 -0
- neurovolume-0.0.0/src/neurovolume/_native/libneurovolume.dylib +0 -0
- neurovolume-0.0.0/src/neurovolume/core.py +188 -0
- neurovolume-0.0.0/src/neurovolume/py.typed +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: neurovolume
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: Python library for Neurovolume. Build VDBs for scientific visualizations
|
|
5
|
+
Author: joachimbbp
|
|
6
|
+
Author-email: joachimbbp <104856283+joachimbbp@users.noreply.github.com>
|
|
7
|
+
Requires-Dist: numpy>=2.3.5
|
|
8
|
+
Requires-Dist: pytest>=9.0.1
|
|
9
|
+
Requires-Dist: ziglang>=0.15.1
|
|
10
|
+
Requires-Python: >=3.14
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Neurovolume is a volumetric scientific visualization pipeline and custom-built, scientific data-focused, VDB writer. The VDB writer is written in Zig with no external dependencies.
|
|
16
|
+
|
|
17
|
+
While this project focuses on neuroscience, it includes `ndarray` to `VDB` to support virtually any volumetric data pipeline.
|
|
18
|
+
|
|
19
|
+
This project is very much a **work in progress**. (see "Missing Features" below). As of now, I do not recommend regarding the images created by this software as scientifically accurate.
|
|
20
|
+
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# 🏗️ Setup and Build
|
|
25
|
+
Neurovolume requires [Zig 0.15.1](https://ziglang.org/download/#release-0.15.1). It was developed using [Blender 4.3.2](https://www.blender.org/download/releases/4-3/) and [Python 3.11.13](https://www.python.org/downloads/release/python-31113/).
|
|
26
|
+
|
|
27
|
+
To compile, run `zig build` from the project repo root.
|
|
28
|
+
|
|
29
|
+
The following files need to be modified before building and running. Presently the most robust way to run this program is to include the full system paths for all of these. Feel free to look at the example paths to get an idea of the setup.
|
|
30
|
+
|
|
31
|
+
In `./src/config.zig.zon`:
|
|
32
|
+
If you wish to run tests, download the [T1](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/anat/sub-01_T1w.nii.gz?versionId=5ZTXVLawdWoVNWe5XVuV6DfF2BnmxzQz) and [BOLD](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/func/sub-01_task-emotionalfaces_run-1_bold.nii.gz?versionId=tq8Y3ktm31Aa8JB0991n9K0XNmHyRS1Q) images to `./media`
|
|
33
|
+
Unzip both of these `.gz` files before running the tests.
|
|
34
|
+
- Set `.nifti_t1` and `.bold` to point to the above test files in media.
|
|
35
|
+
- Set `.vdb_output_dir` and `.output` to your output folder (defaults to `./output`).
|
|
36
|
+
|
|
37
|
+
In `./neurovolume/src/neurovolume/core.py` (The Python library):
|
|
38
|
+
- Set `lib_path` to the build file of the zig library (defaults to `./zig-out/lib/libneurovolume.dylib`)
|
|
39
|
+
- Set `output_dir` to your output directory (same as the `./output` path mentioned above in the `.zon` file)
|
|
40
|
+
|
|
41
|
+
In `./python/__init__.py` (the Blender plugin):
|
|
42
|
+
- Set `user_set_output_path` to the output path (same output as always)
|
|
43
|
+
- Set `user_set_default_nifti` to the `sub-01_T1w.nii` file in your media folder. This is optional, but it's sometimes nice to have a default path here when testing.
|
|
44
|
+
|
|
45
|
+
In `./tests/test_core.py` (Optional testing file):
|
|
46
|
+
- Set `static_testfile` and the `fmri_testfile` to the T1 and BOLD testfiles you downloaded to `./media`
|
|
47
|
+
|
|
48
|
+
These hard-coded paths are not great and very much a hack. They were needed to cover some weird edge cases early in development and will be cleaned up later.
|
|
49
|
+
|
|
50
|
+
If you wish to find all of these, they should be tagged with `USERSET:`
|
|
51
|
+
|
|
52
|
+
# 🔌 Blender Plugin
|
|
53
|
+
Install the Blender plugin using one of the following methods:
|
|
54
|
+
- With [Jacques Lucke's vsCode extension for Blender](https://github.com/JacquesLucke/blender_vscode) (recommended)
|
|
55
|
+
- [Via the Add-ons section](https://docs.blender.org/manual/en/latest/editors/preferences/addons.html)
|
|
56
|
+
- Copy-pasting the add-on into Blender's [Text-editor](https://docs.blender.org/manual/en/latest/editors/text_editor.html) and then clicking the triangular "play" button to run.
|
|
57
|
+
|
|
58
|
+
Import a NIfTI files as a VDBs via the Neurovolume panel:
|
|
59
|
+
|
|
60
|
+

|
|
61
|
+
|
|
62
|
+
Render and enjoy!
|
|
63
|
+
|
|
64
|
+

|
|
65
|
+
|
|
66
|
+
# 🐍 Python and ndArray usage
|
|
67
|
+
In the library located at `./python/neurovolume_lib.py` there is `ndarray_toVDB`. This function will build a static VDB out of a 3D ndarray and a transform. This allows users to build a VDB straight from their own domain-specific data-processing pipeline.
|
|
68
|
+
|
|
69
|
+
The following following neuroscience-specific example actually runs faster than the native `NIfTI1` implementation:
|
|
70
|
+
|
|
71
|
+
````python
|
|
72
|
+
import nibabel as nib
|
|
73
|
+
import neurovolume_lib as nv
|
|
74
|
+
import numpy as np
|
|
75
|
+
from datetime import datetime
|
|
76
|
+
|
|
77
|
+
static_testfile = "./media/sub-01_T1w.nii"
|
|
78
|
+
|
|
79
|
+
def normalize_array(arr):
|
|
80
|
+
return (arr - np.min(arr)) / (np.max(arr) - np.min(arr))
|
|
81
|
+
|
|
82
|
+
img = nib.load(static_testfile)
|
|
83
|
+
data = np.array(img.get_fdata(), order='C', dtype=np.float64)
|
|
84
|
+
norm = normalize_array(data).astype(np.float64)
|
|
85
|
+
|
|
86
|
+
norm = np.transpose(norm, (1, 2, 0))
|
|
87
|
+
norm = np.ascontiguousarray(norm)
|
|
88
|
+
|
|
89
|
+
output = "./output/from_nib.vdb"
|
|
90
|
+
nv.ndarray_to_VDB(norm, output, img.affine)
|
|
91
|
+
````
|
|
92
|
+
Note that all data must be normalized from 0.0-1.0 before being written to a VDB.
|
|
93
|
+
|
|
94
|
+
# ☁️ Why VDB?
|
|
95
|
+
VDBs are a highly performant, art-directable, volumetric data structure that supports animations. Our volume-based approach aims to provide easy access to the original density data throughout the visualization and analysis pipeline. Unlike the [openVDB repo](https://www.openvdb.org/), our smaller version is much more readable and does not need to be run in a docker container.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# 🛠️ Missing Features
|
|
99
|
+
While a comprehensive road-map will be published soon, there are a few important considerations to take into account now.
|
|
100
|
+
- Presently the VDB writer isn't sparse nor does it support multiple grids. Tiles and multiple grids are in development.
|
|
101
|
+
- Neurovolume currently only natively supports `NIfTI1` files (and only some variants). Full coverage and `NIfTI2` will be supported soon. Until then, you can use an `ndarray` as an intermediary (see Python Usage).
|
|
102
|
+
- Frame interpolation (present in the original Go prototype) is currently under development on this branch. If you wish to access the old Go code, check out [the archive](https://github.com/joachimbbp/neurovolume_archive)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# 🧠 Dataset Citation
|
|
106
|
+
This software was tested using the following datasets.
|
|
107
|
+
|
|
108
|
+
Isaac David and Victor Olalde-Mathieu and Ana Y. Martínez and Lluviana Rodríguez-Vidal and Fernando A. Barrios (2021). Emotion Category and Face Perception Task Optimized for Multivariate Pattern Analysis. OpenNeuro. [Dataset] doi: 10.18112/openneuro.ds003548.v1.0.1
|
|
109
|
+
|
|
110
|
+
[OpenNeuro Study Link](https://openneuro.org/datasets/ds003548/versions/1.0.1)
|
|
111
|
+
|
|
112
|
+
[Direct Download Link for T1 Anat test file](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/anat/sub-01_T1w.nii.gz?versionId=5ZTXVLawdWoVNWe5XVuV6DfF2BnmxzQz)
|
|
113
|
+
|
|
114
|
+
[Direct Download Link for BOLD test file](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/func/sub-01_task-emotionalfaces_run-1_bold.nii.gz?versionId=tq8Y3ktm31Aa8JB0991n9K0XNmHyRS1Q)
|
|
115
|
+
|
|
116
|
+
The MNI Template can be found [Here](https://github.com/Angeluz-07/MRI-preprocessing-techniques/tree/main/assets/templates)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
Neurovolume is a volumetric scientific visualization pipeline and custom-built, scientific data-focused, VDB writer. The VDB writer is written in Zig with no external dependencies.
|
|
4
|
+
|
|
5
|
+
While this project focuses on neuroscience, it includes `ndarray` to `VDB` to support virtually any volumetric data pipeline.
|
|
6
|
+
|
|
7
|
+
This project is very much a **work in progress**. (see "Missing Features" below). As of now, I do not recommend regarding the images created by this software as scientifically accurate.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# 🏗️ Setup and Build
|
|
13
|
+
Neurovolume requires [Zig 0.15.1](https://ziglang.org/download/#release-0.15.1). It was developed using [Blender 4.3.2](https://www.blender.org/download/releases/4-3/) and [Python 3.11.13](https://www.python.org/downloads/release/python-31113/).
|
|
14
|
+
|
|
15
|
+
To compile, run `zig build` from the project repo root.
|
|
16
|
+
|
|
17
|
+
The following files need to be modified before building and running. Presently the most robust way to run this program is to include the full system paths for all of these. Feel free to look at the example paths to get an idea of the setup.
|
|
18
|
+
|
|
19
|
+
In `./src/config.zig.zon`:
|
|
20
|
+
If you wish to run tests, download the [T1](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/anat/sub-01_T1w.nii.gz?versionId=5ZTXVLawdWoVNWe5XVuV6DfF2BnmxzQz) and [BOLD](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/func/sub-01_task-emotionalfaces_run-1_bold.nii.gz?versionId=tq8Y3ktm31Aa8JB0991n9K0XNmHyRS1Q) images to `./media`
|
|
21
|
+
Unzip both of these `.gz` files before running the tests.
|
|
22
|
+
- Set `.nifti_t1` and `.bold` to point to the above test files in media.
|
|
23
|
+
- Set `.vdb_output_dir` and `.output` to your output folder (defaults to `./output`).
|
|
24
|
+
|
|
25
|
+
In `./neurovolume/src/neurovolume/core.py` (The Python library):
|
|
26
|
+
- Set `lib_path` to the build file of the zig library (defaults to `./zig-out/lib/libneurovolume.dylib`)
|
|
27
|
+
- Set `output_dir` to your output directory (same as the `./output` path mentioned above in the `.zon` file)
|
|
28
|
+
|
|
29
|
+
In `./python/__init__.py` (the Blender plugin):
|
|
30
|
+
- Set `user_set_output_path` to the output path (same output as always)
|
|
31
|
+
- Set `user_set_default_nifti` to the `sub-01_T1w.nii` file in your media folder. This is optional, but it's sometimes nice to have a default path here when testing.
|
|
32
|
+
|
|
33
|
+
In `./tests/test_core.py` (Optional testing file):
|
|
34
|
+
- Set `static_testfile` and the `fmri_testfile` to the T1 and BOLD testfiles you downloaded to `./media`
|
|
35
|
+
|
|
36
|
+
These hard-coded paths are not great and very much a hack. They were needed to cover some weird edge cases early in development and will be cleaned up later.
|
|
37
|
+
|
|
38
|
+
If you wish to find all of these, they should be tagged with `USERSET:`
|
|
39
|
+
|
|
40
|
+
# 🔌 Blender Plugin
|
|
41
|
+
Install the Blender plugin using one of the following methods:
|
|
42
|
+
- With [Jacques Lucke's vsCode extension for Blender](https://github.com/JacquesLucke/blender_vscode) (recommended)
|
|
43
|
+
- [Via the Add-ons section](https://docs.blender.org/manual/en/latest/editors/preferences/addons.html)
|
|
44
|
+
- Copy-pasting the add-on into Blender's [Text-editor](https://docs.blender.org/manual/en/latest/editors/text_editor.html) and then clicking the triangular "play" button to run.
|
|
45
|
+
|
|
46
|
+
Import a NIfTI files as a VDBs via the Neurovolume panel:
|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+
Render and enjoy!
|
|
51
|
+
|
|
52
|
+

|
|
53
|
+
|
|
54
|
+
# 🐍 Python and ndArray usage
|
|
55
|
+
In the library located at `./python/neurovolume_lib.py` there is `ndarray_toVDB`. This function will build a static VDB out of a 3D ndarray and a transform. This allows users to build a VDB straight from their own domain-specific data-processing pipeline.
|
|
56
|
+
|
|
57
|
+
The following following neuroscience-specific example actually runs faster than the native `NIfTI1` implementation:
|
|
58
|
+
|
|
59
|
+
````python
|
|
60
|
+
import nibabel as nib
|
|
61
|
+
import neurovolume_lib as nv
|
|
62
|
+
import numpy as np
|
|
63
|
+
from datetime import datetime
|
|
64
|
+
|
|
65
|
+
static_testfile = "./media/sub-01_T1w.nii"
|
|
66
|
+
|
|
67
|
+
def normalize_array(arr):
|
|
68
|
+
return (arr - np.min(arr)) / (np.max(arr) - np.min(arr))
|
|
69
|
+
|
|
70
|
+
img = nib.load(static_testfile)
|
|
71
|
+
data = np.array(img.get_fdata(), order='C', dtype=np.float64)
|
|
72
|
+
norm = normalize_array(data).astype(np.float64)
|
|
73
|
+
|
|
74
|
+
norm = np.transpose(norm, (1, 2, 0))
|
|
75
|
+
norm = np.ascontiguousarray(norm)
|
|
76
|
+
|
|
77
|
+
output = "./output/from_nib.vdb"
|
|
78
|
+
nv.ndarray_to_VDB(norm, output, img.affine)
|
|
79
|
+
````
|
|
80
|
+
Note that all data must be normalized from 0.0-1.0 before being written to a VDB.
|
|
81
|
+
|
|
82
|
+
# ☁️ Why VDB?
|
|
83
|
+
VDBs are a highly performant, art-directable, volumetric data structure that supports animations. Our volume-based approach aims to provide easy access to the original density data throughout the visualization and analysis pipeline. Unlike the [openVDB repo](https://www.openvdb.org/), our smaller version is much more readable and does not need to be run in a docker container.
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# 🛠️ Missing Features
|
|
87
|
+
While a comprehensive road-map will be published soon, there are a few important considerations to take into account now.
|
|
88
|
+
- Presently the VDB writer isn't sparse nor does it support multiple grids. Tiles and multiple grids are in development.
|
|
89
|
+
- Neurovolume currently only natively supports `NIfTI1` files (and only some variants). Full coverage and `NIfTI2` will be supported soon. Until then, you can use an `ndarray` as an intermediary (see Python Usage).
|
|
90
|
+
- Frame interpolation (present in the original Go prototype) is currently under development on this branch. If you wish to access the old Go code, check out [the archive](https://github.com/joachimbbp/neurovolume_archive)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
# 🧠 Dataset Citation
|
|
94
|
+
This software was tested using the following datasets.
|
|
95
|
+
|
|
96
|
+
Isaac David and Victor Olalde-Mathieu and Ana Y. Martínez and Lluviana Rodríguez-Vidal and Fernando A. Barrios (2021). Emotion Category and Face Perception Task Optimized for Multivariate Pattern Analysis. OpenNeuro. [Dataset] doi: 10.18112/openneuro.ds003548.v1.0.1
|
|
97
|
+
|
|
98
|
+
[OpenNeuro Study Link](https://openneuro.org/datasets/ds003548/versions/1.0.1)
|
|
99
|
+
|
|
100
|
+
[Direct Download Link for T1 Anat test file](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/anat/sub-01_T1w.nii.gz?versionId=5ZTXVLawdWoVNWe5XVuV6DfF2BnmxzQz)
|
|
101
|
+
|
|
102
|
+
[Direct Download Link for BOLD test file](https://s3.amazonaws.com/openneuro.org/ds003548/sub-01/func/sub-01_task-emotionalfaces_run-1_bold.nii.gz?versionId=tq8Y3ktm31Aa8JB0991n9K0XNmHyRS1Q)
|
|
103
|
+
|
|
104
|
+
The MNI Template can be found [Here](https://github.com/Angeluz-07/MRI-preprocessing-techniques/tree/main/assets/templates)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "neurovolume"
|
|
3
|
+
version = "0.0.0"
|
|
4
|
+
description = "Python library for Neurovolume. Build VDBs for scientific visualizations"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "joachimbbp", email = "104856283+joachimbbp@users.noreply.github.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.14"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"numpy>=2.3.5",
|
|
12
|
+
"pytest>=9.0.1",
|
|
13
|
+
"ziglang>=0.15.1",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[build-system]
|
|
17
|
+
requires = ["uv_build>=0.9.8,<0.10.0"]
|
|
18
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from neurovolume.core import *
|
|
Binary file
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import ctypes as c
|
|
2
|
+
import numpy as np # DEPENDENCY:
|
|
3
|
+
import sys
|
|
4
|
+
import ctypes
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
# LLM:
|
|
9
|
+
def get_library_name():
|
|
10
|
+
if sys.platform == "darwin":
|
|
11
|
+
return "libneurovolume.dylib"
|
|
12
|
+
elif sys.platform == "win32":
|
|
13
|
+
return "libneurovolume.dll"
|
|
14
|
+
else: # Linux and others
|
|
15
|
+
return "libneurovolume.so"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
lib_path = Path(__file__).parent / "_native" / get_library_name()
|
|
19
|
+
lib = ctypes.CDLL(str(lib_path))
|
|
20
|
+
# LLMEND:
|
|
21
|
+
|
|
22
|
+
# _: Main code:
|
|
23
|
+
|
|
24
|
+
nvol = c.cdll.LoadLibrary(lib_path) # Neurovolume library
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def b(string):
|
|
28
|
+
"""
|
|
29
|
+
Returns the utf-u8 encoded bytes literal of the string
|
|
30
|
+
Equivalent to 'b"inputstring"'
|
|
31
|
+
"""
|
|
32
|
+
return string.encode("utf-8")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def get_basename(path):
|
|
36
|
+
hierarchy = path.split("/")
|
|
37
|
+
return hierarchy[-1].split(".")[0]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def get_folder(path):
|
|
41
|
+
"""Returns the folder in which the path points to"""
|
|
42
|
+
hiearchy = path.split("/")
|
|
43
|
+
return "/".join(hiearchy[:-1])
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def ndarray_to_VDB(arr: np.ndarray, save_path: str, transform: np.ndarray = None):
|
|
47
|
+
# LOTS OF LLM: here
|
|
48
|
+
if transform is None:
|
|
49
|
+
transform = np.eye(4, dtype=np.float64)
|
|
50
|
+
affine_flat = transform.flatten().astype(np.float64)
|
|
51
|
+
|
|
52
|
+
arr = np.ascontiguousarray(arr, dtype=np.float32)
|
|
53
|
+
dims = np.array(arr.shape, dtype=np.uint64)
|
|
54
|
+
nvol.ndArrayToVDB_c.argtypes = [
|
|
55
|
+
np.ctypeslib.ndpointer(dtype=np.float32, flags="C_CONTIGUOUS"),
|
|
56
|
+
c.POINTER(c.c_size_t),
|
|
57
|
+
np.ctypeslib.ndpointer(dtype=np.float64, flags="C_CONTIGUOUS"),
|
|
58
|
+
c.c_char_p,
|
|
59
|
+
]
|
|
60
|
+
nvol.ndArrayToVDB_c.restype = c.c_size_t
|
|
61
|
+
res = nvol.ndArrayToVDB_c(
|
|
62
|
+
arr,
|
|
63
|
+
dims.ctypes.data_as(c.POINTER(c.c_size_t)),
|
|
64
|
+
affine_flat,
|
|
65
|
+
save_path.encode("utf-8"),
|
|
66
|
+
)
|
|
67
|
+
if res == 0:
|
|
68
|
+
print("error!")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def nifti1_to_VDB(filepath: str, normalize: bool) -> str:
|
|
72
|
+
BUF_SIZE = 4096 # somewhat arbitrary, should be big enough for file name
|
|
73
|
+
save_location = c.create_string_buffer(BUF_SIZE)
|
|
74
|
+
nvol.nifti1ToVDB_c.argtypes = [
|
|
75
|
+
c.c_char_p,
|
|
76
|
+
c.c_char_p,
|
|
77
|
+
c.c_bool,
|
|
78
|
+
c.POINTER(c.c_char),
|
|
79
|
+
c.c_size_t,
|
|
80
|
+
]
|
|
81
|
+
nvol.nifti1ToVDB_c.restype = c.c_size_t
|
|
82
|
+
nvol.nifti1ToVDB_c(b(filepath), b(output_dir), normalize, save_location, BUF_SIZE)
|
|
83
|
+
|
|
84
|
+
return save_location.value.decode()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# FIX: almost all of these `case "NIfTI1"` switches are redundant,
|
|
88
|
+
# the same logic is following in the zig code
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def num_frames(filepath: str, filetype: str) -> int:
|
|
92
|
+
match filetype:
|
|
93
|
+
case "NIfTI1":
|
|
94
|
+
nvol.numFrames_c.argtypes = [
|
|
95
|
+
c.c_char_p,
|
|
96
|
+
c.c_char_p,
|
|
97
|
+
]
|
|
98
|
+
nvol.numFrames_c.restype = c.c_size_t
|
|
99
|
+
num_frames = nvol.numFrames_c(b(filepath), b(filetype))
|
|
100
|
+
return num_frames
|
|
101
|
+
case _:
|
|
102
|
+
err_msg = f"{filetype} is unsupported for num_frames access"
|
|
103
|
+
raise ValueError(err_msg)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def pixdim(filepath: str, filetype: str, dim: int) -> float:
|
|
107
|
+
match filetype:
|
|
108
|
+
case "NIfTI1":
|
|
109
|
+
nvol.pixdim_c.argtypes = [c.c_char_p, c.c_char_p, c.c_int]
|
|
110
|
+
nvol.pixdim_c.restype = c.c_float
|
|
111
|
+
pixdim = nvol.pixdim_c(b(filepath), b(filetype), dim)
|
|
112
|
+
return pixdim
|
|
113
|
+
case _:
|
|
114
|
+
err_msg = f"{filetype} is unsupported for pixdim access"
|
|
115
|
+
raise ValueError(err_msg)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# WARN: never tested or used and test file just puts this as 0 for some reason
|
|
119
|
+
def slice_duration(filepath: str, filetype: str) -> int:
|
|
120
|
+
match filetype:
|
|
121
|
+
case "NIfTI1":
|
|
122
|
+
nvol.sliceDuration_c.argtypes = [
|
|
123
|
+
c.c_char_p,
|
|
124
|
+
c.c_char_p,
|
|
125
|
+
]
|
|
126
|
+
nvol.sliceDuration_c.restype = c.c_size_t
|
|
127
|
+
slice_duration = nvol.sliceDuration_c(b(filepath), b(filetype))
|
|
128
|
+
return slice_duration
|
|
129
|
+
case _:
|
|
130
|
+
err_msg = f"{filetype} is unsupported for slice_duration access"
|
|
131
|
+
raise ValueError(err_msg)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def unit(filepath: str, filetype: str, unit_kind: str) -> str:
|
|
135
|
+
BUF_SIZE = 64 # generously padded, tbh
|
|
136
|
+
unit_name = c.create_string_buffer(BUF_SIZE)
|
|
137
|
+
nvol.unit_c.argtypes = [
|
|
138
|
+
c.c_char_p,
|
|
139
|
+
c.c_char_p,
|
|
140
|
+
c.c_char_p,
|
|
141
|
+
c.POINTER(c.c_char),
|
|
142
|
+
c.c_size_t,
|
|
143
|
+
]
|
|
144
|
+
nvol.unit_c.restype = c.c_size_t
|
|
145
|
+
nvol.unit_c(b(filepath), b(filetype), b(unit_kind), unit_name, BUF_SIZE)
|
|
146
|
+
return unit_name.value.decode()
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def source_fps(filepath: str, filetype: str) -> int:
|
|
150
|
+
match filetype:
|
|
151
|
+
case "NIfTI1":
|
|
152
|
+
if num_frames(filepath, filetype) == 1:
|
|
153
|
+
# staic file, frames per second is zero
|
|
154
|
+
return 0
|
|
155
|
+
|
|
156
|
+
time_unit = unit(filepath, filetype, "time")
|
|
157
|
+
time_value = pixdim(filepath, filetype, 4)
|
|
158
|
+
match time_unit:
|
|
159
|
+
# time_in_seconds / time_value
|
|
160
|
+
case "Seconds":
|
|
161
|
+
return 1 / time_value
|
|
162
|
+
case "Miliseconds":
|
|
163
|
+
return 0.001 / time_value
|
|
164
|
+
case "Microseconds":
|
|
165
|
+
return 0.000001 / time_value
|
|
166
|
+
|
|
167
|
+
# These will probably be different
|
|
168
|
+
case "Hertz":
|
|
169
|
+
raise ValueError("hz not implemented yet")
|
|
170
|
+
case "Parts_per_million":
|
|
171
|
+
raise ValueError("ppm not implemented yet")
|
|
172
|
+
case "Radians_per_second":
|
|
173
|
+
raise ValueError("rpm not implemented yet")
|
|
174
|
+
case _:
|
|
175
|
+
raise ValueError(unit, "is an unknown unit, not implemented yet")
|
|
176
|
+
|
|
177
|
+
case _:
|
|
178
|
+
err_msg = f"{filetype} is unsupported for num_frames access"
|
|
179
|
+
raise ValueError(err_msg)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
#
|
|
183
|
+
# def real_size():
|
|
184
|
+
# # TODO: will need to get measurement units and as well as the pixdim
|
|
185
|
+
#
|
|
186
|
+
# # TODO: def runtime
|
|
187
|
+
# # which will include a lot fo the stuff in fps as well as temporal_offset
|
|
188
|
+
|
|
File without changes
|