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 :])
0 commit comments