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