epicure.concatenate_movie
1import napari 2from napari import current_viewer 3from magicgui import magicgui 4from napari.utils.history import get_save_history 5import pathlib 6import epicure.Utils as ut 7import numpy as np 8import os 9from skimage.measure import regionprops_table 10 11from epicure.epicuring import EpiCure 12from epicure.tracking import Tracking 13 14 15""" 16 Concatenate temporally two epicured movies (the intensity movie and the labels). 17 The last frame of the first movie should be the same as the first frame of the second movie. 18""" 19 20def merge_epicures( first_movie, first_labels, second_movie, second_labels, fullname="fullmovie.tif" ): 21 """ Do the concatenation """ 22 23 ## open the two intensity movies 24 ut.show_info("Reading and concatenating the intensity movies...") 25 26 print("Reading first movie and EpiCure files") 27 ## open the first movie and epicure data 28 first_epicure = EpiCure() 29 first_epicure.viewer = napari.Viewer(show=False) 30 first_epicure.load_movie( first_movie ) 31 first_epicure.go_epicure( "epics", first_labels ) 32 33 ## open the second movie 34 print("Reading second movie and EpiCure files") 35 second_epicure = EpiCure() 36 second_epicure.viewer = napari.Viewer(show=False) 37 second_epicure.load_movie( second_movie ) 38 second_epicure.go_epicure( "epics", second_labels ) 39 40 ## check that the last frame of first movie and first frame of second are the same 41 if np.sum(first_epicure.img[first_epicure.nframes-1] - second_epicure.img[0]) != 0: 42 ut.show_error("Error: the last frame of first movie is not the same of the first frame of the second movie, I cannot concatenate them.") 43 return 44 45 ## create the full movie 46 full_mov = np.concatenate( (first_epicure.img, second_epicure.img[1:]), axis=0 ) 47 full_movie_name = os.path.join(os.path.dirname(first_epicure.imgpath), fullname) 48 ut.writeTif( full_mov, full_movie_name, first_epicure.epi_metadata["ScaleXY"], first_epicure.img.dtype, what="Full movie") 49 print("Full movie created") 50 51 ###### Read and merge the EpiCure data and merge the movie labels 52 ut.show_info("Reading and concatenating the Epicured results...") 53 54 ### Create new EpiCure instance with the full movie 55 epic = EpiCure() 56 epic.viewer = napari.current_viewer() 57 epic.load_movie(full_movie_name) 58 epic.verbose = 1 59 epic.set_names( "epics" ) 60 61 ## initialize groups to first movie groups 62 epic.groups = first_epicure.groups 63 64 ## initialize tracks to first movie tracks 65 epic.tracking = Tracking(epic.viewer, epic) 66 epic.tracking.track_data = first_epicure.tracking.track_data 67 68 ## initialize track graph to first movie graph 69 if first_epicure.tracking.graph is not None: 70 epic.tracking.graph = first_epicure.tracking.graph 71 else: 72 epic.tracking.graph = {} 73 74 ### Now, work on the labels 75 76 ## track between last and first frame to associate the labels (can be a little different if corrections were done) 77 parent_labels, labels = ut.match_labels( first_epicure.seg[first_epicure.nframes-1], second_epicure.seg[0] ) 78 79 #### Update all the labels in the second movie to match with the first movie 80 nextlabels = first_epicure.get_free_labels(20) ## prepare a list of unused labels 81 used_labels = first_epicure.get_labels() 82 used_labels = used_labels + nextlabels 83 seconds = np.copy(second_epicure.seg) 84 seconds_lab = np.unique(seconds) 85 #second_tracks = np.copy(second_epicure.tracking.track_data) 86 if second_epicure.tracking.graph is None: 87 second_epicure.tracking.graph = {} 88 second_graph = second_epicure.tracking.graph.copy() 89 ## shift all values and keys in the graph, to be sure it's never the same 90 shift = np.max(second_epicure.seg)+1 91 keys = list(second_graph.keys()) 92 for key in keys: 93 val = second_graph.pop(key) 94 shift_val = [] 95 for v in val: 96 shift_val.append(v+shift) 97 second_graph[key+shift] = shift_val 98 99 for lab in seconds_lab: 100 if lab > 0: 101 newlab = None 102 if lab in labels: 103 newlab = parent_labels[labels.index(lab)] 104 #track_indexes = second_epicure.tracking.get_track_indexes( lab ) 105 ## Label from second movie has been associated to one from first movie 106 if newlab is not None: 107 ### If the label is in one group in first or second movie, update its info in full movie 108 fullmovie_group( epic, newlab, lab, second_epicure ) 109 np.place(second_epicure.seg, seconds==lab, newlab) 110 #second_tracks[track_indexes, 0] = newlab 111 if newlab is None: 112 ## Label is a new cell (not present in first movie) 113 nextlabel = nextlabels.pop(0) 114 np.place(second_epicure.seg, seconds==lab, nextlabel) 115 newlab = nextlabel 116 #second_tracks[track_indexes, 0] = nextlabel 117 ### add group information if there is one 118 if second_epicure.groups is not None: 119 second = second_epicure.find_group( lab ) 120 if second is not None: 121 epic.cells_ingroup( [nextlabel], second ) 122 if len(nextlabels) <= 0: 123 ## the list of unused labels has been completly used, regenerates 124 nextlabels = ut.get_free_labels( used_labels, 20 ) 125 used_labels = used_labels + nextlabels 126 127 # add division or merge if lab is in second movie graph 128 if (shift+lab) in second_graph.keys(): 129 second_graph[newlab] = second_graph[shift+lab] 130 for key, vals in second_graph.items(): 131 new_vals = [] 132 for val in vals: 133 if (shift+lab) == val: 134 new_vals.append( newlab ) 135 else: 136 new_vals.append( val ) 137 second_graph[key] = new_vals 138 139 ### merge the two graphs 140 for key, vals in second_graph.items(): 141 if key not in epic.tracking.graph.keys(): 142 epic.tracking.graph[key] = vals 143 else: 144 print("Key "+str(key)+" present in both graph, something might be wrong ") 145 146 ### Ok, save the results 147 full_lab = np.concatenate( (first_epicure.seg, second_epicure.seg[1:]), axis=0 ) 148 epic.seg = full_lab 149 epic.save_epicures() 150 print("Movie and EpiCure files merged; Suspects/Events (if any) are not merged, use inspect tracks on merged movie to generate them") 151 152def fullmovie_group( epic, first_label, second_label, second_epicure ): 153 """ Check if second_label is in a group, and add it to full movie groups if relevant """ 154 first_group = epic.find_group( first_label ) 155 second = None 156 if second_epicure.groups is not None: 157 second = second_epicure.find_group( second_label ) 158 if (first_group is not None) and (second is not None): 159 ### label is present in the two movie groups 160 if first_group != second: 161 print("Label "+str(first_label)+" classified in group "+(first_group)+" in the first movie and in group "+second+" in the second movie") 162 print("Keep only the first movie group: "+first_group) 163 else: 164 if second is not None: 165 epic.cells_ingroup( [first_label], second ) 166 167def concatenate_movies(): 168 hist = get_save_history() 169 cdir = hist[0] 170 viewer = current_viewer() 171 172 def choose_first_movie(): 173 """ First movie is chosen, suggest default labels file """ 174 first = get_files.first_movie.value 175 imgname, imgdir, out = ut.extract_names( first, "epics", mkdir=False ) 176 get_files.first_labels.value = pathlib.Path(out) 177 labname = ut.suggest_segfile(out, imgname) 178 if labname is not None: 179 get_files.first_labels.value = pathlib.Path(labname) 180 181 def choose_second_movie(): 182 """ Second movie is chosen, suggest default labels file """ 183 second = get_files.second_movie.value 184 imgname, imgdir, out = ut.extract_names( second, "epics", mkdir=False ) 185 get_files.second_labels.value = pathlib.Path(out) 186 labname = ut.suggest_segfile(out, imgname) 187 if labname is not None: 188 get_files.second_labels.value = pathlib.Path(labname) 189 190 @magicgui(call_button="Concatenate",) 191 def get_files( 192 first_movie = pathlib.Path(cdir), 193 first_labels = pathlib.Path(cdir), 194 second_movie = pathlib.Path(cdir), 195 second_labels = pathlib.Path(cdir), 196 merged_movie_name = "fullmovie.tif" 197 ): 198 merge_epicures( first_movie, first_labels, second_movie, second_labels, merged_movie_name) 199 return 200 201 get_files.first_movie.changed.connect(choose_first_movie) 202 get_files.second_movie.changed.connect(choose_second_movie) 203 return get_files
def
merge_epicures( first_movie, first_labels, second_movie, second_labels, fullname='fullmovie.tif'):
21def merge_epicures( first_movie, first_labels, second_movie, second_labels, fullname="fullmovie.tif" ): 22 """ Do the concatenation """ 23 24 ## open the two intensity movies 25 ut.show_info("Reading and concatenating the intensity movies...") 26 27 print("Reading first movie and EpiCure files") 28 ## open the first movie and epicure data 29 first_epicure = EpiCure() 30 first_epicure.viewer = napari.Viewer(show=False) 31 first_epicure.load_movie( first_movie ) 32 first_epicure.go_epicure( "epics", first_labels ) 33 34 ## open the second movie 35 print("Reading second movie and EpiCure files") 36 second_epicure = EpiCure() 37 second_epicure.viewer = napari.Viewer(show=False) 38 second_epicure.load_movie( second_movie ) 39 second_epicure.go_epicure( "epics", second_labels ) 40 41 ## check that the last frame of first movie and first frame of second are the same 42 if np.sum(first_epicure.img[first_epicure.nframes-1] - second_epicure.img[0]) != 0: 43 ut.show_error("Error: the last frame of first movie is not the same of the first frame of the second movie, I cannot concatenate them.") 44 return 45 46 ## create the full movie 47 full_mov = np.concatenate( (first_epicure.img, second_epicure.img[1:]), axis=0 ) 48 full_movie_name = os.path.join(os.path.dirname(first_epicure.imgpath), fullname) 49 ut.writeTif( full_mov, full_movie_name, first_epicure.epi_metadata["ScaleXY"], first_epicure.img.dtype, what="Full movie") 50 print("Full movie created") 51 52 ###### Read and merge the EpiCure data and merge the movie labels 53 ut.show_info("Reading and concatenating the Epicured results...") 54 55 ### Create new EpiCure instance with the full movie 56 epic = EpiCure() 57 epic.viewer = napari.current_viewer() 58 epic.load_movie(full_movie_name) 59 epic.verbose = 1 60 epic.set_names( "epics" ) 61 62 ## initialize groups to first movie groups 63 epic.groups = first_epicure.groups 64 65 ## initialize tracks to first movie tracks 66 epic.tracking = Tracking(epic.viewer, epic) 67 epic.tracking.track_data = first_epicure.tracking.track_data 68 69 ## initialize track graph to first movie graph 70 if first_epicure.tracking.graph is not None: 71 epic.tracking.graph = first_epicure.tracking.graph 72 else: 73 epic.tracking.graph = {} 74 75 ### Now, work on the labels 76 77 ## track between last and first frame to associate the labels (can be a little different if corrections were done) 78 parent_labels, labels = ut.match_labels( first_epicure.seg[first_epicure.nframes-1], second_epicure.seg[0] ) 79 80 #### Update all the labels in the second movie to match with the first movie 81 nextlabels = first_epicure.get_free_labels(20) ## prepare a list of unused labels 82 used_labels = first_epicure.get_labels() 83 used_labels = used_labels + nextlabels 84 seconds = np.copy(second_epicure.seg) 85 seconds_lab = np.unique(seconds) 86 #second_tracks = np.copy(second_epicure.tracking.track_data) 87 if second_epicure.tracking.graph is None: 88 second_epicure.tracking.graph = {} 89 second_graph = second_epicure.tracking.graph.copy() 90 ## shift all values and keys in the graph, to be sure it's never the same 91 shift = np.max(second_epicure.seg)+1 92 keys = list(second_graph.keys()) 93 for key in keys: 94 val = second_graph.pop(key) 95 shift_val = [] 96 for v in val: 97 shift_val.append(v+shift) 98 second_graph[key+shift] = shift_val 99 100 for lab in seconds_lab: 101 if lab > 0: 102 newlab = None 103 if lab in labels: 104 newlab = parent_labels[labels.index(lab)] 105 #track_indexes = second_epicure.tracking.get_track_indexes( lab ) 106 ## Label from second movie has been associated to one from first movie 107 if newlab is not None: 108 ### If the label is in one group in first or second movie, update its info in full movie 109 fullmovie_group( epic, newlab, lab, second_epicure ) 110 np.place(second_epicure.seg, seconds==lab, newlab) 111 #second_tracks[track_indexes, 0] = newlab 112 if newlab is None: 113 ## Label is a new cell (not present in first movie) 114 nextlabel = nextlabels.pop(0) 115 np.place(second_epicure.seg, seconds==lab, nextlabel) 116 newlab = nextlabel 117 #second_tracks[track_indexes, 0] = nextlabel 118 ### add group information if there is one 119 if second_epicure.groups is not None: 120 second = second_epicure.find_group( lab ) 121 if second is not None: 122 epic.cells_ingroup( [nextlabel], second ) 123 if len(nextlabels) <= 0: 124 ## the list of unused labels has been completly used, regenerates 125 nextlabels = ut.get_free_labels( used_labels, 20 ) 126 used_labels = used_labels + nextlabels 127 128 # add division or merge if lab is in second movie graph 129 if (shift+lab) in second_graph.keys(): 130 second_graph[newlab] = second_graph[shift+lab] 131 for key, vals in second_graph.items(): 132 new_vals = [] 133 for val in vals: 134 if (shift+lab) == val: 135 new_vals.append( newlab ) 136 else: 137 new_vals.append( val ) 138 second_graph[key] = new_vals 139 140 ### merge the two graphs 141 for key, vals in second_graph.items(): 142 if key not in epic.tracking.graph.keys(): 143 epic.tracking.graph[key] = vals 144 else: 145 print("Key "+str(key)+" present in both graph, something might be wrong ") 146 147 ### Ok, save the results 148 full_lab = np.concatenate( (first_epicure.seg, second_epicure.seg[1:]), axis=0 ) 149 epic.seg = full_lab 150 epic.save_epicures() 151 print("Movie and EpiCure files merged; Suspects/Events (if any) are not merged, use inspect tracks on merged movie to generate them")
Do the concatenation
def
fullmovie_group(epic, first_label, second_label, second_epicure):
153def fullmovie_group( epic, first_label, second_label, second_epicure ): 154 """ Check if second_label is in a group, and add it to full movie groups if relevant """ 155 first_group = epic.find_group( first_label ) 156 second = None 157 if second_epicure.groups is not None: 158 second = second_epicure.find_group( second_label ) 159 if (first_group is not None) and (second is not None): 160 ### label is present in the two movie groups 161 if first_group != second: 162 print("Label "+str(first_label)+" classified in group "+(first_group)+" in the first movie and in group "+second+" in the second movie") 163 print("Keep only the first movie group: "+first_group) 164 else: 165 if second is not None: 166 epic.cells_ingroup( [first_label], second )
Check if second_label is in a group, and add it to full movie groups if relevant
def
concatenate_movies():
168def concatenate_movies(): 169 hist = get_save_history() 170 cdir = hist[0] 171 viewer = current_viewer() 172 173 def choose_first_movie(): 174 """ First movie is chosen, suggest default labels file """ 175 first = get_files.first_movie.value 176 imgname, imgdir, out = ut.extract_names( first, "epics", mkdir=False ) 177 get_files.first_labels.value = pathlib.Path(out) 178 labname = ut.suggest_segfile(out, imgname) 179 if labname is not None: 180 get_files.first_labels.value = pathlib.Path(labname) 181 182 def choose_second_movie(): 183 """ Second movie is chosen, suggest default labels file """ 184 second = get_files.second_movie.value 185 imgname, imgdir, out = ut.extract_names( second, "epics", mkdir=False ) 186 get_files.second_labels.value = pathlib.Path(out) 187 labname = ut.suggest_segfile(out, imgname) 188 if labname is not None: 189 get_files.second_labels.value = pathlib.Path(labname) 190 191 @magicgui(call_button="Concatenate",) 192 def get_files( 193 first_movie = pathlib.Path(cdir), 194 first_labels = pathlib.Path(cdir), 195 second_movie = pathlib.Path(cdir), 196 second_labels = pathlib.Path(cdir), 197 merged_movie_name = "fullmovie.tif" 198 ): 199 merge_epicures( first_movie, first_labels, second_movie, second_labels, merged_movie_name) 200 return 201 202 get_files.first_movie.changed.connect(choose_first_movie) 203 get_files.second_movie.changed.connect(choose_second_movie) 204 return get_files