lbm_caiman_python 0.2.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.
- lbm_caiman_python-0.2.0/LICENSE.md +38 -0
- lbm_caiman_python-0.2.0/PKG-INFO +161 -0
- lbm_caiman_python-0.2.0/README.md +129 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/__init__.py +63 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/__main__.py +302 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/_version.py +8 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/batch.py +188 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/collation.py +125 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/default_ops.py +92 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/gui/__init__.py +3 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/gui/_store_model.py +170 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/gui/rungui.py +13 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/gui/widgets.py +114 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/helpers.py +262 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/postprocessing.py +319 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/run_lcp.py +1059 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/stdout.py +3 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/summary.py +569 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/util/__init__.py +87 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/util/exceptions.py +6 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/util/quality.py +366 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/util/signal.py +17 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/util/transform.py +208 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python/visualize.py +522 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/PKG-INFO +161 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/SOURCES.txt +30 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/dependency_links.txt +1 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/entry_points.txt +2 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/requires.txt +14 -0
- lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/top_level.txt +1 -0
- lbm_caiman_python-0.2.0/pyproject.toml +110 -0
- lbm_caiman_python-0.2.0/setup.cfg +4 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
This software license is the 3-clause BSD license plus a fourth clause that
|
|
2
|
+
prohibits redistribution for commercial purposes without further permission.
|
|
3
|
+
|
|
4
|
+
BSD 3-Clause License
|
|
5
|
+
|
|
6
|
+
Copyright (c) 2024, Miller Brain Observatory.
|
|
7
|
+
|
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
|
9
|
+
modification, are permitted provided that the following conditions are met:
|
|
10
|
+
|
|
11
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
12
|
+
list of conditions and the following disclaimer.
|
|
13
|
+
|
|
14
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
15
|
+
this list of conditions and the following disclaimer in the documentation
|
|
16
|
+
and/or other materials provided with the distribution.
|
|
17
|
+
|
|
18
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
19
|
+
contributors may be used to endorse or promote products derived from
|
|
20
|
+
this software without specific prior written permission.
|
|
21
|
+
|
|
22
|
+
4. Redistributions for commercial purposes are not permitted without the
|
|
23
|
+
written permission of all code authors.
|
|
24
|
+
For purposes of this license, commercial purposes is the incorporation of
|
|
25
|
+
LBM-CaImAn-Python into anything for which you will charge fees or other
|
|
26
|
+
compensation. Contact mbo@rockefeller.edu for more information.
|
|
27
|
+
|
|
28
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
29
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
30
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
31
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
32
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
33
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
34
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
35
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
36
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
37
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
38
|
+
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lbm_caiman_python
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Light Beads Microscopy Pipeline using CaImAn
|
|
5
|
+
License-Expression: BSD-3-Clause
|
|
6
|
+
Project-URL: Homepage, https://github.com/MillerBrainObservatory/LBM-CaImAn-Python
|
|
7
|
+
Project-URL: Documentation, https://millerbrainobservatory.github.io/LBM-CaImAn-Python
|
|
8
|
+
Project-URL: Repository, https://github.com/MillerBrainObservatory/LBM-CaImAn-Python
|
|
9
|
+
Project-URL: Issues, https://github.com/MillerBrainObservatory/LBM-CaImAn-Python/issues
|
|
10
|
+
Keywords: Pipeline,Numpy,Microscopy,ScanImage,CaImAn,tiff,calcium imaging
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Requires-Python: <3.12.10,>=3.12.7
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE.md
|
|
17
|
+
Requires-Dist: numpy
|
|
18
|
+
Requires-Dist: scipy>=1.10
|
|
19
|
+
Requires-Dist: scikit-learn
|
|
20
|
+
Requires-Dist: scikit-image
|
|
21
|
+
Requires-Dist: joblib
|
|
22
|
+
Requires-Dist: tqdm
|
|
23
|
+
Requires-Dist: matplotlib
|
|
24
|
+
Requires-Dist: tifffile
|
|
25
|
+
Requires-Dist: h5py
|
|
26
|
+
Requires-Dist: zarr
|
|
27
|
+
Requires-Dist: dask
|
|
28
|
+
Requires-Dist: pandas
|
|
29
|
+
Requires-Dist: mbo_utilities>=3.1.0
|
|
30
|
+
Requires-Dist: lbm_suite2p_python
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# LBM-CaImAn-Python
|
|
34
|
+
|
|
35
|
+
[**Installation**](https://github.com/MillerBrainObservatory/LBM-CaImAn-Python#installation) | [**Notebooks**](https://github.com/MillerBrainObservatory/LBM-CaImAn-Python/tree/master/demos/notebooks)
|
|
36
|
+
|
|
37
|
+
[](https://millerbrainobservatory.github.io/LBM-CaImAn-Python/)
|
|
38
|
+
|
|
39
|
+
Python implementation of the Light Beads Microscopy (LBM) computational pipeline. The documentation has examples of the rendered notebooks.
|
|
40
|
+
|
|
41
|
+
For the `MATLAB` implementation, see [here](https://github.com/MillerBrainObservatory/LBM-CaImAn-MATLAB/)
|
|
42
|
+
|
|
43
|
+
## Pipeline Steps:
|
|
44
|
+
|
|
45
|
+
1. Image Assembly
|
|
46
|
+
- Extract raw `tiffs` to planar timeseries
|
|
47
|
+
2. Motion Correction
|
|
48
|
+
- Rigid/Non-rigid registration
|
|
49
|
+
3. Segmentation
|
|
50
|
+
- Iterative CNMF segmentation
|
|
51
|
+
- Deconvolution
|
|
52
|
+
- Refine neuron selection
|
|
53
|
+
4. Collation
|
|
54
|
+
- Collate images and metadata into a single volume
|
|
55
|
+
- Lateral offset correction (between z-planes. WIP)
|
|
56
|
+
|
|
57
|
+
## Requirements
|
|
58
|
+
|
|
59
|
+
- caiman
|
|
60
|
+
- numpy
|
|
61
|
+
- scipy
|
|
62
|
+
- fastplotlib
|
|
63
|
+
|
|
64
|
+
:exclamation: **Note:** This package makes heavy use of fastplotlib for visualizations.
|
|
65
|
+
|
|
66
|
+
fastplotlib runs on [Jupyter Lab](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html),
|
|
67
|
+
but is not guarenteed to work with Jupyter Notebook or Visual Studio Code notebook environments.
|
|
68
|
+
|
|
69
|
+
## Installation
|
|
70
|
+
|
|
71
|
+
Install [pixi](https://pixi.sh) (`pip install pixi` or see https://pixi.sh for other methods), then:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git clone https://github.com/MillerBrainObservatory/LBM-CaImAn-Python.git
|
|
75
|
+
cd LBM-CaImAn-Python
|
|
76
|
+
pixi install
|
|
77
|
+
pixi run setup-caiman
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This installs CaImAn from conda-forge along with all dependencies and the project itself in editable mode.
|
|
81
|
+
|
|
82
|
+
To verify:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pixi run python -c "import lbm_caiman_python as lcp; print(lcp.__version__)"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
:exclamation: **Hardware requirements** The large CNMF visualizations with contours etc. usually require either a dedicated GPU or integrated GPU with access to at least 1GB of VRAM.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Troubleshooting
|
|
93
|
+
|
|
94
|
+
### Error during pip install: OSError: [Errno 2] No such file or directory
|
|
95
|
+
|
|
96
|
+
If you recieve an error during pip installation with the hint:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
|
|
100
|
+
HINT: This error might have occurred since this system does not have Windows Long Path support enabled. You can find
|
|
101
|
+
information on how to enable this at https://pip.pypa.io/warnings/enable-long-paths
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
In Windows Powershell, as Administrator:
|
|
106
|
+
|
|
107
|
+
`New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force`
|
|
108
|
+
|
|
109
|
+
Or:
|
|
110
|
+
|
|
111
|
+
- Open Group Policy Editor (Press Windows Key and type gpedit.msc and hit Enter key.
|
|
112
|
+
|
|
113
|
+
- Navigate to the following directory:
|
|
114
|
+
|
|
115
|
+
`Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem > NTFS.`
|
|
116
|
+
|
|
117
|
+
- Click Enable NTFS long paths option and enable it.
|
|
118
|
+
|
|
119
|
+
### Conda Slow / Stalling
|
|
120
|
+
|
|
121
|
+
if conda is behaving slow, clean the conda installation and update `conda-forge`:
|
|
122
|
+
|
|
123
|
+
``` bash
|
|
124
|
+
|
|
125
|
+
conda clean -a
|
|
126
|
+
|
|
127
|
+
conda update -c conda-forge --all
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### virtualenv Troubleshooting
|
|
132
|
+
|
|
133
|
+
#### Error During `pip install .` (CaImAn) on Linux
|
|
134
|
+
If you encounter errors during the installation of `CaImAn`, install the necessary development tools:
|
|
135
|
+
```bash
|
|
136
|
+
sudo apt-get install python3-dev
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Don't forget to press enter a few times if conda is taking a long time.
|
|
140
|
+
|
|
141
|
+
### Recommended Conda Distribution
|
|
142
|
+
|
|
143
|
+
The recommended conda installer is
|
|
144
|
+
|
|
145
|
+
This is a community-driven `conda`/`mamba` installer with pre-configured packages specific to [conda-forge](https://conda-forge.org/).
|
|
146
|
+
|
|
147
|
+
This helps avoid `conda-channel` conflicts and avoids any issues with the Anaconda TOS.
|
|
148
|
+
|
|
149
|
+
You can install the installer from a unix command line:
|
|
150
|
+
|
|
151
|
+
``` bash
|
|
152
|
+
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
|
|
153
|
+
bash Miniforge3-$(uname)-$(uname -m).sh
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Or download the installer for your operating system [here](https://github.com/conda-forge/miniforge/releases).
|
|
157
|
+
|
|
158
|
+
### Graphics Driver Issues
|
|
159
|
+
|
|
160
|
+
If you are attempting to use fastplotlib and receive errors about graphics drivers, see the [fastplotlib driver documentation](https://github.com/fastplotlib/fastplotlib?tab=readme-ov-file#gpu-drivers-and-requirements).
|
|
161
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# LBM-CaImAn-Python
|
|
2
|
+
|
|
3
|
+
[**Installation**](https://github.com/MillerBrainObservatory/LBM-CaImAn-Python#installation) | [**Notebooks**](https://github.com/MillerBrainObservatory/LBM-CaImAn-Python/tree/master/demos/notebooks)
|
|
4
|
+
|
|
5
|
+
[](https://millerbrainobservatory.github.io/LBM-CaImAn-Python/)
|
|
6
|
+
|
|
7
|
+
Python implementation of the Light Beads Microscopy (LBM) computational pipeline. The documentation has examples of the rendered notebooks.
|
|
8
|
+
|
|
9
|
+
For the `MATLAB` implementation, see [here](https://github.com/MillerBrainObservatory/LBM-CaImAn-MATLAB/)
|
|
10
|
+
|
|
11
|
+
## Pipeline Steps:
|
|
12
|
+
|
|
13
|
+
1. Image Assembly
|
|
14
|
+
- Extract raw `tiffs` to planar timeseries
|
|
15
|
+
2. Motion Correction
|
|
16
|
+
- Rigid/Non-rigid registration
|
|
17
|
+
3. Segmentation
|
|
18
|
+
- Iterative CNMF segmentation
|
|
19
|
+
- Deconvolution
|
|
20
|
+
- Refine neuron selection
|
|
21
|
+
4. Collation
|
|
22
|
+
- Collate images and metadata into a single volume
|
|
23
|
+
- Lateral offset correction (between z-planes. WIP)
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- caiman
|
|
28
|
+
- numpy
|
|
29
|
+
- scipy
|
|
30
|
+
- fastplotlib
|
|
31
|
+
|
|
32
|
+
:exclamation: **Note:** This package makes heavy use of fastplotlib for visualizations.
|
|
33
|
+
|
|
34
|
+
fastplotlib runs on [Jupyter Lab](https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html),
|
|
35
|
+
but is not guarenteed to work with Jupyter Notebook or Visual Studio Code notebook environments.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
Install [pixi](https://pixi.sh) (`pip install pixi` or see https://pixi.sh for other methods), then:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/MillerBrainObservatory/LBM-CaImAn-Python.git
|
|
43
|
+
cd LBM-CaImAn-Python
|
|
44
|
+
pixi install
|
|
45
|
+
pixi run setup-caiman
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
This installs CaImAn from conda-forge along with all dependencies and the project itself in editable mode.
|
|
49
|
+
|
|
50
|
+
To verify:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pixi run python -c "import lbm_caiman_python as lcp; print(lcp.__version__)"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
:exclamation: **Hardware requirements** The large CNMF visualizations with contours etc. usually require either a dedicated GPU or integrated GPU with access to at least 1GB of VRAM.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Troubleshooting
|
|
61
|
+
|
|
62
|
+
### Error during pip install: OSError: [Errno 2] No such file or directory
|
|
63
|
+
|
|
64
|
+
If you recieve an error during pip installation with the hint:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
|
|
68
|
+
HINT: This error might have occurred since this system does not have Windows Long Path support enabled. You can find
|
|
69
|
+
information on how to enable this at https://pip.pypa.io/warnings/enable-long-paths
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
In Windows Powershell, as Administrator:
|
|
74
|
+
|
|
75
|
+
`New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force`
|
|
76
|
+
|
|
77
|
+
Or:
|
|
78
|
+
|
|
79
|
+
- Open Group Policy Editor (Press Windows Key and type gpedit.msc and hit Enter key.
|
|
80
|
+
|
|
81
|
+
- Navigate to the following directory:
|
|
82
|
+
|
|
83
|
+
`Local Computer Policy > Computer Configuration > Administrative Templates > System > Filesystem > NTFS.`
|
|
84
|
+
|
|
85
|
+
- Click Enable NTFS long paths option and enable it.
|
|
86
|
+
|
|
87
|
+
### Conda Slow / Stalling
|
|
88
|
+
|
|
89
|
+
if conda is behaving slow, clean the conda installation and update `conda-forge`:
|
|
90
|
+
|
|
91
|
+
``` bash
|
|
92
|
+
|
|
93
|
+
conda clean -a
|
|
94
|
+
|
|
95
|
+
conda update -c conda-forge --all
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### virtualenv Troubleshooting
|
|
100
|
+
|
|
101
|
+
#### Error During `pip install .` (CaImAn) on Linux
|
|
102
|
+
If you encounter errors during the installation of `CaImAn`, install the necessary development tools:
|
|
103
|
+
```bash
|
|
104
|
+
sudo apt-get install python3-dev
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Don't forget to press enter a few times if conda is taking a long time.
|
|
108
|
+
|
|
109
|
+
### Recommended Conda Distribution
|
|
110
|
+
|
|
111
|
+
The recommended conda installer is
|
|
112
|
+
|
|
113
|
+
This is a community-driven `conda`/`mamba` installer with pre-configured packages specific to [conda-forge](https://conda-forge.org/).
|
|
114
|
+
|
|
115
|
+
This helps avoid `conda-channel` conflicts and avoids any issues with the Anaconda TOS.
|
|
116
|
+
|
|
117
|
+
You can install the installer from a unix command line:
|
|
118
|
+
|
|
119
|
+
``` bash
|
|
120
|
+
curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
|
|
121
|
+
bash Miniforge3-$(uname)-$(uname -m).sh
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Or download the installer for your operating system [here](https://github.com/conda-forge/miniforge/releases).
|
|
125
|
+
|
|
126
|
+
### Graphics Driver Issues
|
|
127
|
+
|
|
128
|
+
If you are attempting to use fastplotlib and receive errors about graphics drivers, see the [fastplotlib driver documentation](https://github.com/fastplotlib/fastplotlib?tab=readme-ov-file#gpu-drivers-and-requirements).
|
|
129
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from . import _version
|
|
2
|
+
|
|
3
|
+
# core pipeline api
|
|
4
|
+
from .default_ops import default_ops, mcorr_ops, cnmf_ops
|
|
5
|
+
from .run_lcp import (
|
|
6
|
+
pipeline,
|
|
7
|
+
run_volume,
|
|
8
|
+
run_plane,
|
|
9
|
+
add_processing_step,
|
|
10
|
+
generate_plane_dirname,
|
|
11
|
+
)
|
|
12
|
+
from .postprocessing import (
|
|
13
|
+
load_ops,
|
|
14
|
+
load_planar_results,
|
|
15
|
+
dff_rolling_percentile,
|
|
16
|
+
compute_roi_stats,
|
|
17
|
+
get_accepted_cells,
|
|
18
|
+
get_contours,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# existing utilities
|
|
22
|
+
from .collation import combine_z_planes
|
|
23
|
+
from .util.transform import vectorize, unvectorize, calculate_centers
|
|
24
|
+
from .util.quality import get_noise_fft, greedyROI
|
|
25
|
+
from .util.signal import smooth_data, norm_minmax
|
|
26
|
+
from .helpers import (
|
|
27
|
+
generate_patch_view,
|
|
28
|
+
get_single_patch_coords,
|
|
29
|
+
extract_center_square,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
__version__ = _version.get_versions()['version']
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
# core pipeline
|
|
36
|
+
"pipeline",
|
|
37
|
+
"run_volume",
|
|
38
|
+
"run_plane",
|
|
39
|
+
"default_ops",
|
|
40
|
+
"mcorr_ops",
|
|
41
|
+
"cnmf_ops",
|
|
42
|
+
"add_processing_step",
|
|
43
|
+
"generate_plane_dirname",
|
|
44
|
+
|
|
45
|
+
# postprocessing
|
|
46
|
+
"load_ops",
|
|
47
|
+
"load_planar_results",
|
|
48
|
+
"dff_rolling_percentile",
|
|
49
|
+
"compute_roi_stats",
|
|
50
|
+
"get_accepted_cells",
|
|
51
|
+
"get_contours",
|
|
52
|
+
|
|
53
|
+
# existing utilities
|
|
54
|
+
"combine_z_planes",
|
|
55
|
+
"generate_patch_view",
|
|
56
|
+
"get_noise_fft",
|
|
57
|
+
"calculate_centers",
|
|
58
|
+
"greedyROI",
|
|
59
|
+
"get_single_patch_coords",
|
|
60
|
+
"extract_center_square",
|
|
61
|
+
"smooth_data",
|
|
62
|
+
"norm_minmax",
|
|
63
|
+
]
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
"""
|
|
2
|
+
cli entry point for lbm-caiman-python.
|
|
3
|
+
|
|
4
|
+
usage:
|
|
5
|
+
lcp <input> <output> [options]
|
|
6
|
+
python -m lbm_caiman_python <input> <output> [options]
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import sys
|
|
11
|
+
from functools import partial
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
print = partial(print, flush=True)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def add_args(parser: argparse.ArgumentParser):
|
|
18
|
+
"""add command-line arguments to the parser."""
|
|
19
|
+
from lbm_caiman_python.default_ops import default_ops
|
|
20
|
+
|
|
21
|
+
defaults = default_ops()
|
|
22
|
+
|
|
23
|
+
# positional arguments
|
|
24
|
+
parser.add_argument(
|
|
25
|
+
"input",
|
|
26
|
+
type=str,
|
|
27
|
+
nargs="?",
|
|
28
|
+
default=None,
|
|
29
|
+
help="Input file or directory",
|
|
30
|
+
)
|
|
31
|
+
parser.add_argument(
|
|
32
|
+
"output",
|
|
33
|
+
type=str,
|
|
34
|
+
nargs="?",
|
|
35
|
+
default=None,
|
|
36
|
+
help="Output directory",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# processing flags
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"--planes",
|
|
42
|
+
type=int,
|
|
43
|
+
nargs="+",
|
|
44
|
+
default=None,
|
|
45
|
+
help="Planes to process (1-based)",
|
|
46
|
+
)
|
|
47
|
+
parser.add_argument(
|
|
48
|
+
"--no-mcorr",
|
|
49
|
+
action="store_true",
|
|
50
|
+
help="Skip motion correction",
|
|
51
|
+
)
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
"--no-cnmf",
|
|
54
|
+
action="store_true",
|
|
55
|
+
help="Skip CNMF",
|
|
56
|
+
)
|
|
57
|
+
parser.add_argument(
|
|
58
|
+
"--force-mcorr",
|
|
59
|
+
action="store_true",
|
|
60
|
+
help="Force re-run motion correction",
|
|
61
|
+
)
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
"--force-cnmf",
|
|
64
|
+
action="store_true",
|
|
65
|
+
help="Force re-run CNMF",
|
|
66
|
+
)
|
|
67
|
+
parser.add_argument(
|
|
68
|
+
"--num-frames",
|
|
69
|
+
type=int,
|
|
70
|
+
default=None,
|
|
71
|
+
help="Limit number of frames to process",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
# motion correction parameters
|
|
75
|
+
parser.add_argument(
|
|
76
|
+
"--max-shifts",
|
|
77
|
+
type=int,
|
|
78
|
+
nargs=2,
|
|
79
|
+
default=None,
|
|
80
|
+
help=f"Maximum rigid shifts (default: {defaults['max_shifts']})",
|
|
81
|
+
)
|
|
82
|
+
parser.add_argument(
|
|
83
|
+
"--strides",
|
|
84
|
+
type=int,
|
|
85
|
+
nargs=2,
|
|
86
|
+
default=None,
|
|
87
|
+
help=f"Patch strides for piecewise-rigid (default: {defaults['strides']})",
|
|
88
|
+
)
|
|
89
|
+
parser.add_argument(
|
|
90
|
+
"--overlaps",
|
|
91
|
+
type=int,
|
|
92
|
+
nargs=2,
|
|
93
|
+
default=None,
|
|
94
|
+
help=f"Patch overlaps (default: {defaults['overlaps']})",
|
|
95
|
+
)
|
|
96
|
+
parser.add_argument(
|
|
97
|
+
"--gSig-filt",
|
|
98
|
+
type=int,
|
|
99
|
+
nargs=2,
|
|
100
|
+
default=None,
|
|
101
|
+
help=f"Gaussian filter size (default: {defaults['gSig_filt']})",
|
|
102
|
+
)
|
|
103
|
+
parser.add_argument(
|
|
104
|
+
"--no-pw-rigid",
|
|
105
|
+
action="store_true",
|
|
106
|
+
help="Disable piecewise-rigid correction (use rigid only)",
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
# cnmf parameters
|
|
110
|
+
parser.add_argument(
|
|
111
|
+
"--K",
|
|
112
|
+
type=int,
|
|
113
|
+
default=None,
|
|
114
|
+
help=f"Expected number of neurons (default: {defaults['K']})",
|
|
115
|
+
)
|
|
116
|
+
parser.add_argument(
|
|
117
|
+
"--gSig",
|
|
118
|
+
type=int,
|
|
119
|
+
nargs=2,
|
|
120
|
+
default=None,
|
|
121
|
+
help=f"Expected neuron half-width (default: {defaults['gSig']})",
|
|
122
|
+
)
|
|
123
|
+
parser.add_argument(
|
|
124
|
+
"--min-SNR",
|
|
125
|
+
type=float,
|
|
126
|
+
default=None,
|
|
127
|
+
help=f"Minimum SNR threshold (default: {defaults['min_SNR']})",
|
|
128
|
+
)
|
|
129
|
+
parser.add_argument(
|
|
130
|
+
"--rval-thr",
|
|
131
|
+
type=float,
|
|
132
|
+
default=None,
|
|
133
|
+
help=f"Correlation threshold (default: {defaults['rval_thr']})",
|
|
134
|
+
)
|
|
135
|
+
parser.add_argument(
|
|
136
|
+
"--merge-thresh",
|
|
137
|
+
type=float,
|
|
138
|
+
default=None,
|
|
139
|
+
help=f"Merging threshold (default: {defaults['merge_thresh']})",
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# general parameters
|
|
143
|
+
parser.add_argument(
|
|
144
|
+
"--fr",
|
|
145
|
+
type=float,
|
|
146
|
+
default=None,
|
|
147
|
+
help=f"Frame rate in Hz (default: {defaults['fr']})",
|
|
148
|
+
)
|
|
149
|
+
parser.add_argument(
|
|
150
|
+
"--n-processes",
|
|
151
|
+
type=int,
|
|
152
|
+
default=None,
|
|
153
|
+
help="Number of parallel processes (default: auto)",
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# utility flags
|
|
157
|
+
parser.add_argument(
|
|
158
|
+
"--version",
|
|
159
|
+
action="store_true",
|
|
160
|
+
help="Show version information",
|
|
161
|
+
)
|
|
162
|
+
parser.add_argument(
|
|
163
|
+
"--debug",
|
|
164
|
+
action="store_true",
|
|
165
|
+
help="Enable debug mode",
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
return parser
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def build_ops_from_args(args) -> dict:
|
|
172
|
+
"""build ops dictionary from command-line arguments."""
|
|
173
|
+
from lbm_caiman_python.default_ops import default_ops
|
|
174
|
+
|
|
175
|
+
ops = default_ops()
|
|
176
|
+
|
|
177
|
+
# map cli args to ops keys
|
|
178
|
+
arg_to_ops = {
|
|
179
|
+
"max_shifts": "max_shifts",
|
|
180
|
+
"strides": "strides",
|
|
181
|
+
"overlaps": "overlaps",
|
|
182
|
+
"gSig_filt": "gSig_filt",
|
|
183
|
+
"K": "K",
|
|
184
|
+
"gSig": "gSig",
|
|
185
|
+
"min_SNR": "min_SNR",
|
|
186
|
+
"rval_thr": "rval_thr",
|
|
187
|
+
"merge_thresh": "merge_thresh",
|
|
188
|
+
"fr": "fr",
|
|
189
|
+
"n_processes": "n_processes",
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for arg_name, ops_key in arg_to_ops.items():
|
|
193
|
+
value = getattr(args, arg_name.replace("-", "_"), None)
|
|
194
|
+
if value is not None:
|
|
195
|
+
if isinstance(value, list) and len(value) == 2:
|
|
196
|
+
ops[ops_key] = tuple(value)
|
|
197
|
+
else:
|
|
198
|
+
ops[ops_key] = value
|
|
199
|
+
|
|
200
|
+
# handle boolean flags
|
|
201
|
+
if args.no_mcorr:
|
|
202
|
+
ops["do_motion_correction"] = False
|
|
203
|
+
if args.no_cnmf:
|
|
204
|
+
ops["do_cnmf"] = False
|
|
205
|
+
if args.no_pw_rigid:
|
|
206
|
+
ops["pw_rigid"] = False
|
|
207
|
+
|
|
208
|
+
return ops
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def main():
|
|
212
|
+
"""main cli entry point."""
|
|
213
|
+
print("\n")
|
|
214
|
+
print("--- LBM-CaImAn Pipeline ---")
|
|
215
|
+
print("\n")
|
|
216
|
+
|
|
217
|
+
parser = argparse.ArgumentParser(
|
|
218
|
+
description="LBM-CaImAn processing pipeline",
|
|
219
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
220
|
+
epilog="""
|
|
221
|
+
examples:
|
|
222
|
+
lcp data.tiff output/
|
|
223
|
+
lcp data/ results/ --planes 1 2 3
|
|
224
|
+
lcp movie.tif results/ --K 100 --gSig 5 5
|
|
225
|
+
lcp data.tiff output/ --no-mcorr # skip motion correction
|
|
226
|
+
""",
|
|
227
|
+
)
|
|
228
|
+
parser = add_args(parser)
|
|
229
|
+
args = parser.parse_args()
|
|
230
|
+
|
|
231
|
+
# handle version
|
|
232
|
+
if args.version:
|
|
233
|
+
import lbm_caiman_python
|
|
234
|
+
print(f"lbm_caiman_python v{lbm_caiman_python.__version__}")
|
|
235
|
+
return
|
|
236
|
+
|
|
237
|
+
# check required arguments
|
|
238
|
+
if args.input is None:
|
|
239
|
+
parser.print_help()
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
# setup logging
|
|
243
|
+
if args.debug:
|
|
244
|
+
import logging
|
|
245
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
246
|
+
print("Debug mode enabled.")
|
|
247
|
+
|
|
248
|
+
# validate input
|
|
249
|
+
input_path = Path(args.input).expanduser().resolve()
|
|
250
|
+
if not input_path.exists():
|
|
251
|
+
print(f"Error: Input path does not exist: {input_path}")
|
|
252
|
+
sys.exit(1)
|
|
253
|
+
|
|
254
|
+
# setup output
|
|
255
|
+
if args.output is None:
|
|
256
|
+
output_path = input_path.parent / (input_path.stem + "_caiman_results")
|
|
257
|
+
else:
|
|
258
|
+
output_path = Path(args.output).expanduser().resolve()
|
|
259
|
+
|
|
260
|
+
print(f"Input: {input_path}")
|
|
261
|
+
print(f"Output: {output_path}")
|
|
262
|
+
|
|
263
|
+
# build ops from arguments
|
|
264
|
+
ops = build_ops_from_args(args)
|
|
265
|
+
|
|
266
|
+
# run pipeline
|
|
267
|
+
from lbm_caiman_python.run_lcp import pipeline
|
|
268
|
+
|
|
269
|
+
try:
|
|
270
|
+
results = pipeline(
|
|
271
|
+
input_data=input_path,
|
|
272
|
+
save_path=str(output_path),
|
|
273
|
+
ops=ops,
|
|
274
|
+
planes=args.planes,
|
|
275
|
+
force_mcorr=args.force_mcorr,
|
|
276
|
+
force_cnmf=args.force_cnmf,
|
|
277
|
+
num_timepoints=args.num_frames,
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
print("\n")
|
|
281
|
+
print("--- Processing Complete ---")
|
|
282
|
+
print(f"Results saved to: {output_path}")
|
|
283
|
+
print(f"Processed {len(results)} plane(s)")
|
|
284
|
+
|
|
285
|
+
# print summary
|
|
286
|
+
for ops_path in results:
|
|
287
|
+
from lbm_caiman_python.postprocessing import load_ops
|
|
288
|
+
ops_result = load_ops(ops_path)
|
|
289
|
+
plane = ops_result.get("plane", "?")
|
|
290
|
+
n_cells = ops_result.get("n_cells", 0)
|
|
291
|
+
print(f" Plane {plane}: {n_cells} cells")
|
|
292
|
+
|
|
293
|
+
except Exception as e:
|
|
294
|
+
print(f"\nError: {e}")
|
|
295
|
+
if args.debug:
|
|
296
|
+
import traceback
|
|
297
|
+
traceback.print_exc()
|
|
298
|
+
sys.exit(1)
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
if __name__ == "__main__":
|
|
302
|
+
main()
|