wormscore 0.6.1__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 (38) hide show
  1. wormscore-0.6.1/LICENSE +21 -0
  2. wormscore-0.6.1/PKG-INFO +164 -0
  3. wormscore-0.6.1/README.md +132 -0
  4. wormscore-0.6.1/pyproject.toml +55 -0
  5. wormscore-0.6.1/setup.cfg +4 -0
  6. wormscore-0.6.1/src/wormscore/__init__.py +3 -0
  7. wormscore-0.6.1/src/wormscore/cli.py +81 -0
  8. wormscore-0.6.1/src/wormscore/config.py +265 -0
  9. wormscore-0.6.1/src/wormscore/copydata.py +33 -0
  10. wormscore-0.6.1/src/wormscore/demo.py +96 -0
  11. wormscore-0.6.1/src/wormscore/launcher.py +272 -0
  12. wormscore-0.6.1/src/wormscore/measure.py +145 -0
  13. wormscore-0.6.1/src/wormscore/methods.py +183 -0
  14. wormscore-0.6.1/src/wormscore/pipeline.py +481 -0
  15. wormscore-0.6.1/src/wormscore/readers.py +392 -0
  16. wormscore-0.6.1/src/wormscore/realdemo.py +94 -0
  17. wormscore-0.6.1/src/wormscore/server.py +263 -0
  18. wormscore-0.6.1/src/wormscore/static/app.js +555 -0
  19. wormscore-0.6.1/src/wormscore/static/icon.svg +1 -0
  20. wormscore-0.6.1/src/wormscore/static/index.html +107 -0
  21. wormscore-0.6.1/src/wormscore/static/style.css +147 -0
  22. wormscore-0.6.1/src/wormscore/stats.py +237 -0
  23. wormscore-0.6.1/src/wormscore/unblind.py +304 -0
  24. wormscore-0.6.1/src/wormscore.egg-info/PKG-INFO +164 -0
  25. wormscore-0.6.1/src/wormscore.egg-info/SOURCES.txt +36 -0
  26. wormscore-0.6.1/src/wormscore.egg-info/dependency_links.txt +1 -0
  27. wormscore-0.6.1/src/wormscore.egg-info/entry_points.txt +5 -0
  28. wormscore-0.6.1/src/wormscore.egg-info/requires.txt +11 -0
  29. wormscore-0.6.1/src/wormscore.egg-info/top_level.txt +1 -0
  30. wormscore-0.6.1/tests/test_add_images.py +72 -0
  31. wormscore-0.6.1/tests/test_analysis_plan.py +154 -0
  32. wormscore-0.6.1/tests/test_app.py +117 -0
  33. wormscore-0.6.1/tests/test_measure.py +84 -0
  34. wormscore-0.6.1/tests/test_pipeline.py +90 -0
  35. wormscore-0.6.1/tests/test_readers.py +122 -0
  36. wormscore-0.6.1/tests/test_realdemo.py +47 -0
  37. wormscore-0.6.1/tests/test_results_options.py +155 -0
  38. wormscore-0.6.1/tests/test_stats.py +44 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Arjun Bansal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.4
2
+ Name: wormscore
3
+ Version: 0.6.1
4
+ Summary: Blind scoring of fluorescent neurons in C. elegans confocal stacks, with measurement and genetics statistics.
5
+ Author: Arjun Bansal
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/arjunkai/wormscore
8
+ Project-URL: Documentation, https://github.com/arjunkai/wormscore/blob/main/docs/METHODS.md
9
+ Project-URL: Issues, https://github.com/arjunkai/wormscore/issues
10
+ Project-URL: Releases, https://github.com/arjunkai/wormscore/releases
11
+ Keywords: C. elegans,worm,neuron,blind scoring,fluorescence,microscopy,confocal,penetrance
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
17
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: numpy>=1.26
22
+ Requires-Dist: scipy>=1.11
23
+ Requires-Dist: pillow>=10
24
+ Requires-Dist: liffile>=2026.10.14
25
+ Requires-Dist: czifile>=2026.10.14
26
+ Requires-Dist: tifffile>=2024.1
27
+ Requires-Dist: imagecodecs>=2024.1
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8; extra == "dev"
30
+ Requires-Dist: pyinstaller>=6.10; extra == "dev"
31
+ Dynamic: license-file
32
+
33
+ # wormscore
34
+
35
+ Blind scoring of fluorescent neurons in *C. elegans*, with measurement and genetics statistics.
36
+ Built for scoring reporter neurons (normal / dim / missing) in confocal z-stacks. Nothing is tied
37
+ to one neuron, marker or microscope: those are settings in each project's `config.json`, so other
38
+ organisms work the same way.
39
+
40
+ - **Blind:** every image gets a random code. Genotypes and file names stay in a sealed key
41
+ until you finish scoring.
42
+ - **Fixed display:** every image from the same microscope is shown with the same brightness range.
43
+ You can page through z-planes and overlay brightfield.
44
+ - **Measured, not decided:** suggested cell bodies and your drawn regions are measured (peak, mean,
45
+ local background, sharpest plane, saturation). The numbers are written to files and never shown
46
+ while you score. The software never labels a cell normal, dim or missing.
47
+ - **Traceable:** every number links to the exact file, path, series and SHA-256 checksum it came from.
48
+ - **Reproducible:** every parameter and software version is appended to `log.md` on each run.
49
+ - **Local:** runs on your computer only. Nothing is uploaded.
50
+
51
+ Supported raw formats: Leica `.lif`, Zeiss `.czi`, OME-TIFF (including Micro-Manager style files with
52
+ a `.companion.ome`). Channel identity (marker vs brightfield) is read from metadata, never guessed.
53
+
54
+ ## Install
55
+
56
+ **Windows, no Python needed:** download `wormscore-windows.zip` from the Releases page, unzip it,
57
+ and double-click `wormscore.exe`.
58
+
59
+ **With Python 3.12 or newer:**
60
+
61
+ ```
62
+ pip install git+https://github.com/arjunkai/wormscore.git
63
+ ```
64
+
65
+ This installs a `wormscore` command and a `wormscore-launcher` window.
66
+
67
+ ## Try it in two minutes (simulated data)
68
+
69
+ ```
70
+ wormscore demo my_demo
71
+ wormscore inventory my_demo
72
+ wormscore prepare my_demo
73
+ wormscore app my_demo
74
+ ```
75
+
76
+ `demo` writes 20 simulated worm heads (controls with two normal cells; mutants with cells that are
77
+ normal, dim or missing at random) and a `demo_truth.csv` you can check your calls against later.
78
+ In the launcher window the same steps are buttons: **Demo... > 1. Scan data > 2. Build blind set > 3. Score**.
79
+
80
+ **Real worms:** `wormscore demo my_demo --real` (or Yes in the launcher's Demo dialog) downloads four
81
+ L1 heads with an endogenous GFP reporter, about 150 MB, from
82
+ [Sun and Hobert 2021](https://doi.org/10.1038/s41586-021-04071-4)
83
+ ([Zenodo 5602160](https://doi.org/10.5281/zenodo.5602160), CC BY 4.0). Each file is checked against its
84
+ MD5 from the Zenodo record and cached in `%LOCALAPPDATA%\wormscore\demo_cache` (`~/.cache` elsewhere).
85
+ The two reporters stand in for two genotypes; both are normal animals, so this is for practice.
86
+ The images are not part of this repository.
87
+
88
+ ## Using it on your own images
89
+
90
+ 1. **Copy your data** to a local folder (not a synced cloud folder if the data is not yours to share):
91
+ `wormscore copy D:\from\drive C:\data\my_copy` copies every file, checks each one by SHA-256 and
92
+ makes the copies read-only.
93
+ 2. **Make a project:** `wormscore init C:\projects\my_project`, then edit `config.json`:
94
+ point `sources` at your images, write genotype rules, and name your neurons. See
95
+ [`examples/config_example.json`](https://github.com/arjunkai/wormscore/blob/main/examples/config_example.json).
96
+ 3. **Scan:** `wormscore inventory my_project` lists every file (`outputs/manifest.csv`: raw image,
97
+ duplicate, derived projection, reference, hidden system file) and every image with its metadata
98
+ and channel identity (`outputs/inventory.csv`). Check the flags column.
99
+ 4. **Build the blind set:** `wormscore prepare my_project` applies the inclusion rules, assigns codes,
100
+ finds and measures suggested cells, and writes the sealed key. Excluded images and the reasons are
101
+ in `outputs/excluded.csv`. To leave out images by name (for example a plate with the wrong
102
+ reporter), add `"exclude": [{"match": "*pattern*", "reason": "why"}]` to that source.
103
+ Images taken after scoring started can be added with `wormscore prepare my_project --add-new-images`
104
+ (scan first): existing codes stay the same and new images get codes after the last one.
105
+ 5. **Score:** `wormscore app my_project`. For each image: answer any yellow questions, score each
106
+ neuron, save, then outline each cell body (or accept a suggestion) and save regions.
107
+ 6. **Unblind after scoring:** `wormscore unblind my_project --i-have-finished-scoring`. Writes
108
+ `outputs/unblinded/merged.csv` (scores + numbers + key, one row per image), a summary, and results
109
+ tables: `per_neuron.csv` (one row per animal and neuron, for plotting), `penetrance.csv` (animals with
110
+ 0, 1, 2 ... affected neurons) and `fisher_tests.csv` (Fisher's exact within each microscope,
111
+ Bonferroni-corrected). Set `unblinding.reference_genotype` in `config.json` to test against a control.
112
+ Optional, off unless set in `unblinding`: `question_outcomes` turns the per-neuron questions into
113
+ the same penetrance and Fisher tables (for example "process defect" when a dendrite question is
114
+ answered "no"), and `interaction` tests a double mutant against the value two single mutants predict
115
+ (Product model by default) with a binomial test. Also optional: a secondary definition of "affected"
116
+ (descriptive, within one microscope), planned comparisons, one-sided tests, labelled sources, and
117
+ comparisons across microscopes for chosen measures (with warnings). All of these are recorded as an
118
+ analysis plan before scoring and locked once scoring starts. See [docs/METHODS.md](https://github.com/arjunkai/wormscore/blob/main/docs/METHODS.md#8-unblinding).
119
+ `methods_text.md` is a draft Methods paragraph on blinding, measurement and statistics; fill in the
120
+ `blinding` section of `config.json` (who coded, who scored) or edit the [brackets] it leaves.
121
+
122
+ ## Project folder
123
+
124
+ | Path | Contents | Open while scoring? |
125
+ |---|---|---|
126
+ | `config.json` | every parameter | yes |
127
+ | `log.md` | every run: parameters, software versions, counts | yes |
128
+ | `outputs/manifest.csv`, `inventory.csv`, `excluded.csv` | what was found and what was left out | yes |
129
+ | `outputs/auto_measurements.csv` | numbers for suggested spots | avoid until done |
130
+ | `blind/` | images for scoring, named by code | used by the app |
131
+ | `scoring/` | your scores, regions and their measurements | scores yes; avoid `roi_measurements.csv` |
132
+ | `key/` | code to file, genotype, settings | **no, not until scoring is finished** |
133
+
134
+ ## How it works
135
+
136
+ See [docs/METHODS.md](https://github.com/arjunkai/wormscore/blob/main/docs/METHODS.md) for every step in plain language, suitable for adapting into
137
+ a Methods section, including the measurement definitions and their limits.
138
+
139
+ ## Development
140
+
141
+ ```
142
+ pip install -e .[dev]
143
+ pytest
144
+ ```
145
+
146
+ The tests build a simulated project and check the measurements, the blinding (no genotype or file
147
+ name reaches the scoring page), code stability, the unblinding locks and traceability. Leica and
148
+ Zeiss readers are checked against real files locally; real images are never committed.
149
+
150
+ Build the Windows app: `packaging\build_windows.bat`.
151
+
152
+ ## Privacy
153
+
154
+ This repository contains code only. `.gitignore` excludes image formats, keys, scores and outputs.
155
+ Do not commit or upload data that belongs to someone else.
156
+
157
+ ## License and citation
158
+
159
+ MIT License (see [LICENSE](https://github.com/arjunkai/wormscore/blob/main/LICENSE)). If you use wormscore in research, please cite it: GitHub's
160
+ "Cite this repository" button (from [CITATION.cff](https://github.com/arjunkai/wormscore/blob/main/CITATION.cff)) gives the reference.
161
+
162
+ wormscore reads Leica files with [liffile](https://github.com/cgohlke/liffile) and Zeiss files with
163
+ [czifile](https://github.com/cgohlke/czifile) (both BSD-3). The Windows app bundles these and other
164
+ libraries; their licenses are in `THIRD_PARTY_LICENSES.txt` next to `wormscore.exe`.
@@ -0,0 +1,132 @@
1
+ # wormscore
2
+
3
+ Blind scoring of fluorescent neurons in *C. elegans*, with measurement and genetics statistics.
4
+ Built for scoring reporter neurons (normal / dim / missing) in confocal z-stacks. Nothing is tied
5
+ to one neuron, marker or microscope: those are settings in each project's `config.json`, so other
6
+ organisms work the same way.
7
+
8
+ - **Blind:** every image gets a random code. Genotypes and file names stay in a sealed key
9
+ until you finish scoring.
10
+ - **Fixed display:** every image from the same microscope is shown with the same brightness range.
11
+ You can page through z-planes and overlay brightfield.
12
+ - **Measured, not decided:** suggested cell bodies and your drawn regions are measured (peak, mean,
13
+ local background, sharpest plane, saturation). The numbers are written to files and never shown
14
+ while you score. The software never labels a cell normal, dim or missing.
15
+ - **Traceable:** every number links to the exact file, path, series and SHA-256 checksum it came from.
16
+ - **Reproducible:** every parameter and software version is appended to `log.md` on each run.
17
+ - **Local:** runs on your computer only. Nothing is uploaded.
18
+
19
+ Supported raw formats: Leica `.lif`, Zeiss `.czi`, OME-TIFF (including Micro-Manager style files with
20
+ a `.companion.ome`). Channel identity (marker vs brightfield) is read from metadata, never guessed.
21
+
22
+ ## Install
23
+
24
+ **Windows, no Python needed:** download `wormscore-windows.zip` from the Releases page, unzip it,
25
+ and double-click `wormscore.exe`.
26
+
27
+ **With Python 3.12 or newer:**
28
+
29
+ ```
30
+ pip install git+https://github.com/arjunkai/wormscore.git
31
+ ```
32
+
33
+ This installs a `wormscore` command and a `wormscore-launcher` window.
34
+
35
+ ## Try it in two minutes (simulated data)
36
+
37
+ ```
38
+ wormscore demo my_demo
39
+ wormscore inventory my_demo
40
+ wormscore prepare my_demo
41
+ wormscore app my_demo
42
+ ```
43
+
44
+ `demo` writes 20 simulated worm heads (controls with two normal cells; mutants with cells that are
45
+ normal, dim or missing at random) and a `demo_truth.csv` you can check your calls against later.
46
+ In the launcher window the same steps are buttons: **Demo... > 1. Scan data > 2. Build blind set > 3. Score**.
47
+
48
+ **Real worms:** `wormscore demo my_demo --real` (or Yes in the launcher's Demo dialog) downloads four
49
+ L1 heads with an endogenous GFP reporter, about 150 MB, from
50
+ [Sun and Hobert 2021](https://doi.org/10.1038/s41586-021-04071-4)
51
+ ([Zenodo 5602160](https://doi.org/10.5281/zenodo.5602160), CC BY 4.0). Each file is checked against its
52
+ MD5 from the Zenodo record and cached in `%LOCALAPPDATA%\wormscore\demo_cache` (`~/.cache` elsewhere).
53
+ The two reporters stand in for two genotypes; both are normal animals, so this is for practice.
54
+ The images are not part of this repository.
55
+
56
+ ## Using it on your own images
57
+
58
+ 1. **Copy your data** to a local folder (not a synced cloud folder if the data is not yours to share):
59
+ `wormscore copy D:\from\drive C:\data\my_copy` copies every file, checks each one by SHA-256 and
60
+ makes the copies read-only.
61
+ 2. **Make a project:** `wormscore init C:\projects\my_project`, then edit `config.json`:
62
+ point `sources` at your images, write genotype rules, and name your neurons. See
63
+ [`examples/config_example.json`](https://github.com/arjunkai/wormscore/blob/main/examples/config_example.json).
64
+ 3. **Scan:** `wormscore inventory my_project` lists every file (`outputs/manifest.csv`: raw image,
65
+ duplicate, derived projection, reference, hidden system file) and every image with its metadata
66
+ and channel identity (`outputs/inventory.csv`). Check the flags column.
67
+ 4. **Build the blind set:** `wormscore prepare my_project` applies the inclusion rules, assigns codes,
68
+ finds and measures suggested cells, and writes the sealed key. Excluded images and the reasons are
69
+ in `outputs/excluded.csv`. To leave out images by name (for example a plate with the wrong
70
+ reporter), add `"exclude": [{"match": "*pattern*", "reason": "why"}]` to that source.
71
+ Images taken after scoring started can be added with `wormscore prepare my_project --add-new-images`
72
+ (scan first): existing codes stay the same and new images get codes after the last one.
73
+ 5. **Score:** `wormscore app my_project`. For each image: answer any yellow questions, score each
74
+ neuron, save, then outline each cell body (or accept a suggestion) and save regions.
75
+ 6. **Unblind after scoring:** `wormscore unblind my_project --i-have-finished-scoring`. Writes
76
+ `outputs/unblinded/merged.csv` (scores + numbers + key, one row per image), a summary, and results
77
+ tables: `per_neuron.csv` (one row per animal and neuron, for plotting), `penetrance.csv` (animals with
78
+ 0, 1, 2 ... affected neurons) and `fisher_tests.csv` (Fisher's exact within each microscope,
79
+ Bonferroni-corrected). Set `unblinding.reference_genotype` in `config.json` to test against a control.
80
+ Optional, off unless set in `unblinding`: `question_outcomes` turns the per-neuron questions into
81
+ the same penetrance and Fisher tables (for example "process defect" when a dendrite question is
82
+ answered "no"), and `interaction` tests a double mutant against the value two single mutants predict
83
+ (Product model by default) with a binomial test. Also optional: a secondary definition of "affected"
84
+ (descriptive, within one microscope), planned comparisons, one-sided tests, labelled sources, and
85
+ comparisons across microscopes for chosen measures (with warnings). All of these are recorded as an
86
+ analysis plan before scoring and locked once scoring starts. See [docs/METHODS.md](https://github.com/arjunkai/wormscore/blob/main/docs/METHODS.md#8-unblinding).
87
+ `methods_text.md` is a draft Methods paragraph on blinding, measurement and statistics; fill in the
88
+ `blinding` section of `config.json` (who coded, who scored) or edit the [brackets] it leaves.
89
+
90
+ ## Project folder
91
+
92
+ | Path | Contents | Open while scoring? |
93
+ |---|---|---|
94
+ | `config.json` | every parameter | yes |
95
+ | `log.md` | every run: parameters, software versions, counts | yes |
96
+ | `outputs/manifest.csv`, `inventory.csv`, `excluded.csv` | what was found and what was left out | yes |
97
+ | `outputs/auto_measurements.csv` | numbers for suggested spots | avoid until done |
98
+ | `blind/` | images for scoring, named by code | used by the app |
99
+ | `scoring/` | your scores, regions and their measurements | scores yes; avoid `roi_measurements.csv` |
100
+ | `key/` | code to file, genotype, settings | **no, not until scoring is finished** |
101
+
102
+ ## How it works
103
+
104
+ See [docs/METHODS.md](https://github.com/arjunkai/wormscore/blob/main/docs/METHODS.md) for every step in plain language, suitable for adapting into
105
+ a Methods section, including the measurement definitions and their limits.
106
+
107
+ ## Development
108
+
109
+ ```
110
+ pip install -e .[dev]
111
+ pytest
112
+ ```
113
+
114
+ The tests build a simulated project and check the measurements, the blinding (no genotype or file
115
+ name reaches the scoring page), code stability, the unblinding locks and traceability. Leica and
116
+ Zeiss readers are checked against real files locally; real images are never committed.
117
+
118
+ Build the Windows app: `packaging\build_windows.bat`.
119
+
120
+ ## Privacy
121
+
122
+ This repository contains code only. `.gitignore` excludes image formats, keys, scores and outputs.
123
+ Do not commit or upload data that belongs to someone else.
124
+
125
+ ## License and citation
126
+
127
+ MIT License (see [LICENSE](https://github.com/arjunkai/wormscore/blob/main/LICENSE)). If you use wormscore in research, please cite it: GitHub's
128
+ "Cite this repository" button (from [CITATION.cff](https://github.com/arjunkai/wormscore/blob/main/CITATION.cff)) gives the reference.
129
+
130
+ wormscore reads Leica files with [liffile](https://github.com/cgohlke/liffile) and Zeiss files with
131
+ [czifile](https://github.com/cgohlke/czifile) (both BSD-3). The Windows app bundles these and other
132
+ libraries; their licenses are in `THIRD_PARTY_LICENSES.txt` next to `wormscore.exe`.
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "wormscore"
7
+ version = "0.6.1"
8
+ description = "Blind scoring of fluorescent neurons in C. elegans confocal stacks, with measurement and genetics statistics."
9
+ keywords = ["C. elegans", "worm", "neuron", "blind scoring", "fluorescence", "microscopy", "confocal", "penetrance"]
10
+ readme = "README.md"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Arjun Bansal" }]
14
+ requires-python = ">=3.12"
15
+ classifiers = [
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Science/Research",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Topic :: Scientific/Engineering :: Bio-Informatics",
21
+ "Topic :: Scientific/Engineering :: Image Processing",
22
+ ]
23
+ dependencies = [
24
+ "numpy>=1.26",
25
+ "scipy>=1.11",
26
+ "pillow>=10",
27
+ "liffile>=2026.10.14",
28
+ "czifile>=2026.10.14",
29
+ "tifffile>=2024.1",
30
+ "imagecodecs>=2024.1",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/arjunkai/wormscore"
35
+ Documentation = "https://github.com/arjunkai/wormscore/blob/main/docs/METHODS.md"
36
+ Issues = "https://github.com/arjunkai/wormscore/issues"
37
+ Releases = "https://github.com/arjunkai/wormscore/releases"
38
+
39
+ [project.optional-dependencies]
40
+ dev = ["pytest>=8", "pyinstaller>=6.10"]
41
+
42
+ [project.scripts]
43
+ wormscore = "wormscore.cli:main"
44
+
45
+ [project.gui-scripts]
46
+ wormscore-launcher = "wormscore.launcher:main"
47
+
48
+ [tool.setuptools.packages.find]
49
+ where = ["src"]
50
+
51
+ [tool.setuptools.package-data]
52
+ wormscore = ["static/*"]
53
+
54
+ [tool.pytest.ini_options]
55
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """wormscore: blind scoring and fluorescence measurement of neurons in confocal stacks."""
2
+
3
+ __version__ = "0.6.1"
@@ -0,0 +1,81 @@
1
+ """Command line: wormscore <command> <project folder> ..."""
2
+ import argparse
3
+ import json
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ from . import __version__
8
+
9
+
10
+ def main(argv=None):
11
+ p = argparse.ArgumentParser(prog="wormscore", description="Blind scoring and measurement of neurons in confocal stacks.")
12
+ p.add_argument("--version", action="version", version=f"wormscore {__version__}")
13
+ sub = p.add_subparsers(dest="cmd", required=True)
14
+
15
+ s = sub.add_parser("init", help="create a project folder with a config.json to edit")
16
+ s.add_argument("project")
17
+ s.add_argument("--name", default="My project")
18
+ s = sub.add_parser("demo", help="create a demo project with simulated worms")
19
+ s.add_argument("project")
20
+ s.add_argument("--n", type=int, default=10, help="simulated worms per genotype")
21
+ s.add_argument("--real", action="store_true",
22
+ help="download 4 real worm heads (about 150 MB, CC BY 4.0) instead of simulating")
23
+ s = sub.add_parser("copy", help="copy a data folder and verify every file by SHA-256")
24
+ s.add_argument("source")
25
+ s.add_argument("destination")
26
+ s = sub.add_parser("inventory", help="list every file and image in the project's sources")
27
+ s.add_argument("project")
28
+ s = sub.add_parser("prepare", help="build the blind image set, key and automatic measurements")
29
+ s.add_argument("project")
30
+ s.add_argument("--reassign-codes", action="store_true", help="new codes (only allowed before any scoring)")
31
+ s.add_argument("--add-new-images", dest="add", action="store_true",
32
+ help="code only images not yet in the key; existing codes are kept")
33
+ s = sub.add_parser("app", help="open the scoring app")
34
+ s.add_argument("project")
35
+ s.add_argument("--port", type=int, default=8765)
36
+ s.add_argument("--no-browser", action="store_true")
37
+ s = sub.add_parser("unblind", help="join scores, measurements and the key (after scoring)")
38
+ s.add_argument("project")
39
+ s.add_argument("--i-have-finished-scoring", dest="finished", action="store_true")
40
+ s.add_argument("--anyway", action="store_true", help="unblind below the planned minimum number of scores")
41
+
42
+ a = p.parse_args(argv)
43
+ try:
44
+ if a.cmd == "init":
45
+ from .config import template
46
+ proj = Path(a.project)
47
+ proj.mkdir(parents=True, exist_ok=True)
48
+ cfg = proj / "config.json"
49
+ if cfg.exists():
50
+ sys.exit(f"{cfg} already exists; not overwriting.")
51
+ cfg.write_text(json.dumps(template(a.name), indent=2), encoding="utf-8")
52
+ print(f"Created {cfg}. Edit 'sources' to point at your images, then run 'wormscore inventory {proj}'.")
53
+ elif a.cmd == "demo":
54
+ if a.real:
55
+ from .realdemo import make_real_demo
56
+ make_real_demo(a.project)
57
+ else:
58
+ from .demo import make_demo
59
+ make_demo(a.project, n_per_group=a.n)
60
+ print(f"Next: wormscore inventory {a.project} && wormscore prepare {a.project} && wormscore app {a.project}")
61
+ elif a.cmd == "copy":
62
+ from .copydata import copy_verified
63
+ copy_verified(a.source, a.destination)
64
+ elif a.cmd == "inventory":
65
+ from .pipeline import inventory
66
+ inventory(a.project)
67
+ elif a.cmd == "prepare":
68
+ from .pipeline import prepare
69
+ prepare(a.project, reassign=a.reassign_codes, add=a.add)
70
+ elif a.cmd == "app":
71
+ from .server import serve
72
+ serve(a.project, port=a.port, open_browser=not a.no_browser)
73
+ elif a.cmd == "unblind":
74
+ from .unblind import unblind
75
+ unblind(a.project, finished=a.finished, anyway=a.anyway)
76
+ except FileNotFoundError as exc:
77
+ sys.exit(str(exc))
78
+
79
+
80
+ if __name__ == "__main__":
81
+ main()