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