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.
Files changed (32) hide show
  1. {lbm_suite2p_python-3.0.5/lbm_suite2p_python.egg-info → lbm_suite2p_python-3.0.7}/PKG-INFO +1 -1
  2. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/cli.py +79 -2
  3. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/db_settings.py +531 -531
  4. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/run_lsp.py +529 -125
  5. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7/lbm_suite2p_python.egg-info}/PKG-INFO +1 -1
  6. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/pyproject.toml +106 -106
  7. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/LICENSE.md +0 -0
  8. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/MANIFEST.in +0 -0
  9. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/README.md +0 -0
  10. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/__init__.py +0 -0
  11. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/__main__.py +0 -0
  12. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/_benchmarking.py +0 -0
  13. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/cellpose.py +0 -0
  14. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/conversion.py +0 -0
  15. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/default_ops.py +0 -0
  16. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/grid_search.py +0 -0
  17. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/gui.py +0 -0
  18. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/merging.py +0 -0
  19. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/postprocessing.py +0 -0
  20. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/utils.py +0 -0
  21. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/volume.py +0 -0
  22. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python/zplane.py +0 -0
  23. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/SOURCES.txt +0 -0
  24. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/dependency_links.txt +0 -0
  25. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/entry_points.txt +0 -0
  26. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/requires.txt +0 -0
  27. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/lbm_suite2p_python.egg-info/top_level.txt +0 -0
  28. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/setup.cfg +0 -0
  29. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/tests/test_frame_count_aliases.py +0 -0
  30. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/tests/test_pipeline_parameters.py +0 -0
  31. {lbm_suite2p_python-3.0.5 → lbm_suite2p_python-3.0.7}/tests/test_refactored_pipeline.py +0 -0
  32. {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.5
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__":