Mercurial > repos > bgruening > cp_identify_primary_objects
comparison track_objects.py @ 4:993faa34333b draft
"planemo upload for repository https://github.com/bgruening/galaxytools/tree/master/tools commit 35da2dcd86747c9bff138e100dbe08c6106f3780"
author | bgruening |
---|---|
date | Sat, 06 Feb 2021 09:57:35 +0000 |
parents | |
children | b6eec6087271 |
comparison
equal
deleted
inserted
replaced
3:52c01fb29b2a | 4:993faa34333b |
---|---|
1 #!/usr/bin/env python | |
2 | |
3 import argparse | |
4 import json | |
5 | |
6 from cp_common_functions import get_json_value | |
7 from cp_common_functions import get_pipeline_lines | |
8 from cp_common_functions import get_total_number_of_modules | |
9 from cp_common_functions import INDENTATION | |
10 from cp_common_functions import update_module_count | |
11 from cp_common_functions import write_pipeline | |
12 | |
13 MODULE_NAME = "TrackObjects" | |
14 OUTPUT_FILENAME = "output.cppipe" | |
15 | |
16 | |
17 def build_header(module_name, module_number): | |
18 result = "|".join([f"{module_name}:[module_num:{module_number}", | |
19 "svn_version:\\'Unknown\\'", | |
20 "variable_revision_number:7", | |
21 "show_window:True", | |
22 "notes:\\x5B\\'Track the embryos across images using the Overlap method\\x3A tracked objects are identified by the amount of frame-to-frame overlap. Save an image of embryos labeled with a unique number across time.\\'\\x5D", | |
23 "batch_state:array(\\x5B\\x5D, dtype=uint8)", | |
24 "enabled:True", | |
25 "wants_pause:False]\n"]) | |
26 return result | |
27 | |
28 | |
29 def build_main_block(input_params): | |
30 result = INDENTATION.join([f"{INDENTATION}Choose a tracking method:{get_json_value(input_params,'con_tracking_method.tracking_method')}\n", | |
31 f"Select the objects to track:{get_json_value(input_params,'object_to_track')}\n" | |
32 ]) | |
33 | |
34 tracking_method = get_json_value(input_params, 'con_tracking_method.tracking_method') | |
35 | |
36 obj_measurement = "None" # default value | |
37 if tracking_method == "Measurements": | |
38 measurement_category = get_json_value(input_params, 'con_tracking_method.con_measurement_category.measurement_category') | |
39 measurement = get_json_value(input_params, 'con_tracking_method.con_measurement_category.measurement') | |
40 | |
41 if measurement_category == "Intensity" or measurement_category == "Location": | |
42 img_measure = get_json_value(input_params, 'con_tracking_method.con_measurement_category.img_measure') | |
43 obj_measurement = f"{measurement_category}_{measurement}_{img_measure}" | |
44 else: | |
45 obj_measurement = f"{measurement_category}_{measurement}" | |
46 | |
47 result += INDENTATION.join([f"{INDENTATION}Select object measurement to use for tracking:{obj_measurement}\n"]) | |
48 | |
49 if tracking_method == "LAP": # no max distance required, set default for pipeline | |
50 max_distance = 50 | |
51 else: | |
52 max_distance = get_json_value(input_params, 'con_tracking_method.max_distance') | |
53 | |
54 result += INDENTATION.join([f"{INDENTATION}Maximum pixel distance to consider matches:{max_distance}\n"]) | |
55 | |
56 display_option = get_json_value(input_params, 'con_tracking_method.display_option') | |
57 | |
58 output_img_name = "TrackedCells" # default value, required by cppipe regardless of its presence in UI | |
59 save = get_json_value(input_params, 'con_tracking_method.con_save_coded_img.save_coded_img') | |
60 if save == "Yes": | |
61 output_img_name = get_json_value(input_params, 'con_tracking_method.con_save_coded_img.name_output_img') | |
62 | |
63 result += INDENTATION.join( | |
64 [f"{INDENTATION}Select display option:{display_option}\n", | |
65 f"Save color-coded image?:{save}\n", | |
66 f"Name the output image:{output_img_name}\n" | |
67 ]) | |
68 | |
69 # LAP method default values | |
70 movement_model = "Both" | |
71 no_std = 3.0 | |
72 radius_limit_max = 10.0 | |
73 radius_limit_min = 2.0 | |
74 radius = "2.0,10.0" | |
75 run_second = "Yes" | |
76 gap_closing = 40 | |
77 split_alt = 40 | |
78 merge_alt = 40 | |
79 max_gap_displacement = 5 | |
80 max_split = 50 | |
81 max_merge = 50 | |
82 max_temporal = 5 | |
83 max_mitosis_dist = 40 | |
84 mitosis_alt = 80 | |
85 | |
86 # LAP method | |
87 if tracking_method == "LAP": | |
88 movement_model = get_json_value(input_params, 'con_tracking_method.movement_method') | |
89 no_std = get_json_value(input_params, 'con_tracking_method.no_std_radius') | |
90 radius_limit_max = get_json_value(input_params, 'con_tracking_method.max_radius') | |
91 radius_limit_min = get_json_value(input_params, 'con_tracking_method.min_radius') | |
92 radius = f"{radius_limit_min},{radius_limit_max}" | |
93 | |
94 run_second = get_json_value(input_params, 'con_tracking_method.con_second_lap.second_lap') | |
95 if run_second == "Yes": | |
96 gap_closing = get_json_value(input_params, 'con_tracking_method.con_second_lap.gap_closing') | |
97 split_alt = get_json_value(input_params, 'con_tracking_method.con_second_lap.split_alt') | |
98 merge_alt = get_json_value(input_params, 'con_tracking_method.con_second_lap.merge_alt') | |
99 max_gap_displacement = get_json_value(input_params, 'con_tracking_method.con_second_lap.max_gap_displacement') | |
100 max_split = get_json_value(input_params, 'con_tracking_method.con_second_lap.max_split') | |
101 max_merge = get_json_value(input_params, 'con_tracking_method.con_second_lap.max_merge') | |
102 max_temporal = get_json_value(input_params, 'con_tracking_method.con_second_lap.max_temporal') | |
103 max_mitosis_dist = get_json_value(input_params, 'con_tracking_method.con_second_lap.max_mitosis_distance') | |
104 mitosis_alt = get_json_value(input_params, 'con_tracking_method.con_second_lap.mitosis_alt') | |
105 | |
106 result += INDENTATION.join( | |
107 [f"{INDENTATION}Select the movement model:{movement_model}\n", | |
108 f"Number of standard deviations for search radius:{no_std}\n", | |
109 f"Search radius limit, in pixel units (Min,Max):{radius}\n", | |
110 f"Run the second phase of the LAP algorithm?:{run_second}\n", | |
111 f"Gap closing cost:{gap_closing}\n", | |
112 f"Split alternative cost:{split_alt}\n", | |
113 f"Merge alternative cost:{merge_alt}\n", | |
114 f"Maximum gap displacement, in pixel units:{max_gap_displacement}\n", | |
115 f"Maximum split score:{max_split}\n", | |
116 f"Maximum merge score:{max_merge}\n", | |
117 f"Maximum temporal gap, in frames:{max_temporal}\n" | |
118 ]) | |
119 | |
120 # common section | |
121 filter_by_lifetime = get_json_value(input_params, 'con_tracking_method.con_filter_by_lifetime.filter_by_lifetime') | |
122 use_min = "Yes" # default | |
123 min_life = 1 # default | |
124 use_max = "No" # default | |
125 max_life = 100 # default | |
126 | |
127 if filter_by_lifetime == "Yes": | |
128 use_min = get_json_value(input_params, 'con_tracking_method.con_filter_by_lifetime.con_use_min.use_min') | |
129 if use_min == "Yes": | |
130 min_life = get_json_value(input_params, 'con_tracking_method.con_filter_by_lifetime.con_use_min.min_lifetime') | |
131 | |
132 use_max = get_json_value(input_params, 'con_tracking_method.con_filter_by_lifetime.con_use_max.use_max') | |
133 if use_max == "Yes": | |
134 max_life = get_json_value(input_params, 'con_tracking_method.con_filter_by_lifetime.con_use_max.max_lifetime') | |
135 | |
136 result += INDENTATION.join( | |
137 [f"{INDENTATION}Filter objects by lifetime?:{filter_by_lifetime}\n", | |
138 f"Filter using a minimum lifetime?:{use_min}\n", | |
139 f"Minimum lifetime:{min_life}\n", | |
140 f"Filter using a maximum lifetime?:{use_max}\n", | |
141 f"Maximum lifetime:{max_life}\n" | |
142 ]) | |
143 | |
144 # print 2 leftover from LAP | |
145 result += INDENTATION.join( | |
146 [f"{INDENTATION}Mitosis alternative cost:{mitosis_alt}\n", | |
147 f"Maximum mitosis distance, in pixel units:{max_mitosis_dist}\n" | |
148 ]) | |
149 | |
150 # Follow Neighbors | |
151 # defaults | |
152 avg_cell_diameter = 35.0 | |
153 use_adv = "No" | |
154 cost_of_cell = 15.0 | |
155 weight_of_area_diff = 25.0 | |
156 | |
157 if tracking_method == "Follow Neighbors": | |
158 avg_cell_diameter = get_json_value(input_params, 'con_tracking_method.avg_diameter') | |
159 use_adv = get_json_value(input_params, 'con_tracking_method.con_adv_parameter.adv_parameter') | |
160 if use_adv == "Yes": | |
161 cost_of_cell = get_json_value(input_params, 'con_tracking_method.con_adv_parameter.cost') | |
162 weight_of_area_diff = get_json_value(input_params, 'con_tracking_method.con_adv_parameter.weight') | |
163 | |
164 result += INDENTATION.join( | |
165 [f"{INDENTATION}Average cell diameter in pixels:{avg_cell_diameter}\n", | |
166 f"Use advanced configuration parameters:{use_adv}\n", | |
167 f"Cost of cell to empty matching:{cost_of_cell}\n", | |
168 f"Weight of area difference in function matching cost:{weight_of_area_diff}\n" | |
169 ]) | |
170 | |
171 return result | |
172 | |
173 | |
174 if __name__ == "__main__": | |
175 parser = argparse.ArgumentParser() | |
176 parser.add_argument( | |
177 '-p', '--pipeline', | |
178 help='CellProfiler pipeline' | |
179 ) | |
180 parser.add_argument( | |
181 '-i', '--inputs', | |
182 help='JSON inputs from Galaxy' | |
183 ) | |
184 args = parser.parse_args() | |
185 | |
186 pipeline_lines = get_pipeline_lines(args.pipeline) | |
187 inputs_galaxy = json.load(open(args.inputs, "r")) | |
188 | |
189 current_module_num = get_total_number_of_modules(pipeline_lines) | |
190 current_module_num += 1 | |
191 pipeline_lines = update_module_count(pipeline_lines, current_module_num) | |
192 | |
193 header_block = build_header(MODULE_NAME, current_module_num) | |
194 main_block = build_main_block(inputs_galaxy) | |
195 | |
196 module_pipeline = f"\n{header_block}{main_block}\n" | |
197 pipeline_lines.append(module_pipeline) | |
198 | |
199 write_pipeline(OUTPUT_FILENAME, pipeline_lines) |