Skip to content

Commit 188f65c

Browse files
committed
first-pass at pipeline
1 parent 7e785e1 commit 188f65c

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"""Simple pipeline for computation and visualization of the illumination correction"""
2+
3+
import argparse
4+
import logging
5+
from pathlib import Path
6+
import sys
7+
from typing import Any, Iterable
8+
9+
from gertils import ExtantFile, ExtantFolder, NonExtantPath
10+
import pypiper
11+
12+
from compute_illumination_correction import workflow as compute_correction
13+
from visualize_scalings import workflow as visualize_correction
14+
15+
16+
NO_TEE_LOGS_OPTNAME = "--do-not-tee-logs"
17+
PIPE_NAME = "illumination_correction_computation"
18+
ZARR_NAME = "illumination_correction_scalings.zarr"
19+
20+
21+
class CorrectionComputationPipeline(pypiper.Pipeline):
22+
"""Pipeline to compute and visualize illumination correction weights/scalings"""
23+
def __init__(
24+
self,
25+
*,
26+
path_list_file: ExtantFile,
27+
output_root: ExtantFolder,
28+
version_name: str,
29+
pypiper_folder: ExtantFolder,
30+
**pl_mgr_kwargs: Any,
31+
) -> None:
32+
self.version_name = version_name
33+
self.weights_root = NonExtantPath(output_root / ZARR_NAME)
34+
self.visualization_folder = output_root / "visualization"
35+
with path_list_file.path.open(mode="r") as pathlist:
36+
self.input_paths: list[Path] = [Path(line.strip()) for line in pathlist.readlines() if line.strip()]
37+
super().__init__(name=PIPE_NAME, outfolder=str(pypiper_folder.path), **pl_mgr_kwargs)
38+
39+
def stages(self) -> list[pypiper.Stage]:
40+
return [
41+
pypiper.Stage(
42+
name="computation",
43+
func=compute_correction,
44+
f_kwargs={
45+
"base_paths": self.input_paths,
46+
"output_path": self.weights_root,
47+
"version_name": self.version_name,
48+
"overwrite": True,
49+
},
50+
),
51+
pypiper.Stage(
52+
name="visualization",
53+
func=visualize_correction,
54+
f_kwargs={
55+
"zarr_root": self.weights_root.path,
56+
"output_folder": self.visualization_folder,
57+
"overwrite": True,
58+
},
59+
)
60+
]
61+
62+
63+
def parse_cli(args: Iterable[str]) -> argparse.Namespace:
64+
parser = argparse.ArgumentParser(
65+
description="A pipeline to compute and visualize correction for uneven illumination across fields of view",
66+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
67+
)
68+
parser.add_argument(
69+
"--path-list-file",
70+
required=True,
71+
type=ExtantFile.from_string,
72+
help="Path to file listing the paths in which to find images",
73+
)
74+
parser.add_argument(
75+
"--output-root",
76+
required=True,
77+
type=Path,
78+
help="Path to folder in which to place main outputs",
79+
)
80+
parser.add_argument(
81+
"--version-name",
82+
required=True,
83+
help="Name for the version of the weights/scalings to be produced by this run of the program",
84+
)
85+
parser.add_argument(
86+
"--pypiper-folder",
87+
type=ExtantFolder.from_string,
88+
required=True,
89+
help="Path to folder for pypiper output",
90+
)
91+
parser.add_argument(
92+
NO_TEE_LOGS_OPTNAME,
93+
action="store_true",
94+
help="Do not tee logging output from pypiper manager",
95+
)
96+
parser = pypiper.add_pypiper_args(
97+
parser,
98+
groups=("pypiper", "checkpoint"),
99+
args=("start-point", ),
100+
)
101+
return parser.parse_args(args)
102+
103+
104+
def init(opts: argparse.Namespace) -> CorrectionComputationPipeline:
105+
kwargs = {
106+
"output_root": opts.output_root,
107+
"pypiper_folder": opts.pypiper_folder,
108+
}
109+
if opts.do_not_tee_logs:
110+
kwargs["multi"] = True
111+
logging.info(f"Building {PIPE_NAME} pipeline, using data listed in from {opts.path_list_file.path}")
112+
return CorrectionComputationPipeline(**kwargs)
113+
114+
115+
def main(cmdl):
116+
opts = parse_cli(cmdl)
117+
logging.basicConfig(level=logging.INFO, force=True)
118+
logging.info("Building pipeline")
119+
pipeline = init(opts)
120+
logging.info("Running pipeline")
121+
pipeline.run(start_point=opts.start_point, stop_after=opts.stop_after)
122+
pipeline.wrapup()
123+
124+
125+
if __name__ == "__main__":
126+
main(sys.argv[1:])

scripts/visualize_scalings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ def combine_error_messages(messages: Iterable[str]) -> str:
147147
)
148148
logging.info("Saving heatmap: %s", heatmap_file)
149149
plt.savefig(heatmap_file)
150-
plt.clf() # Clear the figure.
150+
plt.clf() # Clear the figure.
151151
# TODO: plot title, axes, with at least channel information and perhaps original image size.
152152
# TODO: consider also storing and visualizing statistics about the weights/scalings.
153153
logging.info("Done!")

0 commit comments

Comments
 (0)