pylottone 0.2.2__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.
- pylottone-0.2.2/.gitignore +177 -0
- pylottone-0.2.2/LICENSE +21 -0
- pylottone-0.2.2/PKG-INFO +142 -0
- pylottone-0.2.2/README.md +116 -0
- pylottone-0.2.2/environment.yml +22 -0
- pylottone-0.2.2/example_config.toml +60 -0
- pylottone-0.2.2/examples/main_editer_correct.py +480 -0
- pylottone-0.2.2/examples/main_pilottone_extract.py +431 -0
- pylottone-0.2.2/examples/main_pilottone_extract_exercise.py +1200 -0
- pylottone-0.2.2/examples/main_process_reference.py +135 -0
- pylottone-0.2.2/examples/run_all.py +46 -0
- pylottone-0.2.2/examples/save_pt_extract.py +297 -0
- pylottone-0.2.2/pyproject.toml +84 -0
- pylottone-0.2.2/requirements.txt +13 -0
- pylottone-0.2.2/src/pylottone/__init__.py +58 -0
- pylottone-0.2.2/src/pylottone/constants.py +8 -0
- pylottone-0.2.2/src/pylottone/editer.py +252 -0
- pylottone-0.2.2/src/pylottone/model_selection.py +94 -0
- pylottone-0.2.2/src/pylottone/mrdhelper.py +476 -0
- pylottone-0.2.2/src/pylottone/pt.py +735 -0
- pylottone-0.2.2/src/pylottone/reconstruction/Body6Spine18.xml +89 -0
- pylottone-0.2.2/src/pylottone/reconstruction/GIRF.py +275 -0
- pylottone-0.2.2/src/pylottone/reconstruction/GIRF_20200221_Duyn_method_coil2.mat +0 -0
- pylottone-0.2.2/src/pylottone/reconstruction/client.py +380 -0
- pylottone-0.2.2/src/pylottone/reconstruction/coils.py +499 -0
- pylottone-0.2.2/src/pylottone/reconstruction/connection.py +434 -0
- pylottone-0.2.2/src/pylottone/reconstruction/constants.py +55 -0
- pylottone-0.2.2/src/pylottone/reconstruction/send_to_recon_server.py +112 -0
- pylottone-0.2.2/src/pylottone/resources/__init__.py +1 -0
- pylottone-0.2.2/src/pylottone/resources/rocket_pipeline.pkl +0 -0
- pylottone-0.2.2/src/pylottone/selectionui.py +72 -0
- pylottone-0.2.2/src/pylottone/selfnav.py +244 -0
- pylottone-0.2.2/src/pylottone/signal.py +454 -0
- pylottone-0.2.2/src/pylottone/sobi/__init__.py +1 -0
- pylottone-0.2.2/src/pylottone/sobi/sobi.py +216 -0
- pylottone-0.2.2/src/pylottone/sobi/utils.py +78 -0
- pylottone-0.2.2/src/pylottone/trajectory.py +105 -0
- pylottone-0.2.2/src/pylottone/triggering.py +1327 -0
- pylottone-0.2.2/src/pylottone/vis.py +641 -0
- pylottone-0.2.2/tools/remove_waveform.py +91 -0
- pylottone-0.2.2/tools/respiratory_from_image.py +200 -0
- pylottone-0.2.2/tools/save_mrd_as_video.py +78 -0
- pylottone-0.2.2/tools/truncate_acquisitions.py +59 -0
- pylottone-0.2.2/tools/view_mrd_waveforms.py +866 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Project specific
|
|
2
|
+
output_recons/
|
|
3
|
+
config.toml
|
|
4
|
+
saved_figures/
|
|
5
|
+
figures/
|
|
6
|
+
configs/
|
|
7
|
+
*.h5
|
|
8
|
+
|
|
9
|
+
# Byte-compiled / optimized / DLL files
|
|
10
|
+
__pycache__/
|
|
11
|
+
*.py[cod]
|
|
12
|
+
*$py.class
|
|
13
|
+
|
|
14
|
+
# C extensions
|
|
15
|
+
*.so
|
|
16
|
+
|
|
17
|
+
# Distribution / packaging
|
|
18
|
+
.Python
|
|
19
|
+
build/
|
|
20
|
+
develop-eggs/
|
|
21
|
+
dist/
|
|
22
|
+
downloads/
|
|
23
|
+
eggs/
|
|
24
|
+
.eggs/
|
|
25
|
+
lib/
|
|
26
|
+
lib64/
|
|
27
|
+
parts/
|
|
28
|
+
sdist/
|
|
29
|
+
var/
|
|
30
|
+
wheels/
|
|
31
|
+
share/python-wheels/
|
|
32
|
+
*.egg-info/
|
|
33
|
+
.installed.cfg
|
|
34
|
+
*.egg
|
|
35
|
+
MANIFEST
|
|
36
|
+
|
|
37
|
+
# PyInstaller
|
|
38
|
+
# Usually these files are written by a python script from a template
|
|
39
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
40
|
+
*.manifest
|
|
41
|
+
*.spec
|
|
42
|
+
|
|
43
|
+
# Installer logs
|
|
44
|
+
pip-log.txt
|
|
45
|
+
pip-delete-this-directory.txt
|
|
46
|
+
|
|
47
|
+
# Unit test / coverage reports
|
|
48
|
+
htmlcov/
|
|
49
|
+
.tox/
|
|
50
|
+
.nox/
|
|
51
|
+
.coverage
|
|
52
|
+
.coverage.*
|
|
53
|
+
.cache
|
|
54
|
+
nosetests.xml
|
|
55
|
+
coverage.xml
|
|
56
|
+
*.cover
|
|
57
|
+
*.py,cover
|
|
58
|
+
.hypothesis/
|
|
59
|
+
.pytest_cache/
|
|
60
|
+
cover/
|
|
61
|
+
|
|
62
|
+
# Translations
|
|
63
|
+
*.mo
|
|
64
|
+
*.pot
|
|
65
|
+
|
|
66
|
+
# Django stuff:
|
|
67
|
+
*.log
|
|
68
|
+
local_settings.py
|
|
69
|
+
db.sqlite3
|
|
70
|
+
db.sqlite3-journal
|
|
71
|
+
|
|
72
|
+
# Flask stuff:
|
|
73
|
+
instance/
|
|
74
|
+
.webassets-cache
|
|
75
|
+
|
|
76
|
+
# Scrapy stuff:
|
|
77
|
+
.scrapy
|
|
78
|
+
|
|
79
|
+
# Sphinx documentation
|
|
80
|
+
docs/_build/
|
|
81
|
+
|
|
82
|
+
# PyBuilder
|
|
83
|
+
.pybuilder/
|
|
84
|
+
target/
|
|
85
|
+
|
|
86
|
+
# Jupyter Notebook
|
|
87
|
+
.ipynb_checkpoints
|
|
88
|
+
|
|
89
|
+
# IPython
|
|
90
|
+
profile_default/
|
|
91
|
+
ipython_config.py
|
|
92
|
+
|
|
93
|
+
# pyenv
|
|
94
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
95
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
96
|
+
# .python-version
|
|
97
|
+
|
|
98
|
+
# pipenv
|
|
99
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
100
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
101
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
102
|
+
# install all needed dependencies.
|
|
103
|
+
#Pipfile.lock
|
|
104
|
+
|
|
105
|
+
# poetry
|
|
106
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
107
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
108
|
+
# commonly ignored for libraries.
|
|
109
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
110
|
+
#poetry.lock
|
|
111
|
+
|
|
112
|
+
# pdm
|
|
113
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
114
|
+
#pdm.lock
|
|
115
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
116
|
+
# in version control.
|
|
117
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
118
|
+
.pdm.toml
|
|
119
|
+
.pdm-python
|
|
120
|
+
.pdm-build/
|
|
121
|
+
|
|
122
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
123
|
+
__pypackages__/
|
|
124
|
+
|
|
125
|
+
# Celery stuff
|
|
126
|
+
celerybeat-schedule
|
|
127
|
+
celerybeat.pid
|
|
128
|
+
|
|
129
|
+
# SageMath parsed files
|
|
130
|
+
*.sage.py
|
|
131
|
+
|
|
132
|
+
# Environments
|
|
133
|
+
.env
|
|
134
|
+
.venv
|
|
135
|
+
env/
|
|
136
|
+
venv/
|
|
137
|
+
ENV/
|
|
138
|
+
env.bak/
|
|
139
|
+
venv.bak/
|
|
140
|
+
|
|
141
|
+
# Spyder project settings
|
|
142
|
+
.spyderproject
|
|
143
|
+
.spyproject
|
|
144
|
+
|
|
145
|
+
# Rope project settings
|
|
146
|
+
.ropeproject
|
|
147
|
+
|
|
148
|
+
# mkdocs documentation
|
|
149
|
+
/site
|
|
150
|
+
|
|
151
|
+
# mypy
|
|
152
|
+
.mypy_cache/
|
|
153
|
+
.dmypy.json
|
|
154
|
+
dmypy.json
|
|
155
|
+
|
|
156
|
+
# Pyre type checker
|
|
157
|
+
.pyre/
|
|
158
|
+
|
|
159
|
+
# pytype static type analyzer
|
|
160
|
+
.pytype/
|
|
161
|
+
|
|
162
|
+
# Cython debug symbols
|
|
163
|
+
cython_debug/
|
|
164
|
+
|
|
165
|
+
# PyCharm
|
|
166
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
167
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
168
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
169
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
170
|
+
#.idea/
|
|
171
|
+
# pixi environments
|
|
172
|
+
.pixi
|
|
173
|
+
*.egg-info
|
|
174
|
+
|
|
175
|
+
# editor
|
|
176
|
+
.vscode/
|
|
177
|
+
.zed/
|
pylottone-0.2.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Magnetic Resonance Engineering Laboratory
|
|
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.
|
pylottone-0.2.2/PKG-INFO
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: pylottone
|
|
3
|
+
Version: 0.2.2
|
|
4
|
+
Summary: PylotToneMRI is a Python Toolbox with an emphasis on high-amplitude pilot tone applied to spiral MR imaging.
|
|
5
|
+
Author-email: Bilal Tasdelen <tasdelen@usc.edu>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Requires-Dist: joblib>=1.3
|
|
9
|
+
Requires-Dist: matplotlib>=3.10.5
|
|
10
|
+
Requires-Dist: numba
|
|
11
|
+
Requires-Dist: numpy>=2.3.2
|
|
12
|
+
Requires-Dist: pyfftw>=0.15.0
|
|
13
|
+
Requires-Dist: scikit-learn
|
|
14
|
+
Requires-Dist: scipy
|
|
15
|
+
Requires-Dist: sktime
|
|
16
|
+
Provides-Extra: gpu
|
|
17
|
+
Requires-Dist: cupy-cuda12x>=13.6.0; extra == 'gpu'
|
|
18
|
+
Provides-Extra: mrd
|
|
19
|
+
Requires-Dist: ismrmrd>=1.14.1; extra == 'mrd'
|
|
20
|
+
Provides-Extra: segmentation
|
|
21
|
+
Requires-Dist: mpl-image-segmenter>=0.2.1; extra == 'segmentation'
|
|
22
|
+
Provides-Extra: ui
|
|
23
|
+
Requires-Dist: ipywidgets>=8; extra == 'ui'
|
|
24
|
+
Requires-Dist: pyside6>=6.9.1; extra == 'ui'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# HAPTIC: High-amplitude Pilot Tone with Interference Cancellation
|
|
28
|
+
PylotToneMRI is a Python Toolbox with an emphasis on high-amplitude pilot tone applied to spiral MR imaging.
|
|
29
|
+
|
|
30
|
+
# Installation
|
|
31
|
+
|
|
32
|
+
Create an isolated environment using your favorite software (`uv`, `venv`, `conda`, etc.). This project provides an `uv.lock` for the exact replication of the environment via `uv`. Example for `venv`:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
python -m venv ${venv_name}
|
|
36
|
+
source ${venv_name}/bin/activate
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### For development:
|
|
40
|
+
Clone this repository and navigate into it:
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/usc-mrel/PylotToneMRI.git
|
|
43
|
+
cd PylotToneMRI
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Install via `pip` in dev mode:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install -e .
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
If you need ISMRMRD file I/O, waveform injection, or reconstruction tooling, install the MRD extra:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install -e '.[mrd]'
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
To enable GPU acceleration for EDITER, install the optional GPU extra:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install -e '.[gpu]'
|
|
62
|
+
```
|
|
63
|
+
## For usage as a library:
|
|
64
|
+
|
|
65
|
+
It can be directly installed from `PyPI` via `pip`:
|
|
66
|
+
```bash
|
|
67
|
+
pip install pylottone
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If you need ISMRMRD-backed workflows from the GitHub install, use:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install 'pylottone[mrd]'
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If you want EDITER GPU support from the GitHub install, use:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install 'pylottone[gpu]'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Note:** Toolbox is only tested for Python>=3.11 and Python<=3.12.
|
|
83
|
+
|
|
84
|
+
### For ECG guided PT and fusion algorithm:
|
|
85
|
+
|
|
86
|
+
ECG guided PT extraction (`examples/main_pilottone_extract_exercise.py`) requires `torch` library, which can be installed separately before running the script.
|
|
87
|
+
|
|
88
|
+
# Usage
|
|
89
|
+
|
|
90
|
+
Most inputs and outputs are in [ISMRMRD](https://ismrmrd.readthedocs.io/en/latest/) format. Base `pylottone` installs now leave ISMRMRD optional; install `pylottone[mrd]` for MRD file I/O, waveform editing, and reconstruction tooling. Some scripts do modify the input raw data, so in case something goes wrong, it is important to back-up original raw data. For a more detailed explanation of raw data, please refer to subsection [Directory Hierarchy for Raw Data](#directory-hierarchy-for-raw-data).
|
|
91
|
+
|
|
92
|
+
Most scripts take the configuration file in `toml` format, for specifying input data and some important parameters. An example config file, `example_config.toml` can be used as the template.
|
|
93
|
+
|
|
94
|
+
Example for supplying the config file: `python script_to_run.py -c config_file_path.toml`. If no input config is supplied, `config.toml` is used as the default path.
|
|
95
|
+
|
|
96
|
+
Most scripts also accepts list of inputs to be processed as a list of filepaths using `-f` or `--filepaths` switch. If no filepath is provided, scripts will open a UI to select one or multiple files for processing.
|
|
97
|
+
|
|
98
|
+
## Summary of important notebooks/scripts
|
|
99
|
+
|
|
100
|
+
### Following are under `examples/` directory:
|
|
101
|
+
|
|
102
|
+
`main_pilottone_extract.py`: This is the main script that loads the raw data, extracts pilot tone, and saves the extracted waveforms back into the same raw data as an MRD waveform. Later parts of this notebook assumes ECG is acquired in the raw data, so if it is not the case, one can also run the parts that extract pilot tone, without comparing to ECG. **Note:** This script provides a pipeline for a spiral acquisiton, as implemented here: [Real Time Spiral sequences in PyPulseq](https://github.com/usc-mrel/rtspiral_pypulseq). Can be used as a template for other type of acquisitions.
|
|
103
|
+
|
|
104
|
+
`main_editer_correct.py`: This script will process the raw data using EDITER and saves the corrected raw data.
|
|
105
|
+
|
|
106
|
+
`run_all.py`: A convenience script that applies pilot tone extraction and EDITER processing on the supplied raw data, and send the results to reconstruction server.
|
|
107
|
+
|
|
108
|
+
`main_process_reference.py`: Can be used to process raw data with no PT.
|
|
109
|
+
|
|
110
|
+
### Following are under `tools/` directory:
|
|
111
|
+
|
|
112
|
+
`respiratory_from_image.py`: From reconstructed images in MRD format, asks the user to place a line plot, which is then used for estimating respiratory waveform from the reconstructed images.
|
|
113
|
+
|
|
114
|
+
`remove_waveform.py`: Removes the waveforms with given ID from one or more MRD raw data files. You can pass files on the command line, including glob patterns, or select multiple files in the UI. It can also repack the data to reclaim space.
|
|
115
|
+
|
|
116
|
+
`truncate_acquisitions.py`: Truncates the raw data to shorten the acquisiton time.
|
|
117
|
+
|
|
118
|
+
-----
|
|
119
|
+
|
|
120
|
+
`send_to_recon_server.py`: This script is part of the package and also provides an entry point that can be called as `send_to_recon_server`. It configures and runs the MRD client, which in turn sends the waveforms and the raw data to the reconstruction server. This workflow requires the `mrd` extra. A server toolkit that includes some reconstructions, including several ones capable of processing pilot tone is provided [here](https://github.com/usc-mrel/python-ismrmrd-server).
|
|
121
|
+
|
|
122
|
+
There are several notebooks under `notebooks/` directory for mostly debugging or interactive usage purposes.
|
|
123
|
+
|
|
124
|
+
## Directory Hierarchy for Raw Data
|
|
125
|
+
|
|
126
|
+
The code expect raw data in the following hierarchy:
|
|
127
|
+
|
|
128
|
+
DATA_ROOT\
|
|
129
|
+
|- data_folder\
|
|
130
|
+
|- SEQUENCEHASH.mat
|
|
131
|
+
|- raw\
|
|
132
|
+
|- h5\
|
|
133
|
+
|- raw_file.h5
|
|
134
|
+
|- h5_proc\
|
|
135
|
+
|- raw_file_editer.h5
|
|
136
|
+
|- raw_file_ptsub.h5
|
|
137
|
+
|- noise\
|
|
138
|
+
|- noise_raw_file.h5
|
|
139
|
+
|
|
140
|
+
`SEQUENCEHASH.mat` is the metadata file generated during sequence design. Refer to [rtspiral_pypulseq](https://github.com/usc-mrel/rtspiral_pypulseq) for the details.
|
|
141
|
+
|
|
142
|
+
Processed raw data (either by EDITER or model subtraction) is put into `h5_proc` folder, with appropriate suffix to the file name.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# HAPTIC: High-amplitude Pilot Tone with Interference Cancellation
|
|
2
|
+
PylotToneMRI is a Python Toolbox with an emphasis on high-amplitude pilot tone applied to spiral MR imaging.
|
|
3
|
+
|
|
4
|
+
# Installation
|
|
5
|
+
|
|
6
|
+
Create an isolated environment using your favorite software (`uv`, `venv`, `conda`, etc.). This project provides an `uv.lock` for the exact replication of the environment via `uv`. Example for `venv`:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
python -m venv ${venv_name}
|
|
10
|
+
source ${venv_name}/bin/activate
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### For development:
|
|
14
|
+
Clone this repository and navigate into it:
|
|
15
|
+
```bash
|
|
16
|
+
git clone https://github.com/usc-mrel/PylotToneMRI.git
|
|
17
|
+
cd PylotToneMRI
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Install via `pip` in dev mode:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install -e .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If you need ISMRMRD file I/O, waveform injection, or reconstruction tooling, install the MRD extra:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install -e '.[mrd]'
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
To enable GPU acceleration for EDITER, install the optional GPU extra:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install -e '.[gpu]'
|
|
36
|
+
```
|
|
37
|
+
## For usage as a library:
|
|
38
|
+
|
|
39
|
+
It can be directly installed from `PyPI` via `pip`:
|
|
40
|
+
```bash
|
|
41
|
+
pip install pylottone
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If you need ISMRMRD-backed workflows from the GitHub install, use:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install 'pylottone[mrd]'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
If you want EDITER GPU support from the GitHub install, use:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install 'pylottone[gpu]'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Note:** Toolbox is only tested for Python>=3.11 and Python<=3.12.
|
|
57
|
+
|
|
58
|
+
### For ECG guided PT and fusion algorithm:
|
|
59
|
+
|
|
60
|
+
ECG guided PT extraction (`examples/main_pilottone_extract_exercise.py`) requires `torch` library, which can be installed separately before running the script.
|
|
61
|
+
|
|
62
|
+
# Usage
|
|
63
|
+
|
|
64
|
+
Most inputs and outputs are in [ISMRMRD](https://ismrmrd.readthedocs.io/en/latest/) format. Base `pylottone` installs now leave ISMRMRD optional; install `pylottone[mrd]` for MRD file I/O, waveform editing, and reconstruction tooling. Some scripts do modify the input raw data, so in case something goes wrong, it is important to back-up original raw data. For a more detailed explanation of raw data, please refer to subsection [Directory Hierarchy for Raw Data](#directory-hierarchy-for-raw-data).
|
|
65
|
+
|
|
66
|
+
Most scripts take the configuration file in `toml` format, for specifying input data and some important parameters. An example config file, `example_config.toml` can be used as the template.
|
|
67
|
+
|
|
68
|
+
Example for supplying the config file: `python script_to_run.py -c config_file_path.toml`. If no input config is supplied, `config.toml` is used as the default path.
|
|
69
|
+
|
|
70
|
+
Most scripts also accepts list of inputs to be processed as a list of filepaths using `-f` or `--filepaths` switch. If no filepath is provided, scripts will open a UI to select one or multiple files for processing.
|
|
71
|
+
|
|
72
|
+
## Summary of important notebooks/scripts
|
|
73
|
+
|
|
74
|
+
### Following are under `examples/` directory:
|
|
75
|
+
|
|
76
|
+
`main_pilottone_extract.py`: This is the main script that loads the raw data, extracts pilot tone, and saves the extracted waveforms back into the same raw data as an MRD waveform. Later parts of this notebook assumes ECG is acquired in the raw data, so if it is not the case, one can also run the parts that extract pilot tone, without comparing to ECG. **Note:** This script provides a pipeline for a spiral acquisiton, as implemented here: [Real Time Spiral sequences in PyPulseq](https://github.com/usc-mrel/rtspiral_pypulseq). Can be used as a template for other type of acquisitions.
|
|
77
|
+
|
|
78
|
+
`main_editer_correct.py`: This script will process the raw data using EDITER and saves the corrected raw data.
|
|
79
|
+
|
|
80
|
+
`run_all.py`: A convenience script that applies pilot tone extraction and EDITER processing on the supplied raw data, and send the results to reconstruction server.
|
|
81
|
+
|
|
82
|
+
`main_process_reference.py`: Can be used to process raw data with no PT.
|
|
83
|
+
|
|
84
|
+
### Following are under `tools/` directory:
|
|
85
|
+
|
|
86
|
+
`respiratory_from_image.py`: From reconstructed images in MRD format, asks the user to place a line plot, which is then used for estimating respiratory waveform from the reconstructed images.
|
|
87
|
+
|
|
88
|
+
`remove_waveform.py`: Removes the waveforms with given ID from one or more MRD raw data files. You can pass files on the command line, including glob patterns, or select multiple files in the UI. It can also repack the data to reclaim space.
|
|
89
|
+
|
|
90
|
+
`truncate_acquisitions.py`: Truncates the raw data to shorten the acquisiton time.
|
|
91
|
+
|
|
92
|
+
-----
|
|
93
|
+
|
|
94
|
+
`send_to_recon_server.py`: This script is part of the package and also provides an entry point that can be called as `send_to_recon_server`. It configures and runs the MRD client, which in turn sends the waveforms and the raw data to the reconstruction server. This workflow requires the `mrd` extra. A server toolkit that includes some reconstructions, including several ones capable of processing pilot tone is provided [here](https://github.com/usc-mrel/python-ismrmrd-server).
|
|
95
|
+
|
|
96
|
+
There are several notebooks under `notebooks/` directory for mostly debugging or interactive usage purposes.
|
|
97
|
+
|
|
98
|
+
## Directory Hierarchy for Raw Data
|
|
99
|
+
|
|
100
|
+
The code expect raw data in the following hierarchy:
|
|
101
|
+
|
|
102
|
+
DATA_ROOT\
|
|
103
|
+
|- data_folder\
|
|
104
|
+
|- SEQUENCEHASH.mat
|
|
105
|
+
|- raw\
|
|
106
|
+
|- h5\
|
|
107
|
+
|- raw_file.h5
|
|
108
|
+
|- h5_proc\
|
|
109
|
+
|- raw_file_editer.h5
|
|
110
|
+
|- raw_file_ptsub.h5
|
|
111
|
+
|- noise\
|
|
112
|
+
|- noise_raw_file.h5
|
|
113
|
+
|
|
114
|
+
`SEQUENCEHASH.mat` is the metadata file generated during sequence design. Refer to [rtspiral_pypulseq](https://github.com/usc-mrel/rtspiral_pypulseq) for the details.
|
|
115
|
+
|
|
116
|
+
Processed raw data (either by EDITER or model subtraction) is put into `h5_proc` folder, with appropriate suffix to the file name.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
name: pilottone
|
|
2
|
+
channels:
|
|
3
|
+
- ismrmrd
|
|
4
|
+
- conda-forge
|
|
5
|
+
- defaults
|
|
6
|
+
dependencies:
|
|
7
|
+
- python=3.12
|
|
8
|
+
- ismrmrd::ismrmrd-python=1.14.1
|
|
9
|
+
- ismrmrd::siemens_to_ismrmrd=1.2.12
|
|
10
|
+
- boost=1.80.0 # For ismrmrd
|
|
11
|
+
- libxml2=2.10.3 # For ismrmrd
|
|
12
|
+
- h5py=3.7.0 # For ismrmrd
|
|
13
|
+
- matplotlib=3.8.4 # used by rgb.py and provides various visualization tools including colormaps
|
|
14
|
+
- numpy=1.26.4
|
|
15
|
+
- pyside2=5.15.5 # For UI in respiratory_from_image.py
|
|
16
|
+
- git
|
|
17
|
+
- ipykernel
|
|
18
|
+
- pandas
|
|
19
|
+
- pyfftw
|
|
20
|
+
- hyperspy
|
|
21
|
+
- pip
|
|
22
|
+
- cupy # For GPU acceleration at EDITER processing.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# File Path config
|
|
2
|
+
data_folder = ""
|
|
3
|
+
DATA_ROOT = "/"
|
|
4
|
+
|
|
5
|
+
# Reconstruction control
|
|
6
|
+
[reconstruction]
|
|
7
|
+
recon_type = "viewsharing" # 'viewsharing', 'ttv', 'xdgrasp'
|
|
8
|
+
server_port = 9028 # Port that server is currently running on.
|
|
9
|
+
show_images = true # Whether or not to show images after reconstruction.
|
|
10
|
+
output_folder = "output_recons"
|
|
11
|
+
|
|
12
|
+
# EDITER control
|
|
13
|
+
[editer]
|
|
14
|
+
prewhiten = true
|
|
15
|
+
autosniffer_select = false
|
|
16
|
+
sensing_coils = [1, 15, 16, 17] # Coils to use for sensing.
|
|
17
|
+
gpu_device = 1 # GPU device to use for EDITER, -1 for CPU.
|
|
18
|
+
# Note: If the configured GPU is unavailable or CuPy is not installed,
|
|
19
|
+
# the EDITER implementation will automatically fall back to the CPU path.
|
|
20
|
+
interference_freq = 24e6 # Frequency of the interference signal, to be used in autosniffer_select.
|
|
21
|
+
denoise_rank = 1 # Number of singular components to keep for per-window sniffer denoising.
|
|
22
|
+
|
|
23
|
+
[pilottone]
|
|
24
|
+
pt_freq = 24e6
|
|
25
|
+
prewhiten = true
|
|
26
|
+
discard_badcoils = true # Uses the same algorithm as autosniffer_select to discard bad coils.
|
|
27
|
+
sensing_coils = [15, 16, 17] # Coils to use for sensing.
|
|
28
|
+
show_outputs = false # Whether or not to show the outputs of the pilottone extraction.
|
|
29
|
+
golay_filter_len = 81 # Golay filter length for initial denoising.
|
|
30
|
+
source_selection_method = "spectral" # "spectral" or "model" for SOBI navigator source selection.
|
|
31
|
+
|
|
32
|
+
[pilottone.model_source_selection]
|
|
33
|
+
force_navpred = true # Force one respiratory and one cardiac source when using model source selection.
|
|
34
|
+
# classifier_path = "" # Optional path to a custom joblib-compatible navigator classifier.
|
|
35
|
+
|
|
36
|
+
[pilottone.respiratory]
|
|
37
|
+
freq_start = 0.05 # [Hz] Lower frequency limit for respiratory bandpass filter
|
|
38
|
+
freq_stop = 0.9 # [Hz] Upper frequency limit for respiratory bandpass filter
|
|
39
|
+
corr_threshold = 0.9 # Correlation threshold for respiratory coil selection
|
|
40
|
+
initial_channel = -1 # Initial guess for the respiratory coil selection
|
|
41
|
+
separation_method = "sobi" # SOBI or PCA
|
|
42
|
+
|
|
43
|
+
[pilottone.cardiac]
|
|
44
|
+
freq_start = 1 # [Hz] Lower frequency limit for cardiac bandpass filter
|
|
45
|
+
freq_stop = 20 # [Hz] Upper frequency limit for cardiac bandpass filter
|
|
46
|
+
corr_threshold = 0.9 # Correlation threshold for cardiac coil selection
|
|
47
|
+
initial_channel = 'Body_6:1:B13' # Initial guess for the cardiac coil selection
|
|
48
|
+
separation_method = "pca" # SOBI or PCA
|
|
49
|
+
sign = 1 # When cardiac signal is not stable enough, sign detection fails. This will flip the signal in case cardiac signal is flipped.
|
|
50
|
+
|
|
51
|
+
[pilottone.debug]
|
|
52
|
+
selected_coils = [0,1]
|
|
53
|
+
show_plots = false
|
|
54
|
+
no_normalize = true
|
|
55
|
+
|
|
56
|
+
[saving]
|
|
57
|
+
remove_os = false # Remove 2x oversampling when saving the raw data
|
|
58
|
+
save_model_subtracted = false # Whether or not to save PT model subtracted data in main_pilottone_extract script.
|
|
59
|
+
save_pt_waveforms = false # Whether or not to save pilottone waveforms in main_pilottone_extract script.
|
|
60
|
+
save_pt_separate = true # Whether or not to save pilottone waveforms in separate npz files.
|