lbm_suite2p_python 3.0.5__tar.gz → 3.0.7__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_suite2p_python-3.0.5/lbm_suite2p_python.egg-info → lbm_suite2p_python-3.0.7}/PKG-INFO +1 -1
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/cli.py +79 -2
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/db_settings.py +531 -531
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/run_lsp.py +529 -125
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7/lbm_suite2p_python.egg-info}/PKG-INFO +1 -1
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/pyproject.toml +106 -106
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/LICENSE.md +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/MANIFEST.in +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/README.md +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/__init__.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/__main__.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/_benchmarking.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/cellpose.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/conversion.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/default_ops.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/grid_search.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/gui.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/merging.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/postprocessing.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/utils.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/volume.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/zplane.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/SOURCES.txt +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/dependency_links.txt +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/entry_points.txt +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/requires.txt +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/top_level.txt +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/setup.cfg +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/tests/test_frame_count_aliases.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/tests/test_pipeline_parameters.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/tests/test_refactored_pipeline.py +0 -0
- {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/tests/test_run_volume.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lbm_suite2p_python
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.7
|
|
4
4
|
Summary: Calcium Imaging Pipeline built with Suite2p, Cellpose and Rastermap
|
|
5
5
|
License-Expression: BSD-3-Clause
|
|
6
6
|
Project-URL: homepage, https://github.com/MillerBrainObservatory/LBM-Suite2p-Python
|
|
@@ -174,6 +174,24 @@ Examples:
|
|
|
174
174
|
"--accept-all-cells", action="store_true",
|
|
175
175
|
help="mark all detected ROIs as accepted cells"
|
|
176
176
|
)
|
|
177
|
+
pipeline.add_argument(
|
|
178
|
+
"--workers", type=int, default=4,
|
|
179
|
+
help="number of zplane worker processes (default: 4). "
|
|
180
|
+
"Use 1 for sequential, or 0 / negative for auto = "
|
|
181
|
+
"min(num_planes, cpu_count//2, 8). "
|
|
182
|
+
"Cellpose on GPU may OOM with multiple workers."
|
|
183
|
+
)
|
|
184
|
+
pipeline.add_argument(
|
|
185
|
+
"--skip-volumetric", action="store_true", dest="skip_volumetric",
|
|
186
|
+
help="skip merge_mrois, volume_stats, and volumetric plots after per-plane processing"
|
|
187
|
+
)
|
|
188
|
+
pipeline.add_argument(
|
|
189
|
+
"--threads-per-worker", type=int, dest="threads_per_worker", default=2,
|
|
190
|
+
help="cap BLAS / OMP / numba / torch threads per worker process "
|
|
191
|
+
"(default: 2). Total CPU load ~ workers * threads_per_worker. "
|
|
192
|
+
"Set to 0 or a negative value to use library defaults "
|
|
193
|
+
"(typically 1 thread per core, which oversubscribes when workers > 1)."
|
|
194
|
+
)
|
|
177
195
|
|
|
178
196
|
# dff options
|
|
179
197
|
dff = parser.add_argument_group("dff options")
|
|
@@ -324,6 +342,30 @@ def list_ops():
|
|
|
324
342
|
print(f" --{_snake_to_kebab(key):<22} {default_str:<20} {help_text}")
|
|
325
343
|
|
|
326
344
|
|
|
345
|
+
class _Tee:
|
|
346
|
+
"""Duplicate writes to multiple text streams (e.g., stdout + file)."""
|
|
347
|
+
|
|
348
|
+
def __init__(self, *streams):
|
|
349
|
+
self.streams = streams
|
|
350
|
+
|
|
351
|
+
def write(self, data):
|
|
352
|
+
for s in self.streams:
|
|
353
|
+
try:
|
|
354
|
+
s.write(data)
|
|
355
|
+
except Exception:
|
|
356
|
+
pass
|
|
357
|
+
|
|
358
|
+
def flush(self):
|
|
359
|
+
for s in self.streams:
|
|
360
|
+
try:
|
|
361
|
+
s.flush()
|
|
362
|
+
except Exception:
|
|
363
|
+
pass
|
|
364
|
+
|
|
365
|
+
def isatty(self):
|
|
366
|
+
return False
|
|
367
|
+
|
|
368
|
+
|
|
327
369
|
def build_cell_filters(args) -> list | None:
|
|
328
370
|
"""build cell filters list from CLI args."""
|
|
329
371
|
filters = []
|
|
@@ -457,8 +499,28 @@ def main():
|
|
|
457
499
|
|
|
458
500
|
output_path.mkdir(parents=True, exist_ok=True)
|
|
459
501
|
|
|
502
|
+
log_path = output_path / "log.txt"
|
|
503
|
+
log_file = open(log_path, "w", encoding="utf-8", buffering=1)
|
|
504
|
+
_orig_stdout, _orig_stderr = sys.stdout, sys.stderr
|
|
505
|
+
sys.stdout = _Tee(_orig_stdout, log_file)
|
|
506
|
+
sys.stderr = _Tee(_orig_stderr, log_file)
|
|
507
|
+
print(f"Logging to: {log_path}")
|
|
508
|
+
|
|
509
|
+
from importlib.metadata import PackageNotFoundError, version as _pkg_version
|
|
510
|
+
try:
|
|
511
|
+
_mbo_version = _pkg_version("mbo_utilities")
|
|
512
|
+
except PackageNotFoundError:
|
|
513
|
+
_mbo_version = "unknown"
|
|
514
|
+
try:
|
|
515
|
+
_s2p_version = _pkg_version("suite2p")
|
|
516
|
+
except PackageNotFoundError:
|
|
517
|
+
_s2p_version = "not installed"
|
|
518
|
+
|
|
460
519
|
print(f"\n{'='*60}")
|
|
461
520
|
print(f"LBM Suite2p Pipeline v{__version__}")
|
|
521
|
+
print(f" mbo_utilities v{_mbo_version}")
|
|
522
|
+
print(f" lbm_suite2p_python v{__version__}")
|
|
523
|
+
print(f" suite2p v{_s2p_version}")
|
|
462
524
|
print(f"{'='*60}")
|
|
463
525
|
print(f"Input: {input_path}")
|
|
464
526
|
print(f"Output: {output_path}")
|
|
@@ -491,6 +553,8 @@ def main():
|
|
|
491
553
|
print(f"\n{'='*60}\n")
|
|
492
554
|
|
|
493
555
|
# run pipeline
|
|
556
|
+
import time
|
|
557
|
+
_pipeline_start = time.time()
|
|
494
558
|
try:
|
|
495
559
|
lsp.pipeline(
|
|
496
560
|
input_data=input_path,
|
|
@@ -501,8 +565,8 @@ def main():
|
|
|
501
565
|
num_timepoints=args.num_timepoints,
|
|
502
566
|
keep_reg=args.keep_reg,
|
|
503
567
|
keep_raw=args.keep_raw,
|
|
504
|
-
force_reg=args.force_reg,
|
|
505
|
-
force_detect=args.force_detect,
|
|
568
|
+
force_reg=args.force_reg or args.overwrite,
|
|
569
|
+
force_detect=args.force_detect or args.overwrite,
|
|
506
570
|
dff_window_size=args.dff_window_size,
|
|
507
571
|
dff_percentile=args.dff_percentile,
|
|
508
572
|
dff_smooth_window=args.dff_smooth_window,
|
|
@@ -511,11 +575,18 @@ def main():
|
|
|
511
575
|
accept_all_cells=args.accept_all_cells,
|
|
512
576
|
save_json=args.save_json,
|
|
513
577
|
reader_kwargs=reader_kwargs if reader_kwargs else None,
|
|
578
|
+
workers=args.workers,
|
|
579
|
+
skip_volumetric=args.skip_volumetric,
|
|
580
|
+
threads_per_worker=args.threads_per_worker,
|
|
514
581
|
)
|
|
515
582
|
|
|
583
|
+
_elapsed = time.time() - _pipeline_start
|
|
584
|
+
_h, _rem = divmod(int(_elapsed), 3600)
|
|
585
|
+
_m, _s = divmod(_rem, 60)
|
|
516
586
|
print(f"\n{'='*60}")
|
|
517
587
|
print(f"Processing complete!")
|
|
518
588
|
print(f"Results saved to: {output_path}")
|
|
589
|
+
print(f"Total elapsed: {_h:02d}:{_m:02d}:{_s:02d} ({_elapsed:.1f}s)")
|
|
519
590
|
print(f"{'='*60}\n")
|
|
520
591
|
|
|
521
592
|
return 0
|
|
@@ -525,6 +596,12 @@ def main():
|
|
|
525
596
|
import traceback
|
|
526
597
|
traceback.print_exc()
|
|
527
598
|
return 1
|
|
599
|
+
finally:
|
|
600
|
+
sys.stdout, sys.stderr = _orig_stdout, _orig_stderr
|
|
601
|
+
try:
|
|
602
|
+
log_file.close()
|
|
603
|
+
except Exception:
|
|
604
|
+
pass
|
|
528
605
|
|
|
529
606
|
|
|
530
607
|
if __name__ == "__main__":
|