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.
- pykrait-0.3.3/.gitignore +59 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/LICENSE +1 -1
- pykrait-0.3.3/PKG-INFO +168 -0
- pykrait-0.3.3/README.md +114 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/pyproject.toml +14 -11
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/__main__.py +3 -3
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/async_workers.py +28 -10
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/mainwindow.py +3 -1
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/pipeline/pipeline.py +128 -63
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/preprocessing/timeseries_extraction.py +10 -6
- pykrait-0.3.3/src/pykrait/trace_analysis/__init__.py +1 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/oscillations.py +10 -8
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/peak_analysis.py +1 -1
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/synchronicity.py +2 -1
- pykrait-0.3.3/src/pykrait/visualization/__init__.py +1 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/visualization/image_overlays.py +28 -19
- pykrait-0.3.2/.gitignore +0 -185
- pykrait-0.3.2/PKG-INFO +0 -81
- pykrait-0.3.2/README.md +0 -30
- pykrait-0.3.2/src/.python-version +0 -1
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/__init__.py +0 -0
- {pykrait-0.3.2/src/pykrait/pipeline → pykrait-0.3.3/src/pykrait/gui}/__init__.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/app.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/custom_widgets.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/fileselection.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/gui/resources/logo.png +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/io/__init__.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/io/files.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/io/images.py +0 -0
- {pykrait-0.3.2/src/pykrait/preprocessing → pykrait-0.3.3/src/pykrait/pipeline}/__init__.py +0 -0
- {pykrait-0.3.2/src/pykrait/trace_analysis → pykrait-0.3.3/src/pykrait/preprocessing}/__init__.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/preprocessing/segmentation.py +0 -0
- {pykrait-0.3.2 → pykrait-0.3.3}/src/pykrait/trace_analysis/filtering.py +0 -0
pykrait-0.3.3/.gitignore
ADDED
|
@@ -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/
|
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/<your-org>/pykrait/actions"><img src="https://img.shields.io/github/actions/workflow/status/<your-org>/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
|
+
|
pykrait-0.3.3/README.md
ADDED
|
@@ -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/<your-org>/pykrait/actions"><img src="https://img.shields.io/github/actions/workflow/status/<your-org>/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.
|
|
4
|
-
description = "Python Calcium Recording Analysis and
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
[
|
|
104
|
-
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
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 ©
|
|
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
|
-
|
|
10
|
-
|
|
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
|
-
|
|
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.
|
|
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)
|