Skip to content

Commit 33b0d05

Browse files
committed
feat(starrynight: moduels): add sbs preprocess module
1 parent 8ade241 commit 33b0d05

File tree

7 files changed

+681
-0
lines changed

7 files changed

+681
-0
lines changed

starrynight/src/starrynight/modules/registry.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@
5555
from starrynight.modules.sbs_pre_segcheck.pre_segcheck_load_data import (
5656
SBSPreSegcheckGenLoadDataModule,
5757
)
58+
from starrynight.modules.sbs_preprocess.preprocess_cp import SBSPreprocessInvokeCPModule
59+
from starrynight.modules.sbs_preprocess.preprocess_cppipe import (
60+
SBSPreprocessGenCPPipeModule,
61+
)
62+
from starrynight.modules.sbs_preprocess.preprocess_load_data import (
63+
SBSPreprocessGenLoadDataModule,
64+
)
5865

5966
MODULE_REGISTRY: dict[str, StarrynightModule] = {
6067
# Generate inventory and index for the project
@@ -92,4 +99,8 @@
9299
SBSAlignGenLoadDataModule.uid(): SBSAlignGenLoadDataModule,
93100
SBSAlignGenCPPipeModule.uid(): SBSAlignGenCPPipeModule,
94101
SBSAlignInvokeCPModule.uid(): SBSAlignInvokeCPModule,
102+
# SBS preprocess
103+
SBSPreprocessGenLoadDataModule.uid(): SBSPreprocessGenLoadDataModule,
104+
SBSPreprocessGenCPPipeModule.uid(): SBSPreprocessGenCPPipeModule,
105+
SBSPreprocessInvokeCPModule.uid(): SBSPreprocessInvokeCPModule,
95106
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""SBS Preprocess."""
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
"""Constants for the module."""
2+
3+
SBS_PREPROCESS_OUT_PATH_SUFFIX = "preprocess/sbs/"
4+
SBS_PREPROCESS_CP_LOADDATA_OUT_PATH_SUFFIX = "cellprofiler/loaddata/sbs/preprocess"
5+
SBS_PREPROCESS_CP_CPPIPE_OUT_PATH_SUFFIX = "cellprofiler/cppipe/sbs/preprocess"
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
"""SBS preprocess invoke cellprofiler module."""
2+
3+
from pathlib import Path
4+
from typing import Self
5+
6+
from cloudpathlib import CloudPath
7+
from pipecraft.node import Container, ContainerConfig, UnitOfWork
8+
from pipecraft.pipeline import Pipeline, Seq
9+
10+
from starrynight.experiments.common import Experiment
11+
from starrynight.modules.common import StarrynightModule
12+
from starrynight.modules.sbs_preprocess.constants import (
13+
SBS_PREPROCESS_CP_CPPIPE_OUT_PATH_SUFFIX,
14+
SBS_PREPROCESS_CP_LOADDATA_OUT_PATH_SUFFIX,
15+
SBS_PREPROCESS_OUT_PATH_SUFFIX,
16+
)
17+
from starrynight.modules.schema import (
18+
Container as SpecContainer,
19+
)
20+
from starrynight.modules.schema import (
21+
ExecFunction,
22+
TypeAlgorithmFromCitation,
23+
TypeCitations,
24+
TypeEnum,
25+
TypeInput,
26+
TypeOutput,
27+
)
28+
from starrynight.schema import DataConfig
29+
30+
31+
def create_work_unit_gen_index(out_dir: Path | CloudPath) -> list[UnitOfWork]:
32+
"""Create units of work for Generate Index step.
33+
34+
Parameters
35+
----------
36+
out_dir : Path | CloudPath
37+
Path to load data csv. Can be local or cloud.
38+
39+
Returns
40+
-------
41+
list[UnitOfWork]
42+
List of unit of work.
43+
44+
"""
45+
uow_list = [
46+
UnitOfWork(
47+
inputs={
48+
"inventory": [out_dir.joinpath("inventory.parquet").resolve().__str__()]
49+
},
50+
outputs={"index": [out_dir.joinpath("index.parquet").resolve().__str__()]},
51+
)
52+
]
53+
54+
return uow_list
55+
56+
57+
def create_pipe_gen_cpinvoke(uid: str, spec: SpecContainer) -> Pipeline:
58+
"""Create pipeline for invoking cellprofiler.
59+
60+
Parameters
61+
----------
62+
uid: str
63+
Module unique id.
64+
spec: SpecContainer
65+
SBSPreprocessInvokeCPModule specification.
66+
67+
Returns
68+
-------
69+
Pipeline
70+
Pipeline instance.
71+
72+
"""
73+
cmd = [
74+
"starrynight",
75+
"cp",
76+
"-p",
77+
spec.inputs[0].path,
78+
"-l",
79+
spec.inputs[1].path,
80+
"-o",
81+
spec.outputs[0].path,
82+
"--sbs",
83+
]
84+
85+
gen_load_data_pipe = Seq(
86+
[
87+
Container(
88+
name=uid,
89+
input_paths={
90+
"cppipe_path": [spec.inputs[0].path],
91+
"load_data_path": [spec.inputs[1].path],
92+
},
93+
output_paths={"corr_images_dir": [spec.outputs[0].path]},
94+
config=ContainerConfig(
95+
image="ghrc.io/leoank/starrynight:dev",
96+
cmd=cmd,
97+
env={},
98+
),
99+
),
100+
]
101+
)
102+
return gen_load_data_pipe
103+
104+
105+
class SBSPreprocessInvokeCPModule(StarrynightModule):
106+
"""SBS Preprocess invoke cellprofiler module."""
107+
108+
@staticmethod
109+
def uid() -> str:
110+
"""Return module unique id."""
111+
return "sbs_preprocess_invoke_cp"
112+
113+
@staticmethod
114+
def _spec() -> str:
115+
"""Return module default spec."""
116+
return SpecContainer(
117+
inputs=[
118+
TypeInput(
119+
name="cppipe_path",
120+
type=TypeEnum.files,
121+
description="Path to the cppipe file.",
122+
optional=False,
123+
path="path/to/the/cppipe",
124+
),
125+
TypeInput(
126+
name="load_data_path",
127+
type=TypeEnum.files,
128+
description="Path to the LoadData csv.",
129+
optional=False,
130+
path="path/to/the/loaddata",
131+
),
132+
],
133+
outputs=[
134+
TypeOutput(
135+
name="path to compensated images",
136+
type=TypeEnum.files,
137+
description="Compensated images after preprocessing",
138+
optional=False,
139+
path="random/path/to/corrected images",
140+
),
141+
TypeOutput(
142+
name="cppipe_notebook",
143+
type=TypeEnum.notebook,
144+
description="Notebook for inspecting illum corrections",
145+
optional=False,
146+
path="http://karkinos:2720/?file=.%2FillumSBSApplyOutput.py",
147+
),
148+
],
149+
parameters=[],
150+
display_only=[],
151+
results=[],
152+
exec_function=ExecFunction(
153+
name="",
154+
script="",
155+
module="",
156+
cli_command="",
157+
),
158+
docker_image=None,
159+
algorithm_folder_name=None,
160+
citations=TypeCitations(
161+
algorithm=[
162+
TypeAlgorithmFromCitation(
163+
name="Starrynight SBS Preprocess invoke cellprofiler module",
164+
description="This module invoke cellprofiler for sbs preprocess.",
165+
)
166+
]
167+
),
168+
)
169+
170+
@staticmethod
171+
def from_config(
172+
data: DataConfig,
173+
experiment: Experiment | None = None,
174+
spec: SpecContainer | None = None,
175+
) -> Self:
176+
"""Create module from experiment and data config."""
177+
if spec is None:
178+
spec = SBSPreprocessInvokeCPModule._spec()
179+
spec.inputs[0].path = (
180+
data.workspace_path.joinpath(SBS_PREPROCESS_CP_CPPIPE_OUT_PATH_SUFFIX)
181+
.resolve()
182+
.__str__()
183+
)
184+
185+
spec.inputs[1].path = (
186+
data.workspace_path.joinpath(SBS_PREPROCESS_CP_LOADDATA_OUT_PATH_SUFFIX)
187+
.resolve()
188+
.__str__()
189+
)
190+
191+
spec.outputs[0].path = (
192+
data.workspace_path.joinpath(SBS_PREPROCESS_OUT_PATH_SUFFIX)
193+
.resolve()
194+
.__str__()
195+
)
196+
pipe = create_pipe_gen_cpinvoke(
197+
uid=SBSPreprocessInvokeCPModule.uid(),
198+
spec=spec,
199+
)
200+
uow = create_work_unit_gen_index(out_dir=data.storage_path.joinpath("index"))
201+
202+
return SBSPreprocessInvokeCPModule(spec=spec, pipe=pipe, uow=uow)

0 commit comments

Comments
 (0)