pykrait 0.3.2__tar.gz → 0.3.3__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 (33) hide show
  1. pykrait-0.3.3/.gitignore +59 -0
  2. {pykrait-0.3.2 → pykrait-0.3.3}/LICENSE +1 -1
  3. pykrait-0.3.3/PKG-INFO +168 -0
  4. pykrait-0.3.3/README.md +114 -0
  5. {pykrait-0.3.2 → pykrait-0.3.3}/pyproject.toml +14 -11
  6. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/__main__.py +3 -3
  7. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/async_workers.py +28 -10
  8. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/mainwindow.py +3 -1
  9. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/pipeline/pipeline.py +128 -63
  10. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/preprocessing/timeseries_extraction.py +10 -6
  11. pykrait-0.3.3/src/pykrait/trace_analysis/__init__.py +1 -0
  12. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/oscillations.py +10 -8
  13. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/peak_analysis.py +1 -1
  14. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/synchronicity.py +2 -1
  15. pykrait-0.3.3/src/pykrait/visualization/__init__.py +1 -0
  16. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/visualization/image_overlays.py +28 -19
  17. pykrait-0.3.2/.gitignore +0 -185
  18. pykrait-0.3.2/PKG-INFO +0 -81
  19. pykrait-0.3.2/README.md +0 -30
  20. pykrait-0.3.2/src/.python-version +0 -1
  21. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/__init__.py +0 -0
  22. {pykrait-0.3.2/src/pykrait/pipeline → pykrait-0.3.3/src/pykrait/gui}/__init__.py +0 -0
  23. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/app.py +0 -0
  24. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/custom_widgets.py +0 -0
  25. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/fileselection.py +0 -0
  26. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/resources/logo.png +0 -0
  27. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/io/__init__.py +0 -0
  28. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/io/files.py +0 -0
  29. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/io/images.py +0 -0
  30. {pykrait-0.3.2/src/pykrait/preprocessing → pykrait-0.3.3/src/pykrait/pipeline}/__init__.py +0 -0
  31. {pykrait-0.3.2/src/pykrait/trace_analysis → pykrait-0.3.3/src/pykrait/preprocessing}/__init__.py +0 -0
  32. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/preprocessing/segmentation.py +0 -0
  33. {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/filtering.py +0 -0
@@ -0,0 +1,59 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+
8
+ # Distribution / packaging
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+ *.egg
13
+ MANIFEST
14
+
15
+ # Virtual environments
16
+ .venv/
17
+ venv/
18
+ env/
19
+
20
+ # uv
21
+ .uv/
22
+ uv.lock
23
+
24
+ # Testing
25
+ .pytest_cache/
26
+ .coverage
27
+ coverage.xml
28
+ htmlcov/
29
+
30
+ # Linting
31
+ .ruff_cache/
32
+ .mypy_cache/
33
+
34
+ # Jupyter
35
+ .ipynb_checkpoints/
36
+
37
+ # Docs
38
+ docs/_build/
39
+ docs/autoapi/
40
+ docs/source/_autosummary/
41
+ docs/make.bat
42
+ docs/Makefile
43
+
44
+ # IDEs
45
+ .vscode/
46
+ .idea/
47
+ .claude/
48
+ *.swp
49
+ *.swo
50
+
51
+ # macOS
52
+ .DS_Store
53
+
54
+ # Secrets
55
+ .env
56
+ *.pem
57
+
58
+ # cellpose models
59
+ cellpose_models/
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Phaleanopsis
3
+ Copyright (c) 2026 Phaleanopsis
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
pykrait-0.3.3/PKG-INFO ADDED
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.4
2
+ Name: pykrait
3
+ Version: 0.3.3
4
+ Summary: Python Calcium Recording Analysis and Interpretation Toolbox
5
+ Author-email: phaleanopsis <22663502+phaleanopsis@users.noreply.github.com>
6
+ License: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: aicspylibczi>=3.3.1
10
+ Requires-Dist: bioio-czi>=2.4.0
11
+ Requires-Dist: bioio-imageio
12
+ Requires-Dist: bioio-ome-tiff>=1.1.0
13
+ Requires-Dist: bioio-tifffile>=1.3.0
14
+ Requires-Dist: bioio>=3.2.0
15
+ Requires-Dist: cellpose>=4.0.8
16
+ Requires-Dist: dask>=2025.5.1
17
+ Requires-Dist: fsspec>=2022.8.0
18
+ Requires-Dist: imagecodecs>=2025.3.30
19
+ Requires-Dist: lxml>=5.4.0
20
+ Requires-Dist: matplotlib>=3.10.3
21
+ Requires-Dist: numcodecs<0.16
22
+ Requires-Dist: numpy>2
23
+ Requires-Dist: ome-types>=0.5.3
24
+ Requires-Dist: ome-zarr>=0.10.2
25
+ Requires-Dist: pandas>=2.3.1
26
+ Requires-Dist: pip>=25.1.1
27
+ Requires-Dist: pydantic<2
28
+ Requires-Dist: pylibczirw>=6.0.1
29
+ Requires-Dist: pyyaml>=6.0.2
30
+ Requires-Dist: resource-backed-dask-array>=0.1.0
31
+ Requires-Dist: scikit-image>=0.25.2
32
+ Requires-Dist: scikit-learn>=1.7.2
33
+ Requires-Dist: scipy>=1.15.3
34
+ Requires-Dist: xarray>=2025.12
35
+ Requires-Dist: zarr>=2.15.0
36
+ Requires-Dist: zstandard>=0.23.0
37
+ Provides-Extra: dev
38
+ Requires-Dist: build>=1.2.2.post1; extra == 'dev'
39
+ Requires-Dist: hatch>=1.14.1; extra == 'dev'
40
+ Requires-Dist: ipywidgets>=8.1.7; extra == 'dev'
41
+ Requires-Dist: myst-parser>=5.0.0; extra == 'dev'
42
+ Requires-Dist: pydata-sphinx-theme>=0.16.1; extra == 'dev'
43
+ Requires-Dist: pytest-cov; extra == 'dev'
44
+ Requires-Dist: pytest>=8.4.1; extra == 'dev'
45
+ Requires-Dist: ruff>=0.11.13; extra == 'dev'
46
+ Requires-Dist: sphinx-autoapi>=3.6.0; extra == 'dev'
47
+ Requires-Dist: sphinx-favicon>=1.0.1; extra == 'dev'
48
+ Requires-Dist: sphinx>=8.1.3; extra == 'dev'
49
+ Requires-Dist: tomli>=2.2.1; extra == 'dev'
50
+ Requires-Dist: twine>=6.1.0; extra == 'dev'
51
+ Provides-Extra: gui
52
+ Requires-Dist: pyside6>=6.9.1; extra == 'gui'
53
+ Description-Content-Type: text/markdown
54
+
55
+ <p align="center">
56
+ <img src="docs/_static/logo.png" alt="pyKrait" width="200">
57
+ </p>
58
+
59
+ <h1 align="center">pyKrait</h1>
60
+
61
+
62
+ <p align="center">
63
+ <a href="https://pypi.org/project/pykrait/"><img src="https://img.shields.io/pypi/v/pykrait" alt="PyPI"></a>
64
+ <a href="https://pypi.org/project/pykrait/"><img src="https://img.shields.io/pypi/pyversions/pykrait" alt="Python versions"></a>
65
+ <a href="https://github.com/&lt;your-org&gt;/pykrait/actions"><img src="https://img.shields.io/github/actions/workflow/status/&lt;your-org&gt;/pykrait/CI.yaml" alt="CI"></a>
66
+ <a href="https://pykrait.readthedocs.io"><img src="https://img.shields.io/readthedocs/pykrait" alt="Docs"></a>
67
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License"></a>
68
+ </p>
69
+ <p align="center">
70
+ End-to-end pipeline for segmenting cells, detecting calcium peaks,<br>
71
+ and quantifying oscillation periodicity and spatial synchronicity<br>
72
+ from time-lapse microscopy.
73
+ </p>
74
+
75
+
76
+ <p align="center">
77
+ <img src="docs/_static/pyKrait_steps.png" alt="Analysis Steps of the pykrait package" width="600">
78
+ </p>
79
+
80
+ ## Overview
81
+
82
+ pyKrait (**py**thon **C**alcium **r**ecording **a**nalysis and **i**nterpretation **t**oolbox) automatically processes calcium-imaging videos (.czi, .tif, .tiff) and computes calcium activity, peak statistics, periodicity scores, and neighbour-aware synchronicity z-scores.
83
+
84
+ ## Installation
85
+
86
+ It is recommended to install pyKrait in a virtual environment using either venv or uv. The graphical user interface is optional, install it with `pip install "pykrait[gui]"`.
87
+
88
+ ### Standard `venv`
89
+
90
+ ```bash
91
+ python -m venv .venv
92
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
93
+ pip install --upgrade pip
94
+ pip install pykrait
95
+ ```
96
+
97
+ ### Using `uv`
98
+
99
+ ```bash
100
+ uv venv --python 3.11
101
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
102
+ uv pip install pykrait
103
+ ```
104
+
105
+ ## Quickstart
106
+
107
+ ### Launch the GUI
108
+
109
+ From inside the activated virtual environment:
110
+ ```bash
111
+ python -m pykrait
112
+ ```
113
+
114
+ The GUI walks you through video selection, segmentation, peak detection, periodicity, and synchronicity, and lets you save results to disk.
115
+
116
+ ### Batch process an entire folder
117
+
118
+ ```python
119
+ from pykrait.pipeline.pipeline import BatchExperiment, AnalysisParameters
120
+ from pykrait.io.files import concat_analysis_files
121
+
122
+ experiment = BatchExperiment(
123
+ folder="/path/to/videos",
124
+ params=AnalysisParameters(),
125
+ extension=".czi",
126
+ )
127
+ experiment.run()
128
+
129
+ concat_analysis_files("/path/to/videos", filetype="output")
130
+ ```
131
+
132
+ This produces one `Analysis_<video>/` directory per video and an `analysis_output_overview.csv` at the root of the folder.
133
+
134
+ ## Examples
135
+
136
+ | Scenario | Notebook |
137
+ |----------|----------|
138
+ | Run a folder with custom parameters | [`notebooks/example_batch_with_custom_parameters.ipynb`](notebooks/example_batch_with_custom_parameters.ipynb) |
139
+ | Re-run a folder reusing saved parameters and cached masks | [`notebooks/example_batch_reusing_parameters.ipynb`](notebooks/example_batch_reusing_parameters.ipynb) |
140
+ | Inspect or refine a single video interactively | Launch the GUI: `python -m pykrait` |
141
+
142
+ ## How it works
143
+
144
+ For each video, pyKrait runs the following stages:
145
+
146
+ 1. **Load** — lazy `Dask` array via `bioio` (`.czi`, `.tif`, `.tiff`).
147
+ 2. **Project** — STD or SUM projection across time, with optional CLAHE.
148
+ 3. **Segment** — Cellpose (`cpsam` by default, or a custom model path).
149
+ 4. **Extract** — per-cell mean intensity per frame, computed lazily on Dask.
150
+ 5. **Detrend** — Blackman-windowed sinc filter (cf. pyBOAT).
151
+ 6. **Detect peaks** — `scipy.signal.find_peaks` with width / height / prominence thresholds.
152
+ 7. **Periodicity** — STD and CoV of inter-peak intervals, scored against a shuffled-peaks null.
153
+ 8. **Adjacency** — neighbour graph from segmented masks (kernel-based proximity).
154
+ 9. **Synchronicity** — co-firing peaks within a time window and topological distance, z-scored against label-shuffled controls.
155
+
156
+ ## Documentation
157
+
158
+ Full API reference and tutorials: **<https://pykrait.readthedocs.io/en/latest/>**.
159
+
160
+ ## Acknowledgements
161
+
162
+ pyKrait builds on and heavily uses prior open-source work:
163
+
164
+ - [Cellpose](https://github.com/MouseLand/cellpose) for cell segmentation
165
+ - [pyBOAT](https://github.com/tensionhead/pyBOAT) for the sinc-filter detrending approach
166
+ - [bioio](https://github.com/bioio-devs/bioio) for image I/O
167
+ - [Dask](https://www.dask.org/) for lazy array computation
168
+
@@ -0,0 +1,114 @@
1
+ <p align="center">
2
+ <img src="docs/_static/logo.png" alt="pyKrait" width="200">
3
+ </p>
4
+
5
+ <h1 align="center">pyKrait</h1>
6
+
7
+
8
+ <p align="center">
9
+ <a href="https://pypi.org/project/pykrait/"><img src="https://img.shields.io/pypi/v/pykrait" alt="PyPI"></a>
10
+ <a href="https://pypi.org/project/pykrait/"><img src="https://img.shields.io/pypi/pyversions/pykrait" alt="Python versions"></a>
11
+ <a href="https://github.com/&lt;your-org&gt;/pykrait/actions"><img src="https://img.shields.io/github/actions/workflow/status/&lt;your-org&gt;/pykrait/CI.yaml" alt="CI"></a>
12
+ <a href="https://pykrait.readthedocs.io"><img src="https://img.shields.io/readthedocs/pykrait" alt="Docs"></a>
13
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="License"></a>
14
+ </p>
15
+ <p align="center">
16
+ End-to-end pipeline for segmenting cells, detecting calcium peaks,<br>
17
+ and quantifying oscillation periodicity and spatial synchronicity<br>
18
+ from time-lapse microscopy.
19
+ </p>
20
+
21
+
22
+ <p align="center">
23
+ <img src="docs/_static/pyKrait_steps.png" alt="Analysis Steps of the pykrait package" width="600">
24
+ </p>
25
+
26
+ ## Overview
27
+
28
+ pyKrait (**py**thon **C**alcium **r**ecording **a**nalysis and **i**nterpretation **t**oolbox) automatically processes calcium-imaging videos (.czi, .tif, .tiff) and computes calcium activity, peak statistics, periodicity scores, and neighbour-aware synchronicity z-scores.
29
+
30
+ ## Installation
31
+
32
+ It is recommended to install pyKrait in a virtual environment using either venv or uv. The graphical user interface is optional, install it with `pip install "pykrait[gui]"`.
33
+
34
+ ### Standard `venv`
35
+
36
+ ```bash
37
+ python -m venv .venv
38
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
39
+ pip install --upgrade pip
40
+ pip install pykrait
41
+ ```
42
+
43
+ ### Using `uv`
44
+
45
+ ```bash
46
+ uv venv --python 3.11
47
+ source .venv/bin/activate # Windows: .venv\Scripts\activate
48
+ uv pip install pykrait
49
+ ```
50
+
51
+ ## Quickstart
52
+
53
+ ### Launch the GUI
54
+
55
+ From inside the activated virtual environment:
56
+ ```bash
57
+ python -m pykrait
58
+ ```
59
+
60
+ The GUI walks you through video selection, segmentation, peak detection, periodicity, and synchronicity, and lets you save results to disk.
61
+
62
+ ### Batch process an entire folder
63
+
64
+ ```python
65
+ from pykrait.pipeline.pipeline import BatchExperiment, AnalysisParameters
66
+ from pykrait.io.files import concat_analysis_files
67
+
68
+ experiment = BatchExperiment(
69
+ folder="/path/to/videos",
70
+ params=AnalysisParameters(),
71
+ extension=".czi",
72
+ )
73
+ experiment.run()
74
+
75
+ concat_analysis_files("/path/to/videos", filetype="output")
76
+ ```
77
+
78
+ This produces one `Analysis_<video>/` directory per video and an `analysis_output_overview.csv` at the root of the folder.
79
+
80
+ ## Examples
81
+
82
+ | Scenario | Notebook |
83
+ |----------|----------|
84
+ | Run a folder with custom parameters | [`notebooks/example_batch_with_custom_parameters.ipynb`](notebooks/example_batch_with_custom_parameters.ipynb) |
85
+ | Re-run a folder reusing saved parameters and cached masks | [`notebooks/example_batch_reusing_parameters.ipynb`](notebooks/example_batch_reusing_parameters.ipynb) |
86
+ | Inspect or refine a single video interactively | Launch the GUI: `python -m pykrait` |
87
+
88
+ ## How it works
89
+
90
+ For each video, pyKrait runs the following stages:
91
+
92
+ 1. **Load** — lazy `Dask` array via `bioio` (`.czi`, `.tif`, `.tiff`).
93
+ 2. **Project** — STD or SUM projection across time, with optional CLAHE.
94
+ 3. **Segment** — Cellpose (`cpsam` by default, or a custom model path).
95
+ 4. **Extract** — per-cell mean intensity per frame, computed lazily on Dask.
96
+ 5. **Detrend** — Blackman-windowed sinc filter (cf. pyBOAT).
97
+ 6. **Detect peaks** — `scipy.signal.find_peaks` with width / height / prominence thresholds.
98
+ 7. **Periodicity** — STD and CoV of inter-peak intervals, scored against a shuffled-peaks null.
99
+ 8. **Adjacency** — neighbour graph from segmented masks (kernel-based proximity).
100
+ 9. **Synchronicity** — co-firing peaks within a time window and topological distance, z-scored against label-shuffled controls.
101
+
102
+ ## Documentation
103
+
104
+ Full API reference and tutorials: **<https://pykrait.readthedocs.io/en/latest/>**.
105
+
106
+ ## Acknowledgements
107
+
108
+ pyKrait builds on and heavily uses prior open-source work:
109
+
110
+ - [Cellpose](https://github.com/MouseLand/cellpose) for cell segmentation
111
+ - [pyBOAT](https://github.com/tensionhead/pyBOAT) for the sinc-filter detrending approach
112
+ - [bioio](https://github.com/bioio-devs/bioio) for image I/O
113
+ - [Dask](https://www.dask.org/) for lazy array computation
114
+
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "pykrait"
3
- version = "0.3.2"
4
- description = "Python Calcium Recording Analysis and Inference Toolbox"
3
+ version = "0.3.3"
4
+ description = "Python Calcium Recording Analysis and Interpretation Toolbox"
5
5
  readme = { file = "README.md", content-type = "text/markdown" }
6
6
  license = { text = "MIT" }
7
7
  authors = [
@@ -10,12 +10,12 @@ authors = [
10
10
  requires-python = ">=3.11"
11
11
  dependencies = [
12
12
  "aicspylibczi>=3.3.1",
13
- "bioio>=3.0.0",
13
+ "bioio>=3.2.0",
14
14
  "bioio-czi>=2.4.0",
15
15
  "bioio-ome-tiff>=1.1.0",
16
16
  "bioio-tifffile>=1.3.0",
17
17
  "bioio-imageio",
18
- "cellpose>=4.0.5",
18
+ "cellpose>=4.0.8",
19
19
  "dask>=2025.5.1",
20
20
  "fsspec>=2022.8.0",
21
21
  "imagecodecs>=2025.3.30",
@@ -31,10 +31,12 @@ dependencies = [
31
31
  "resource-backed-dask-array>=0.1.0",
32
32
  "scikit-image>=0.25.2",
33
33
  "scipy>=1.15.3",
34
- "xarray>2025",
34
+ "xarray>=2025.12",
35
35
  "pandas>=2.3.1",
36
36
  "zstandard>=0.23.0",
37
37
  "scikit-learn>=1.7.2",
38
+ "zarr>=2.15.0",
39
+ "pylibczirw>=6.0.1",
38
40
  ]
39
41
 
40
42
  [project.optional-dependencies]
@@ -53,7 +55,8 @@ dev = [
53
55
  "tomli>=2.2.1",
54
56
  "twine>=6.1.0",
55
57
  "pytest>=8.4.1",
56
- "pytest-cov"
58
+ "pytest-cov",
59
+ "myst-parser>=5.0.0",
57
60
  ]
58
61
 
59
62
  [build-system]
@@ -100,9 +103,9 @@ src = ["src"]
100
103
  line-length = 88
101
104
  target-version = "py311"
102
105
 
103
- [dependency-groups]
104
- dev = [
105
- "build>=1.2.2.post1",
106
- "hatch>=1.14.1",
107
- "twine>=6.1.0",
106
+ classifiers = [
107
+ "Programming Language :: Python :: 3",
108
+ "Programming Language :: Python :: 3.11",
109
+ "Programming Language :: Python :: 3.12",
110
+ "Programming Language :: Python :: 3.13",
108
111
  ]
@@ -1,10 +1,10 @@
1
1
  """
2
- Copyright © 2025 Pentabyteman
2
+ Copyright © 2026 Phaleanopsis
3
3
  """
4
4
 
5
5
  # src/pykrait/__main__.py
6
6
  from pykrait.gui.app import AppController
7
7
 
8
8
  if __name__ == "__main__":
9
- controller = AppController()
10
- controller.run()
9
+ app_controller = AppController()
10
+ app_controller.run()
@@ -1,13 +1,16 @@
1
- from PySide6.QtCore import QObject, Signal, Slot
2
1
  import traceback
2
+ import os
3
+ import tifffile
3
4
  import numpy as np
5
+ import pandas as pd
6
+
7
+ from PySide6.QtCore import QObject, Signal, Slot
8
+
4
9
  from pykrait.io.images import read_label_image, get_pixel_contour_from_label_img
5
10
  from pykrait.io.files import read_Txnrois
6
11
  from pykrait.preprocessing.segmentation import timelapse_projection
7
- import tifffile
8
12
  from pykrait.preprocessing.timeseries_extraction import extract_mean_intensities, get_adjacency_matrix
9
13
  from pykrait.trace_analysis.filtering import detrend_with_sinc_filter
10
- import os
11
14
 
12
15
  from pykrait.pipeline.pipeline import (
13
16
  AnalysisParameters,
@@ -19,7 +22,8 @@ from pykrait.pipeline.pipeline import (
19
22
  calculate_periodic_cells,
20
23
  calculate_synchronicity,
21
24
  save_analysis_results,
22
- save_params
25
+ save_params,
26
+ create_roi_dataframe
23
27
  )
24
28
 
25
29
  class ExtractIntensitiesWorker(QObject):
@@ -139,10 +143,7 @@ class ExtractIntensitiesWorker(QObject):
139
143
 
140
144
  class DetrendWorker(QObject):
141
145
  """
142
- _summary_
143
-
144
- :param QObject: _description_
145
- :type QObject: _type_
146
+ Worker for detrending the mean intensity traces, wraps the `detrend_with_sinc_filter` function.
146
147
  """
147
148
 
148
149
  finished = Signal(np.ndarray)
@@ -164,6 +165,8 @@ class DetrendWorker(QObject):
164
165
  )
165
166
  self.finished.emit(detrended)
166
167
  except Exception as e:
168
+ tb = traceback.format_exc()
169
+ print(f"Error during Detrending: {e}\n{tb}")
167
170
  self.error.emit(e)
168
171
 
169
172
 
@@ -189,6 +192,8 @@ class PeakDetectionWorker(QObject):
189
192
  result = [peak_series, analysis_output]
190
193
  self.finished.emit(result)
191
194
  except Exception as e:
195
+ tb = traceback.format_exc()
196
+ print(f"Error during Peak Detection: {e}\n{tb}")
192
197
  self.error.emit(e)
193
198
 
194
199
 
@@ -197,7 +202,7 @@ class PeriodicCellWorker(QObject):
197
202
  Worker for finding oscillating ROIs in the peak series, wraps the `find_oscillating_rois` function.
198
203
  """
199
204
 
200
- finished = Signal(AnalysisOutput, np.ndarray, np.ndarray)
205
+ finished = Signal(AnalysisOutput, np.ndarray, np.ndarray, pd.DataFrame)
201
206
  error = Signal(Exception)
202
207
 
203
208
  def __init__(self, peaks: np.ndarray, analysis_params, analysis_output):
@@ -211,8 +216,12 @@ class PeriodicCellWorker(QObject):
211
216
  analysis_output, stds, covs = calculate_periodic_cells(
212
217
  self.peaks, self.analysis_params, self.analysis_output
213
218
  )
214
- self.finished.emit(analysis_output, stds, covs)
219
+ roi_dataframe = create_roi_dataframe(self.peaks, stds, covs, analysis_output)
220
+
221
+ self.finished.emit(analysis_output, stds, covs, roi_dataframe)
215
222
  except Exception as e:
223
+ tb = traceback.format_exc()
224
+ print(f"Error during Periodicity Analysis: {e}\n{tb}")
216
225
  self.error.emit(e)
217
226
 
218
227
 
@@ -236,6 +245,8 @@ class AdjacencyMatrixWorker(QObject):
236
245
  )
237
246
  self.finished.emit(adjacency_matrix, shortest_path_matrix)
238
247
  except Exception as e:
248
+ tb = traceback.format_exc()
249
+ print(f"Error during Neighbourhood Analysis: {e}\n{tb}")
239
250
  self.error.emit(e)
240
251
 
241
252
 
@@ -264,6 +275,8 @@ class SynchronicityWorker(QObject):
264
275
  )
265
276
  self.finished.emit(results)
266
277
  except Exception as e:
278
+ tb = traceback.format_exc()
279
+ print(f"Error during Synchronicity Analysis: {e}\n{tb}")
267
280
  self.error.emit(e)
268
281
 
269
282
 
@@ -287,6 +300,7 @@ class AnalysisSaveWorker(QObject):
287
300
  intensities: np.ndarray,
288
301
  stds: np.ndarray = None,
289
302
  covs: np.ndarray = None,
303
+ roi_dataframe = None,
290
304
  overwrite: bool = False,
291
305
  ):
292
306
  super().__init__()
@@ -301,6 +315,7 @@ class AnalysisSaveWorker(QObject):
301
315
  self.overwrite = overwrite
302
316
  self.stds = stds
303
317
  self.covs = covs
318
+ self.roi_dataframe = roi_dataframe
304
319
 
305
320
  def run(self):
306
321
  try:
@@ -315,9 +330,12 @@ class AnalysisSaveWorker(QObject):
315
330
  intensities=self.intensities,
316
331
  stds=self.stds,
317
332
  covs=self.covs,
333
+ roi_dataframe=self.roi_dataframe,
318
334
  overwrite=self.overwrite,
319
335
  )
320
336
  self.finished.emit(f"Saved to {self.analysis_output.analysis_folder}")
321
337
 
322
338
  except Exception as e:
339
+ tb = traceback.format_exc()
340
+ print(f"Error during Tracing: {e}\n{tb}")
323
341
  self.error.emit(e)
@@ -909,10 +909,11 @@ class MainWindow(QMainWindow):
909
909
  self.periodicity_thread.finished.connect(self.periodicity_thread.deleteLater)
910
910
  self.periodicity_thread.start()
911
911
 
912
- def _periodicity_done(self, analysis_output, stds, covs):
912
+ def _periodicity_done(self, analysis_output, stds, covs, roi_dataframe):
913
913
  self.analysis_output = analysis_output
914
914
  self.experimental_stds = stds
915
915
  self.experimental_covs = covs
916
+ self.roi_dataframe = roi_dataframe
916
917
 
917
918
  # Update the labels with periodicity cutoffs and quantiles
918
919
  self.cov_cutoff_value_label.setText(
@@ -1061,6 +1062,7 @@ class MainWindow(QMainWindow):
1061
1062
  intensities=self.intensities,
1062
1063
  stds=self.experimental_stds,
1063
1064
  covs=self.experimental_covs,
1065
+ roi_dataframe=self.roi_dataframe,
1064
1066
  overwrite=self.overwrite_checkbox.isChecked(),
1065
1067
  )
1066
1068
  self.analysis_worker.moveToThread(self.analysis_save_thread)