mcmicroprep 0.1.0__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.
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.1
2
+ Name: mcmicroprep
3
+ Version: 0.1.0
4
+ Summary:
5
+ Author: Ajit Johnson Nirmal
6
+ Author-email: ajitjohnson.n@gmail.com
7
+ Requires-Python: >=3.10,<4.0
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Requires-Dist: lxml (>=6.0.0,<7.0.0)
12
+ Requires-Dist: ome-types (>=0.6.1,<0.7.0)
13
+ Requires-Dist: pandas (>=2.3.1,<3.0.0)
14
+ Requires-Dist: pydantic (>=2.11.7,<3.0.0)
15
+ Description-Content-Type: text/markdown
16
+
17
+ # ๐Ÿงช mcmicroprep ๐Ÿš€
18
+
19
+ A **command-line tool** for preparing multiplexed imaging datasets (๐Ÿฆ  Olympus, ๐Ÿฉธ RareCyte) for the MCMICRO Nextflow pipeline.
20
+
21
+
22
+ ## ๐Ÿ› ๏ธ Installation
23
+
24
+ 1. **Prerequisites**
25
+
26
+ - Conda or Miniconda installed ๐Ÿ
27
+ - Python **3.10+** environment ๐ŸŒŸ
28
+ - SLURM & Nextflow (`labsyspharm/mcmicro`) on your `$PATH`
29
+
30
+ 2. **Create Conda env**
31
+
32
+ ```bash
33
+ conda create -n mcmicroprep python=3.12
34
+ conda activate mcmicroprep
35
+ ```
36
+
37
+ 3. **Install package**
38
+
39
+ ```bash
40
+ pip install mcmicroprep
41
+ ```
42
+
43
+ ## ๐Ÿ“ Expected Dataset Structure
44
+
45
+ Your dataset root should contain one subdirectory per slide. Structures vary by vendor:
46
+
47
+ ### ๐Ÿฆ  Olympus
48
+
49
+ Each *slide directory* must contain at least one `*_frames/` folder โ€”-- this is the minimum required structure. Additional files or folders may be present and do not need to be removed.
50
+
51
+ ```
52
+ .DATASET FOLDER
53
+ โ”œโ”€โ”€ slide1/
54
+ โ”‚ โ”œโ”€โ”€ image1_frames/
55
+ โ”‚ โ”œโ”€โ”€ image2_frames/
56
+ โ”œโ”€โ”€ slide2/
57
+ โ””โ”€โ”€ slideN/
58
+ ```
59
+
60
+ After running for **Olympus**: each slide/image folder would be as follows
61
+
62
+ ```
63
+ slide1/
64
+ โ”œโ”€โ”€ raw/ # image1_frames/, image2_frames/
65
+ โ”œโ”€โ”€ misc_files/ # JSON, logs
66
+ โ”œโ”€โ”€ batch_submission.sh # pipeline wrapper
67
+ โ”œโ”€โ”€ mcmicro_template.sh # Nextflow template
68
+ โ”œโ”€โ”€ base.config
69
+ โ”œโ”€โ”€ markers.csv
70
+ โ””โ”€โ”€ params.yml
71
+ ```
72
+
73
+ ### ๐Ÿฉธ RareCyte
74
+
75
+ Slide dirs may contain `*.rcpnl` at any depth: โ€”-- this is the minimum required structure. Additional files or folders may be present and do not need to be removed.
76
+
77
+ ```
78
+ /path/to/dataset/
79
+ โ”œโ”€โ”€ slide1/
80
+ โ”‚ โ”œโ”€โ”€ img001.rcpnl
81
+ โ”‚ โ”œโ”€โ”€ subA/img002.rcpnl
82
+ โ”‚ โ””โ”€โ”€ other files
83
+ โ””โ”€โ”€ slideN/
84
+ ```
85
+
86
+ After running for **RareCyte**:
87
+
88
+ ```
89
+ slide1/
90
+ โ”œโ”€โ”€ raw/ # all .rcpnl files
91
+ โ”‚ โ”œโ”€โ”€ img001.rcpnl
92
+ โ”‚ โ””โ”€โ”€ img002.rcpnl
93
+ โ”œโ”€โ”€ misc_files/ # CSV, text
94
+ โ”œโ”€โ”€ batch_submission.sh
95
+ โ”œโ”€โ”€ mcmicro_template.sh
96
+ โ”œโ”€โ”€ base.config
97
+ โ”œโ”€โ”€ markers.csv
98
+ โ””โ”€โ”€ params.yml
99
+ ```
100
+
101
+ ## ๐Ÿš€ Usage
102
+
103
+ > **Note**: Configured for the HMS O2 cluster (SLURM). Generalize by editing SLURM directives in `templates/common/`.
104
+
105
+ ### ๐Ÿฆ  Olympus
106
+
107
+ ```bash
108
+ preparemcmicro \
109
+ --microscope olympus \
110
+ --image-root /path/to/dataset
111
+ ```
112
+
113
+ ### ๐Ÿฉธ RareCyte
114
+
115
+ ```bash
116
+ preparemcmicro \
117
+ --microscope rarecyte \
118
+ --image-root /path/to/dataset
119
+ ```
120
+
121
+ ## ๐Ÿ› ๏ธ Next Steps for Users
122
+
123
+ 1. โœ๏ธ **Edit **`` in each slide directory to include your experiment-specific cycle-to-marker mappings.
124
+ 2. ๐Ÿ“ค **Upload** the entire processed dataset folder to the O2 cluster if you ran this locally.
125
+ 3. ๐Ÿš€ **Start the job** on O2:
126
+ ```bash
127
+ cd /n/scratch/users/USERNAME/<DATASET FOLDER>
128
+ bash batch_submission.sh --dataset_path /n/scratch/users/USERNAME/<DATASET FOLDER>
129
+ ```
130
+
131
+ Happy processing! ๐Ÿ”ฌ
132
+
133
+
@@ -0,0 +1,116 @@
1
+ # ๐Ÿงช mcmicroprep ๐Ÿš€
2
+
3
+ A **command-line tool** for preparing multiplexed imaging datasets (๐Ÿฆ  Olympus, ๐Ÿฉธ RareCyte) for the MCMICRO Nextflow pipeline.
4
+
5
+
6
+ ## ๐Ÿ› ๏ธ Installation
7
+
8
+ 1. **Prerequisites**
9
+
10
+ - Conda or Miniconda installed ๐Ÿ
11
+ - Python **3.10+** environment ๐ŸŒŸ
12
+ - SLURM & Nextflow (`labsyspharm/mcmicro`) on your `$PATH`
13
+
14
+ 2. **Create Conda env**
15
+
16
+ ```bash
17
+ conda create -n mcmicroprep python=3.12
18
+ conda activate mcmicroprep
19
+ ```
20
+
21
+ 3. **Install package**
22
+
23
+ ```bash
24
+ pip install mcmicroprep
25
+ ```
26
+
27
+ ## ๐Ÿ“ Expected Dataset Structure
28
+
29
+ Your dataset root should contain one subdirectory per slide. Structures vary by vendor:
30
+
31
+ ### ๐Ÿฆ  Olympus
32
+
33
+ Each *slide directory* must contain at least one `*_frames/` folder โ€”-- this is the minimum required structure. Additional files or folders may be present and do not need to be removed.
34
+
35
+ ```
36
+ .DATASET FOLDER
37
+ โ”œโ”€โ”€ slide1/
38
+ โ”‚ โ”œโ”€โ”€ image1_frames/
39
+ โ”‚ โ”œโ”€โ”€ image2_frames/
40
+ โ”œโ”€โ”€ slide2/
41
+ โ””โ”€โ”€ slideN/
42
+ ```
43
+
44
+ After running for **Olympus**: each slide/image folder would be as follows
45
+
46
+ ```
47
+ slide1/
48
+ โ”œโ”€โ”€ raw/ # image1_frames/, image2_frames/
49
+ โ”œโ”€โ”€ misc_files/ # JSON, logs
50
+ โ”œโ”€โ”€ batch_submission.sh # pipeline wrapper
51
+ โ”œโ”€โ”€ mcmicro_template.sh # Nextflow template
52
+ โ”œโ”€โ”€ base.config
53
+ โ”œโ”€โ”€ markers.csv
54
+ โ””โ”€โ”€ params.yml
55
+ ```
56
+
57
+ ### ๐Ÿฉธ RareCyte
58
+
59
+ Slide dirs may contain `*.rcpnl` at any depth: โ€”-- this is the minimum required structure. Additional files or folders may be present and do not need to be removed.
60
+
61
+ ```
62
+ /path/to/dataset/
63
+ โ”œโ”€โ”€ slide1/
64
+ โ”‚ โ”œโ”€โ”€ img001.rcpnl
65
+ โ”‚ โ”œโ”€โ”€ subA/img002.rcpnl
66
+ โ”‚ โ””โ”€โ”€ other files
67
+ โ””โ”€โ”€ slideN/
68
+ ```
69
+
70
+ After running for **RareCyte**:
71
+
72
+ ```
73
+ slide1/
74
+ โ”œโ”€โ”€ raw/ # all .rcpnl files
75
+ โ”‚ โ”œโ”€โ”€ img001.rcpnl
76
+ โ”‚ โ””โ”€โ”€ img002.rcpnl
77
+ โ”œโ”€โ”€ misc_files/ # CSV, text
78
+ โ”œโ”€โ”€ batch_submission.sh
79
+ โ”œโ”€โ”€ mcmicro_template.sh
80
+ โ”œโ”€โ”€ base.config
81
+ โ”œโ”€โ”€ markers.csv
82
+ โ””โ”€โ”€ params.yml
83
+ ```
84
+
85
+ ## ๐Ÿš€ Usage
86
+
87
+ > **Note**: Configured for the HMS O2 cluster (SLURM). Generalize by editing SLURM directives in `templates/common/`.
88
+
89
+ ### ๐Ÿฆ  Olympus
90
+
91
+ ```bash
92
+ preparemcmicro \
93
+ --microscope olympus \
94
+ --image-root /path/to/dataset
95
+ ```
96
+
97
+ ### ๐Ÿฉธ RareCyte
98
+
99
+ ```bash
100
+ preparemcmicro \
101
+ --microscope rarecyte \
102
+ --image-root /path/to/dataset
103
+ ```
104
+
105
+ ## ๐Ÿ› ๏ธ Next Steps for Users
106
+
107
+ 1. โœ๏ธ **Edit **`` in each slide directory to include your experiment-specific cycle-to-marker mappings.
108
+ 2. ๐Ÿ“ค **Upload** the entire processed dataset folder to the O2 cluster if you ran this locally.
109
+ 3. ๐Ÿš€ **Start the job** on O2:
110
+ ```bash
111
+ cd /n/scratch/users/USERNAME/<DATASET FOLDER>
112
+ bash batch_submission.sh --dataset_path /n/scratch/users/USERNAME/<DATASET FOLDER>
113
+ ```
114
+
115
+ Happy processing! ๐Ÿ”ฌ
116
+
File without changes
@@ -0,0 +1,105 @@
1
+ # %%
2
+ import dataclasses
3
+ import lxml.etree
4
+ import ome_types
5
+ import pandas as pd
6
+ import pathlib
7
+ import pydantic
8
+ import re
9
+ import sys
10
+ import uuid
11
+
12
+
13
+ # %%
14
+ @pydantic.validate_arguments
15
+ @dataclasses.dataclass
16
+ class AlignInfo:
17
+ version: str
18
+ unknown1: str
19
+ unknown2: str
20
+ unknown3: str
21
+ unknown4: str
22
+ pixel_size_x: float
23
+ pixel_size_y: float
24
+ tile_size_x: int
25
+ tile_size_y: int
26
+
27
+
28
+ # in_path = pathlib.Path(sys.argv[1])
29
+ # align_info_raw = re.split(r"\s+", (in_path / "AlignInfo").read_text().rstrip())
30
+ # replaced by ajit
31
+ def generate_companion_ome(in_path):
32
+ in_path = pathlib.Path(in_path)
33
+ align_info_raw = re.split(r"\s+", (in_path / "AlignInfo").read_text().rstrip())
34
+ assert align_info_raw[0] == "SAlignInfo2"
35
+ align_info = AlignInfo(*align_info_raw)
36
+
37
+ tree = lxml.etree.parse(in_path / "ScanSpace")
38
+ points = pd.read_xml(in_path / "ScanSpace", xpath="./vPoints/point")
39
+ # vInvSrtPrm maps point indices to field indices (.tif numbers).
40
+ points["field"] = [int(index.text) for index in tree.find("vInvSrtPrm")]
41
+ points = points.sort_values("field")
42
+ num_channels = int(tree.find("vOMs").attrib["n"])
43
+ channel_indices = list(range(num_channels))
44
+
45
+ ome = ome_types.OME()
46
+ field_groups = points.groupby("iAI", sort=False)
47
+ for _, plane_data in field_groups:
48
+ # Ensure we have all channels and they are already sorted.
49
+ assert list(plane_data.iOM) == channel_indices
50
+ channels = []
51
+ planes = []
52
+ tiff_data_blocks = []
53
+ for p in plane_data.itertuples():
54
+ channels.append(ome_types.model.Channel())
55
+ planes.append(
56
+ ome_types.model.Plane(
57
+ position_x=p.fStgX,
58
+ position_x_unit="ยตm",
59
+ position_y=p.fStgY,
60
+ position_y_unit="ยตm",
61
+ the_z=0,
62
+ the_t=0,
63
+ the_c=p.iOM,
64
+ ),
65
+ )
66
+ tiff_data_blocks.append(
67
+ ome_types.model.TiffData(
68
+ uuid=ome_types.model.TiffData.UUID(
69
+ file_name=f"{p.field}.tif",
70
+ value=uuid.uuid4().urn,
71
+ ),
72
+ first_c=p.iOM,
73
+ plane_count=1,
74
+ ),
75
+ )
76
+ pixels = ome_types.model.Pixels(
77
+ dimension_order="XYCZT",
78
+ type="uint16",
79
+ size_x=align_info.tile_size_x,
80
+ size_y=align_info.tile_size_y,
81
+ size_z=1,
82
+ size_c=num_channels,
83
+ size_t=1,
84
+ physical_size_x=align_info.pixel_size_x,
85
+ physical_size_x_unit="ยตm",
86
+ physical_size_y=align_info.pixel_size_y,
87
+ physical_size_y_unit="ยตm",
88
+ channels=channels,
89
+ planes=planes,
90
+ tiff_data_blocks=tiff_data_blocks,
91
+ )
92
+ image = ome_types.model.Image(pixels=pixels)
93
+ ome.images.append(image)
94
+
95
+ with open(in_path / "image.companion.ome", "w", encoding="utf-8") as f:
96
+ f.write(ome.to_xml())
97
+
98
+
99
+ def main(frames_path):
100
+ generate_companion_ome(frames_path)
101
+
102
+ if __name__ == "__main__":
103
+ import sys
104
+ main(sys.argv[1])
105
+
@@ -0,0 +1,40 @@
1
+ from pathlib import Path
2
+ import shutil
3
+ from mcmicroprep.microscopes.base import MicroscopeHandler
4
+
5
+
6
+ class CorePipeline:
7
+ def __init__(self, handler: MicroscopeHandler, image_root: Path):
8
+ self.handler = handler
9
+ self.image_root = Path(image_root)
10
+ self.templates = Path(__file__).parent / "templates"
11
+
12
+ def run(self):
13
+ # 1๏ธโƒฃ Organize raw imagery in-place
14
+ self.handler.restructure_raw(self.image_root)
15
+ # 2๏ธโƒฃ Enforce dataset structure (expect image_root to be the dataset root)
16
+ # No additional moving of slide folders; image_root should contain slide dirs directly.
17
+ # 3๏ธโƒฃ Generate boilerplate
18
+ self._generate_boilerplate()
19
+
20
+ def _generate_boilerplate(self):
21
+ # Copy common boilerplate templates
22
+ common = self.templates / "common"
23
+ for fname in [
24
+ "batch_submission.sh",
25
+ "mcmicro_template.sh",
26
+ "base.config",
27
+ "markers.csv",
28
+ ]:
29
+ src = common / fname
30
+ dst = self.image_root / fname
31
+ if not dst.exists():
32
+ shutil.copy(src, dst)
33
+ if dst.suffix == ".sh":
34
+ dst.chmod(dst.stat().st_mode | 0o111)
35
+
36
+ # Copy microscope-specific params YAML
37
+ params_src = self.templates / "params" / f"{self.handler.name}.yml"
38
+ params_dst = self.image_root / "params.yml"
39
+ if params_src.exists() and not params_dst.exists():
40
+ shutil.copy(params_src, params_dst)
File without changes
@@ -0,0 +1,18 @@
1
+ from abc import ABC, abstractmethod
2
+ from pathlib import Path
3
+
4
+ class MicroscopeHandler(ABC):
5
+ """
6
+ Base class for microscope-specific handlers.
7
+ """
8
+ name: str # e.g. 'olympus'
9
+
10
+ @abstractmethod
11
+ def restructure_raw(self, image_root: Path):
12
+ """Reorganize raw files into raw/ and misc_files/ in place."""
13
+ pass
14
+
15
+ @abstractmethod
16
+ def params_template(self) -> dict:
17
+ """(Optional) Return dict for param overrides; not used for file-based params."""
18
+ pass
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env python3
2
+ import subprocess
3
+ import sys
4
+ from pathlib import Path
5
+ from mcmicroprep.microscopes.base import MicroscopeHandler
6
+
7
+
8
+ class OlympusHandler(MicroscopeHandler):
9
+ name = "olympus"
10
+
11
+ def restructure_raw(self, image_root: Path):
12
+ for slide in image_root.iterdir():
13
+ if not slide.is_dir() or slide.name in [
14
+ "dataset",
15
+ "templates",
16
+ "microscopes",
17
+ ]:
18
+ continue
19
+ raw = slide / "raw"
20
+ misc = slide / "misc_files"
21
+ raw.mkdir(exist_ok=True)
22
+ misc.mkdir(exist_ok=True)
23
+
24
+ for item in list(slide.iterdir()):
25
+ if item.is_dir() and item.name.endswith("_frames"):
26
+ item.rename(raw / item.name)
27
+ elif item.name not in ["raw", "misc_files"]:
28
+ item.rename(misc / item.name)
29
+
30
+ # Only run companion script if missing the OME file
31
+ for frame in raw.iterdir():
32
+ ome = frame / "image.companion.ome"
33
+ if not ome.exists():
34
+ # Invoke installed module, not script in cwd
35
+ subprocess.run(
36
+ [
37
+ sys.executable,
38
+ "-m",
39
+ "mcmicroprep.companion_script",
40
+ str(frame),
41
+ ],
42
+ check=True,
43
+ )
44
+
45
+ def params_template(self) -> dict:
46
+ # Not used when file-based params selection is preferred
47
+ return {}
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env python3
2
+ from pathlib import Path
3
+ from mcmicroprep.microscopes.base import MicroscopeHandler
4
+
5
+
6
+ class RareCyteHandler(MicroscopeHandler):
7
+ name = "rarecyte"
8
+
9
+ def restructure_raw(self, image_root: Path):
10
+ for slide in image_root.iterdir():
11
+ if not slide.is_dir() or slide.name in ["templates", "microscopes"]:
12
+ continue
13
+ raw = slide / "raw"
14
+ misc = slide / "misc_files"
15
+ raw.mkdir(exist_ok=True)
16
+ misc.mkdir(exist_ok=True)
17
+
18
+ # Flatten: move all .rcpnl files directly into raw/
19
+ for path in slide.rglob("*.rcpnl"):
20
+ if raw in path.parents or misc in path.parents:
21
+ continue
22
+ dest = raw / path.name
23
+ path.rename(dest)
24
+
25
+ # Move all other top-level items to misc_files/
26
+ for item in list(slide.iterdir()):
27
+ if item.name not in ["raw", "misc_files"]:
28
+ item.rename(misc / item.name)
29
+
30
+ def params_template(self) -> dict:
31
+ return {}
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env python3
2
+ import argparse
3
+ from pathlib import Path
4
+ from mcmicroprep.core import CorePipeline
5
+ from mcmicroprep.microscopes.olympus import OlympusHandler
6
+ from mcmicroprep.microscopes.rarecyte import RareCyteHandler
7
+
8
+ HANDLERS = {
9
+ "olympus": OlympusHandler,
10
+ "rarecyte": RareCyteHandler,
11
+ # add more handlers here
12
+ }
13
+
14
+
15
+ def main():
16
+ parser = argparse.ArgumentParser("Prepare data for MCMicro")
17
+ parser.add_argument(
18
+ "--microscope",
19
+ choices=HANDLERS,
20
+ required=True,
21
+ help="Microscope vendor (e.g., olympus, rarecyte)",
22
+ )
23
+ parser.add_argument(
24
+ "--image-root", required=True, help="Root folder containing slide directories"
25
+ )
26
+ args = parser.parse_args()
27
+
28
+ handler = HANDLERS[args.microscope]()
29
+ pipeline = CorePipeline(handler, Path(args.image_root))
30
+ pipeline.run()
31
+
32
+
33
+ if __name__ == "__main__":
34
+ main()
@@ -0,0 +1,28 @@
1
+ process {
2
+ withName:illumination {
3
+ cpus = 4
4
+ time = '12h'
5
+ }
6
+ withName:ashlar {
7
+ cpus = 1
8
+ time = '36h'
9
+ queue = 'medium'
10
+ }
11
+ withName: 'segmentation:worker' {
12
+ time = '2h'
13
+ queue = 'gpu_quad'
14
+ }
15
+ withName:s3seg {
16
+ cpus = 4
17
+ time = '2h'
18
+ }
19
+ withName:mcquant {
20
+ cpus = 1
21
+ queue = 'medium'
22
+ time = '96h'
23
+ }
24
+ }
25
+
26
+ report {
27
+ enabled = false
28
+ }
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+
3
+ # Parse arguments
4
+ OPTS=$(getopt -o "" --long dataset_path:,mcmicro_template:,markers_csv:,params_yml: -n 'submission.sh' -- "$@")
5
+
6
+ if [ $? != 0 ]; then
7
+ echo "Failed parsing options." >&2
8
+ exit 1
9
+ fi
10
+
11
+ eval set -- "$OPTS"
12
+
13
+ dataset_path=""
14
+ mcmicro_template=""
15
+ markers_csv=""
16
+ params_yml=""
17
+
18
+ # Extract arguments
19
+ while true; do
20
+ case "$1" in
21
+ --dataset_path ) dataset_path="$2"; shift 2 ;;
22
+ --mcmicro_template ) mcmicro_template="$2"; shift 2 ;;
23
+ --markers_csv ) markers_csv="$2"; shift 2 ;;
24
+ --params_yml ) params_yml="$2"; shift 2 ;;
25
+ -- ) shift; break ;;
26
+ * ) break ;;
27
+ esac
28
+ done
29
+
30
+ # Check dataset_path
31
+ if [[ -z "$dataset_path" || ! -d "$dataset_path" ]]; then
32
+ echo "Error: dataset_path is required and must exist: $dataset_path"
33
+ exit 1
34
+ fi
35
+
36
+ # Assign default paths if optional ones are not provided
37
+ if [[ -z "$mcmicro_template" ]]; then
38
+ mcmicro_template="${dataset_path%/}/mcmicro_template.sh"
39
+ echo "No mcmicro_template provided. Using default: $mcmicro_template"
40
+ fi
41
+
42
+ if [[ -z "$markers_csv" ]]; then
43
+ markers_csv="${dataset_path%/}/markers.csv"
44
+ echo "No markers_csv provided. Using default: $markers_csv"
45
+ fi
46
+
47
+ if [[ -z "$params_yml" ]]; then
48
+ params_yml="${dataset_path%/}/params.yml"
49
+ echo "No params_yml provided. Using default: $params_yml"
50
+ fi
51
+
52
+ # Check that all necessary files exist now
53
+ if [[ ! -f "$mcmicro_template" ]]; then
54
+ echo "Error: mcmicro_template not found at $mcmicro_template"
55
+ exit 1
56
+ fi
57
+
58
+ if [[ ! -f "$markers_csv" ]]; then
59
+ echo "Error: markers_csv not found at $markers_csv"
60
+ exit 1
61
+ fi
62
+
63
+ if [[ ! -f "$params_yml" ]]; then
64
+ echo "Error: params_yml not found at $params_yml"
65
+ exit 1
66
+ fi
67
+
68
+ # Submit jobs for each raw folder
69
+ for raw_folder in "$dataset_path"/raw/*_frames; do
70
+ if [ -d "$raw_folder" ]; then
71
+ echo "Submitting job for: $raw_folder"
72
+ sbatch "$mcmicro_template" "$raw_folder"
73
+ fi
74
+ done
@@ -0,0 +1,5 @@
1
+ cycle,marker_name
2
+ 1,DNA
3
+ 1,Marker1
4
+ 1,Marker2
5
+ 1,Marker3
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+ #SBATCH -p short
3
+ #SBATCH -J nextflow_O2
4
+ #SBATCH -t 0-12:00
5
+ #SBATCH --mem=1G
6
+ #SBATCH --mail-type=END
7
+
8
+ SAMPLEDIR=$1
9
+ SAMPLEID=$(basename $SAMPLEDIR)
10
+
11
+ module purge
12
+ module load java
13
+
14
+ /n/groups/lsp/mcmicro/tools/o2/config_pre_reg.sh -s -u $SAMPLEDIR > $SAMPLEDIR/memory.config
15
+
16
+ nextflow run labsyspharm/mcmicro -profile O2,WSI,GPU --in $SAMPLEDIR -w /n/scratch/users/${USER:0:1}/$USER/work -c $(dirname "$SAMPLEDIR")/base.config -c $SAMPLEDIR/memory.config -publish_dir_mode link
@@ -0,0 +1,18 @@
1
+ workflow:
2
+ start-at: illumination
3
+ stop-at: quantification
4
+ background: false
5
+ segmentation-channel: 1 1
6
+ multi-formats: .ome
7
+ tma: false
8
+ options:
9
+ ashlar: --flip-y --filter-sigma 1
10
+ unmicst: --channel 1 --scalingFactor 0.5 --tool unmicst-duo --outlier 99.99
11
+ s3seg: --maxima-footprint-size 15 --area-max 50000 --expand-size 6 --pixelSize 0.325 --mean-intensity-min 80
12
+ mcquant: --masks nucleiRing.ome.tif cellRing.ome.tif cytoRing.ome.tif
13
+ coreograph: --channel 1
14
+ modules:
15
+ watershed:
16
+ name: s3seg
17
+ container: labsyspharm/s3segmenter
18
+ version: 1.5.5-large
@@ -0,0 +1,16 @@
1
+ workflow:
2
+ start-at: illumination
3
+ stop-at: quantification
4
+ background: false
5
+ segmentation-channel: 1 1
6
+ tma: false
7
+ options:
8
+ unmicst: --channel 1 --scalingFactor 0.5 --tool unmicst-duo --outlier 99.99
9
+ s3seg: --maxima-footprint-size 15 --area-max 50000 --expand-size 6 --pixelSize 0.325 --mean-intensity-min 80
10
+ mcquant: --masks nucleiRing.ome.tif cellRing.ome.tif cytoRing.ome.tif
11
+ coreograph: --channel 1
12
+ modules:
13
+ watershed:
14
+ name: s3seg
15
+ container: labsyspharm/s3segmenter
16
+ version: 1.5.5-large
@@ -0,0 +1,10 @@
1
+ # Base parameters for MCMicro workflow
2
+ illumination_correction:
3
+ method: default
4
+ segmentation:
5
+ method: default
6
+ markers:
7
+ # cycle: marker_name
8
+ # e.g., 1: DAPI
9
+ channels:
10
+ # channel-specific settings go here
@@ -0,0 +1,21 @@
1
+ [tool.poetry]
2
+ name = "mcmicroprep"
3
+ version = "0.1.0"
4
+ description = ""
5
+ authors = ["Ajit Johnson Nirmal <ajitjohnson.n@gmail.com>"]
6
+ readme = "README.md"
7
+
8
+ [tool.poetry.dependencies]
9
+ python = "^3.10"
10
+ lxml = "^6.0.0"
11
+ ome-types = "^0.6.1"
12
+ pandas = "^2.3.1"
13
+ pydantic = "^2.11.7"
14
+
15
+
16
+ [build-system]
17
+ requires = ["poetry-core"]
18
+ build-backend = "poetry.core.masonry.api"
19
+
20
+ [tool.poetry.scripts]
21
+ preparemcmicro = "mcmicroprep.preparemcmicro:main"