def export(self, filename, hypothesesGraph, objectFeaturesSlot, labelImageSlot, rawImageSlot): """Export the tracking solution stored in the hypotheses graph as a sequence of H5 files, one per frame, containing the label image of that frame and which objects were part of a move or a division. :param filename: string of the FOLDER where to save the result :param hypothesesGraph: hytra.core.hypothesesgraph.HypothesesGraph filled with a solution :param objectFeaturesSlot: lazyflow.graph.InputSlot, connected to the RegionFeaturesAll output of ilastik.applets.trackingFeatureExtraction.opTrackingFeatureExtraction.OpTrackingFeatureExtraction :returns: True on success, False otherwise """ traxelIdPerTimestepToUniqueIdMap, uuidToTraxelMap = hypothesesGraph.getMappingsBetweenUUIDsAndTraxels( ) timesteps = [t for t in traxelIdPerTimestepToUniqueIdMap.keys()] result = hypothesesGraph.getSolutionDictionary() mergers, detections, links, divisions = getMergersDetectionsLinksDivisions( result, uuidToTraxelMap) # group by timestep for event creation mergersPerTimestep = getMergersPerTimestep(mergers, timesteps) linksPerTimestep = getLinksPerTimestep(links, timesteps) detectionsPerTimestep = getDetectionsPerTimestep( detections, timesteps) divisionsPerTimestep = getDivisionsPerTimestep( divisions, linksPerTimestep, timesteps) # save to disk in parallel pool = RequestPool() timeIndex = labelImageSlot.meta.axistags.index('t') for timestep in traxelIdPerTimestepToUniqueIdMap.keys(): # extract current frame lable image roi = [ slice(None) for i in range(len(labelImageSlot.meta.shape)) ] roi[timeIndex] = slice(int(timestep), int(timestep) + 1) roi = tuple(roi) labelImage = labelImageSlot[roi].wait() if not os.path.exists(filename + '/H5-Event-Sequence'): os.makedirs(filename + '/H5-Event-Sequence') fn = os.path.join( filename, "H5-Event-Sequence/{0:05d}.h5".format(int(timestep))) pool.add( Request( partial(writeEvents, int(timestep), linksPerTimestep[timestep], divisionsPerTimestep[timestep], mergersPerTimestep[timestep], detectionsPerTimestep[timestep], fn, labelImage))) pool.wait() return True
def export(self, filename, hypothesesGraph, pluginExportContext): """Export the tracking solution stored in the hypotheses graph as a sequence of H5 files, one per frame, containing the label image of that frame and which objects were part of a move or a division. :param filename: string of the FOLDER where to save the result :param hypothesesGraph: hytra.core.hypothesesgraph.HypothesesGraph filled with a solution :param pluginExportContext: instance of ilastik.plugins.PluginExportContext containing: labelImageSlot (required here) as well as objectFeaturesSlot, rawImageSlot, additionalPluginArgumentsSlot :returns: True on success, False otherwise """ labelImageSlot = pluginExportContext.labelImageSlot traxelIdPerTimestepToUniqueIdMap, uuidToTraxelMap = hypothesesGraph.getMappingsBetweenUUIDsAndTraxels() timesteps = [t for t in traxelIdPerTimestepToUniqueIdMap.keys()] result = hypothesesGraph.getSolutionDictionary() mergers, detections, links, divisions = getMergersDetectionsLinksDivisions(result, uuidToTraxelMap) # group by timestep for event creation mergersPerTimestep = getMergersPerTimestep(mergers, timesteps) linksPerTimestep = getLinksPerTimestep(links, timesteps) detectionsPerTimestep = getDetectionsPerTimestep(detections, timesteps) divisionsPerTimestep = getDivisionsPerTimestep(divisions, linksPerTimestep, timesteps) # save to disk in parallel pool = RequestPool() timeIndex = labelImageSlot.meta.axistags.index('t') if not os.path.exists(filename): os.makedirs(filename) for timestep in traxelIdPerTimestepToUniqueIdMap.keys(): # extract current frame lable image roi = [slice(None) for i in range(len(labelImageSlot.meta.shape))] roi[timeIndex] = slice(int(timestep), int(timestep)+1) roi = tuple(roi) labelImage = labelImageSlot[roi].wait() fn = os.path.join(filename, "{0:05d}.h5".format(int(timestep))) pool.add(Request(partial(writeEvents, int(timestep), linksPerTimestep[timestep], divisionsPerTimestep[timestep], mergersPerTimestep[timestep], detectionsPerTimestep[timestep], fn, labelImage))) pool.wait() return True
def _getEventsVector(self, result, model): traxelIdPerTimestepToUniqueIdMap, uuidToTraxelMap = getMappingsBetweenUUIDsAndTraxels(model) timesteps = [t for t in traxelIdPerTimestepToUniqueIdMap.keys()] mergers, detections, links, divisions = getMergersDetectionsLinksDivisions(result, uuidToTraxelMap) # Group by timestep for event creation mergersPerTimestep = getMergersPerTimestep(mergers, timesteps) linksPerTimestep = getLinksPerTimestep(links, timesteps) detectionsPerTimestep = getDetectionsPerTimestep(detections, timesteps) divisionsPerTimestep = getDivisionsPerTimestep(divisions, linksPerTimestep, timesteps) # Populate events dictionary events = {} # Save mergers, links, detections, and divisions for timestep in traxelIdPerTimestepToUniqueIdMap.keys(): # We need to add an extra column with zeros in order to be backward compatible with the older version def stackExtraColumnWithZeros(array): return np.hstack((array, np.zeros((array.shape[0], 1), dtype=array.dtype))) dis = [] app = [] div = [] mov = [] mer = [] mul = [] dis = np.asarray(dis) app = np.asarray(app) div = np.asarray([[k, v[0], v[1]] for k,v in divisionsPerTimestep[timestep].iteritems()]) mov = np.asarray(linksPerTimestep[timestep]) mer = np.asarray([[k,v] for k,v in mergersPerTimestep[timestep].iteritems()]) mul = np.asarray(mul) events[timestep] = {} if len(dis) > 0: events[timestep]['dis'] = dis if len(app) > 0: events[timestep]['app'] = app if len(div) > 0: events[timestep]['div'] = div if len(mov) > 0: events[timestep]['mov'] = mov if len(mer) > 0: events[timestep]['mer'] = mer if len(mul) > 0: events[timestep]['mul'] = mul # Write merger results dictionary resolvedMergersDict = self.ResolvedMergers.value if resolvedMergersDict: mergerRes = {} for idx in mergersPerTimestep[timestep]: mergerRes[idx] = resolvedMergersDict[int(timestep)][idx]['newIds'] events[timestep]['res'] = mergerRes else: logger.info("Resolved Merger Dictionary not available. Please click on the Track button.") return events
def test_loading_no_divisions(): model = return_example_model() result = return_example_result() # traxel <=> uuid mappings traxelIdPerTimestepToUniqueIdMap, uuidToTraxelMap = jg.getMappingsBetweenUUIDsAndTraxels( model) assert (traxelIdPerTimestepToUniqueIdMap == { '0': { '1': 0, '2': 5 }, '1': { '1': 4 }, '2': { '1': 3 }, '3': { '1': 2, '2': 1 } }) assert (uuidToTraxelMap == { 0: [(0, 1)], 1: [(3, 2)], 2: [(3, 1)], 3: [(2, 1)], 4: [(1, 1)], 5: [(0, 2)] }) # get lists mergers, detections, links, divisions = jg.getMergersDetectionsLinksDivisions( result, uuidToTraxelMap) assert (divisions is None) assert (mergers == [(2, 1, 2), (1, 1, 2)]) assert (detections == [(0, 1), (3, 2), (3, 1), (2, 1), (1, 1), (0, 2)]) assert (links == [((0, 1), (1, 1)), ((2, 1), (3, 2)), ((2, 1), (3, 1)), ((1, 1), (2, 1)), ((0, 2), (1, 1))]) # events per timestep timesteps = traxelIdPerTimestepToUniqueIdMap.keys() mergersPerTimestep = jg.getMergersPerTimestep(mergers, timesteps) assert (mergersPerTimestep == {'0': {}, '1': {1: 2}, '2': {1: 2}, '3': {}}) detectionsPerTimestep = jg.getDetectionsPerTimestep(detections, timesteps) assert (detectionsPerTimestep == { '0': [1, 2], '1': [1], '2': [1], '3': [2, 1] }) linksPerTimestep = jg.getLinksPerTimestep(links, timesteps) assert (linksPerTimestep == { '0': [], '1': [(1, 1), (2, 1)], '2': [(1, 1)], '3': [(1, 2), (1, 1)] }) # merger links as triplets [("timestep", (sourceId, destId)), (), ...] mergerLinks = jg.getMergerLinks(linksPerTimestep, mergersPerTimestep, timesteps) assert (mergerLinks == [('1', (1, 1)), ('1', (2, 1)), ('3', (1, 2)), ('3', (1, 1)), ('2', (1, 1))])