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.
Files changed (32) hide show
  1. lbm_caiman_python-0.2.0/LICENSE.md +38 -0
  2. lbm_caiman_python-0.2.0/PKG-INFO +161 -0
  3. lbm_caiman_python-0.2.0/README.md +129 -0
  4. lbm_caiman_python-0.2.0/lbm_caiman_python/__init__.py +63 -0
  5. lbm_caiman_python-0.2.0/lbm_caiman_python/__main__.py +302 -0
  6. lbm_caiman_python-0.2.0/lbm_caiman_python/_version.py +8 -0
  7. lbm_caiman_python-0.2.0/lbm_caiman_python/batch.py +188 -0
  8. lbm_caiman_python-0.2.0/lbm_caiman_python/collation.py +125 -0
  9. lbm_caiman_python-0.2.0/lbm_caiman_python/default_ops.py +92 -0
  10. lbm_caiman_python-0.2.0/lbm_caiman_python/gui/__init__.py +3 -0
  11. lbm_caiman_python-0.2.0/lbm_caiman_python/gui/_store_model.py +170 -0
  12. lbm_caiman_python-0.2.0/lbm_caiman_python/gui/rungui.py +13 -0
  13. lbm_caiman_python-0.2.0/lbm_caiman_python/gui/widgets.py +114 -0
  14. lbm_caiman_python-0.2.0/lbm_caiman_python/helpers.py +262 -0
  15. lbm_caiman_python-0.2.0/lbm_caiman_python/postprocessing.py +319 -0
  16. lbm_caiman_python-0.2.0/lbm_caiman_python/run_lcp.py +1059 -0
  17. lbm_caiman_python-0.2.0/lbm_caiman_python/stdout.py +3 -0
  18. lbm_caiman_python-0.2.0/lbm_caiman_python/summary.py +569 -0
  19. lbm_caiman_python-0.2.0/lbm_caiman_python/util/__init__.py +87 -0
  20. lbm_caiman_python-0.2.0/lbm_caiman_python/util/exceptions.py +6 -0
  21. lbm_caiman_python-0.2.0/lbm_caiman_python/util/quality.py +366 -0
  22. lbm_caiman_python-0.2.0/lbm_caiman_python/util/signal.py +17 -0
  23. lbm_caiman_python-0.2.0/lbm_caiman_python/util/transform.py +208 -0
  24. lbm_caiman_python-0.2.0/lbm_caiman_python/visualize.py +522 -0
  25. lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/PKG-INFO +161 -0
  26. lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/SOURCES.txt +30 -0
  27. lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/dependency_links.txt +1 -0
  28. lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/entry_points.txt +2 -0
  29. lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/requires.txt +14 -0
  30. lbm_caiman_python-0.2.0/lbm_caiman_python.egg-info/top_level.txt +1 -0
  31. lbm_caiman_python-0.2.0/pyproject.toml +110 -0
  32. 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
+ [![Documentation](https://img.shields.io/badge/Documentation-black?style=for-the-badge&logo=readthedocs&logoColor=white)](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
+ [![Documentation](https://img.shields.io/badge/Documentation-black?style=for-the-badge&logo=readthedocs&logoColor=white)](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()
@@ -0,0 +1,8 @@
1
+ """version information for lbm_caiman_python."""
2
+
3
+ __version__ = "0.1.0"
4
+
5
+
6
+ def get_versions():
7
+ """return version dict for backwards compatibility."""
8
+ return {"version": __version__}