def track(imp): from fiji.plugin.trackmate import Model from fiji.plugin.trackmate import Settings from fiji.plugin.trackmate import TrackMate from fiji.plugin.trackmate import SelectionModel from fiji.plugin.trackmate import Logger from fiji.plugin.trackmate.detection import LogDetectorFactory from fiji.plugin.trackmate.tracking.sparselap import SparseLAPTrackerFactory from fiji.plugin.trackmate.tracking import LAPUtils from ij import IJ import fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer as HyperStackDisplayer import fiji.plugin.trackmate.features.FeatureFilter as FeatureFilter import sys import fiji.plugin.trackmate.features.track.TrackDurationAnalyzer as TrackDurationAnalyzer # Get currently selected image #imp = WindowManager.getCurrentImage() #imp = IJ.openImage('http://fiji.sc/samples/FakeTracks.tif') #imp.show() #---------------------------- # Create the model object now #---------------------------- # Some of the parameters we configure below need to have # a reference to the model at creation. So we create an # empty model now. model = Model() # Send all messages to ImageJ log window. model.setLogger(Logger.IJ_LOGGER) #------------------------ # Prepare settings object #------------------------ settings = Settings() settings.setFrom(imp) # Configure detector - We use the Strings for the keys settings.detectorFactory = LogDetectorFactory() settings.detectorSettings = { 'DO_SUBPIXEL_LOCALIZATION': True, 'RADIUS': 3.0, 'TARGET_CHANNEL': 1, 'THRESHOLD': 1., 'DO_MEDIAN_FILTERING': False, } # Configure spot filters - Classical filter on quality filter1 = FeatureFilter('QUALITY', 30, True) settings.addSpotFilter(filter1) # Configure tracker - We want to allow merges and fusions settings.trackerFactory = SparseLAPTrackerFactory() settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap( ) # almost good enough settings.trackerSettings['ALLOW_TRACK_SPLITTING'] = True settings.trackerSettings['ALLOW_TRACK_MERGING'] = True # Configure track analyzers - Later on we want to filter out tracks # based on their displacement, so we need to state that we want # track displacement to be calculated. By default, out of the GUI, # not features are calculated. # The displacement feature is provided by the TrackDurationAnalyzer. settings.addTrackAnalyzer(TrackDurationAnalyzer()) #------------------- # Instantiate plugin #------------------- trackmate = TrackMate(model, settings) #-------- # Process #-------- ok = trackmate.checkInput() if not ok: sys.exit(str(trackmate.getErrorMessage())) ok = trackmate.process() if not ok: sys.exit(str(trackmate.getErrorMessage())) #---------------- # Display results #---------------- selectionModel = SelectionModel(model) displayer = HyperStackDisplayer(model, selectionModel, imp) displayer.render() displayer.refresh() # Echo results with the logger we set at start: #model.getLogger().log(str(model)) fm = model.getFeatureModel() norm_x = [] norm_y = [] for id in model.getTrackModel().trackIDs(True): track = model.getTrackModel().trackSpots(id) for spot in track: t = spot.getFeature('FRAME') if (t == 0.0): min_x = spot.getFeature('POSITION_X') min_y = spot.getFeature('POSITION_Y') for spot in track: norm_x.append(spot.getFeature('POSITION_X') - min_x) norm_y.append(spot.getFeature('POSITION_Y') - min_y) max_x = abs(max(norm_x, key=abs)) max_y = abs(max(norm_y, key=abs)) return max_x, max_y
if not ok: sys.exit(str(trackmate.getErrorMessage())) #---------------- # Display results #---------------- #model.getLogger().log('Found ' + str(model.getTrackModel().nTracks(True)) + ' tracks.') selectionModel = SelectionModel(model) #displayer = HyperStackDisplayer(model, selectionModel, imp) #displayer.render() #displayer.refresh() # The feature model, that stores edge and track features. fm = model.getFeatureModel() model.getLogger().log('Data starts here.') model.getLogger().log('Track_ID' + ',' + 'Spot_ID' + ',' + 'Frame' + ',' + 'X' + ',' + 'Y' + ',' + 'Quality' + ',' + 'SN_Ratio' + ',' + 'Mean_Intensity') for id in model.getTrackModel().trackIDs(True): # Fetch the track feature from the feature model. #v = fm.getTrackFeature(id, 'TRACK_MEAN_SPEED') #dur = fm.getTrackFeature(id, 'TRACK_DURATION') #model.getLogger().log('') #model.getLogger().log('Track ' + str(id) + ': mean velocity = ' + str(v) + ' ' + model.getSpaceUnits() + '/' + model.getTimeUnits()) #model.getLogger().log('Track ' + str(id) + ': duration = ' + str(dur) + ' ' + model.getTimeUnits()) track = model.getTrackModel().trackSpots(id) for spot in track:
#---------------- # Display results #---------------- model.getLogger().log('Found ' + str(model.getTrackModel().nTracks(True)) + ' tracks.') selectionModel = SelectionModel(model) displayer = HyperStackDisplayer(model, selectionModel, imp) displayer.render() displayer.refresh() # The feature model, that stores edge and track features. fm = model.getFeatureModel() for id in model.getTrackModel().trackIDs(True): # Fetch the track feature from the feature model. v = fm.getTrackFeature(id, 'TRACK_MEAN_SPEED') model.getLogger().log('') model.getLogger().log('Track ' + str(id) + ': mean velocity = ' + str(v) + ' ' + model.getSpaceUnits() + '/' + model.getTimeUnits()) track = model.getTrackModel().trackSpots(id) for spot in track: sid = spot.ID() # Fetch spot features directly from spot. x=spot.getFeature('POSITION_X') y=spot.getFeature('POSITION_Y') t=spot.getFeature('FRAME')
def runTrackMate(imp): import fiji.plugin.trackmate.Settings as Settings import fiji.plugin.trackmate.Model as Model import fiji.plugin.trackmate.SelectionModel as SelectionModel import fiji.plugin.trackmate.TrackMate as TrackMate import fiji.plugin.trackmate.Logger as Logger import fiji.plugin.trackmate.detection.DetectorKeys as DetectorKeys import fiji.plugin.trackmate.detection.DogDetectorFactory as DogDetectorFactory import fiji.plugin.trackmate.tracking.sparselap.SparseLAPTrackerFactory as SparseLAPTrackerFactory import fiji.plugin.trackmate.tracking.LAPUtils as LAPUtils import fiji.plugin.trackmate.visualization.hyperstack.HyperStackDisplayer as HyperStackDisplayer import fiji.plugin.trackmate.features.FeatureFilter as FeatureFilter import fiji.plugin.trackmate.features.FeatureAnalyzer as FeatureAnalyzer import fiji.plugin.trackmate.features.spot.SpotContrastAndSNRAnalyzerFactory as SpotContrastAndSNRAnalyzerFactory import fiji.plugin.trackmate.action.ExportStatsToIJAction as ExportStatsToIJAction import fiji.plugin.trackmate.io.TmXmlReader as TmXmlReader import fiji.plugin.trackmate.action.ExportTracksToXML as ExportTracksToXML import fiji.plugin.trackmate.io.TmXmlWriter as TmXmlWriter import fiji.plugin.trackmate.features.ModelFeatureUpdater as ModelFeatureUpdater import fiji.plugin.trackmate.features.SpotFeatureCalculator as SpotFeatureCalculator import fiji.plugin.trackmate.features.spot.SpotContrastAndSNRAnalyzer as SpotContrastAndSNRAnalyzer import fiji.plugin.trackmate.features.spot.SpotIntensityAnalyzerFactory as SpotIntensityAnalyzerFactory import fiji.plugin.trackmate.features.track.TrackSpeedStatisticsAnalyzer as TrackSpeedStatisticsAnalyzer import fiji.plugin.trackmate.util.TMUtils as TMUtils import fiji.plugin.trackmate.visualization.trackscheme.TrackScheme as TrackScheme import fiji.plugin.trackmate.visualization.PerTrackFeatureColorGenerator as PerTrackFeatureColorGenerator #------------------------- # Instantiate model object #------------------------- nFrames = imp.getNFrames() model = Model() # Set logger #model.setLogger(Logger.IJ_LOGGER) #------------------------ # Prepare settings object #------------------------ settings = Settings() settings.setFrom(imp) # Configure detector settings.detectorFactory = DogDetectorFactory() settings.detectorSettings = { DetectorKeys.KEY_DO_SUBPIXEL_LOCALIZATION: True, DetectorKeys.KEY_RADIUS: 12.30, DetectorKeys.KEY_TARGET_CHANNEL: 1, DetectorKeys.KEY_THRESHOLD: 100., DetectorKeys.KEY_DO_MEDIAN_FILTERING: False, } # Configure tracker settings.trackerFactory = SparseLAPTrackerFactory() settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap() settings.trackerSettings['LINKING_MAX_DISTANCE'] = 10.0 settings.trackerSettings['GAP_CLOSING_MAX_DISTANCE'] = 10.0 settings.trackerSettings['MAX_FRAME_GAP'] = 3 # Add the analyzers for some spot features. # You need to configure TrackMate with analyzers that will generate # the data you need. # Here we just add two analyzers for spot, one that computes generic # pixel intensity statistics (mean, max, etc...) and one that computes # an estimate of each spot's SNR. # The trick here is that the second one requires the first one to be in # place. Be aware of this kind of gotchas, and read the docs. settings.addSpotAnalyzerFactory(SpotIntensityAnalyzerFactory()) settings.addSpotAnalyzerFactory(SpotContrastAndSNRAnalyzerFactory()) # Add an analyzer for some track features, such as the track mean speed. settings.addTrackAnalyzer(TrackSpeedStatisticsAnalyzer()) settings.initialSpotFilterValue = 1 print(str(settings)) #---------------------- # Instantiate trackmate #---------------------- trackmate = TrackMate(model, settings) #------------ # Execute all #------------ ok = trackmate.checkInput() if not ok: sys.exit(str(trackmate.getErrorMessage())) ok = trackmate.process() if not ok: sys.exit(str(trackmate.getErrorMessage())) #---------------- # Display results #---------------- selectionModel = SelectionModel(model) displayer = HyperStackDisplayer(model, selectionModel, imp) displayer.render() displayer.refresh() #--------------------- # Select correct spots #--------------------- # Prepare display. sm = SelectionModel(model) color = PerTrackFeatureColorGenerator(model, 'TRACK_INDEX') # launch TrackScheme to select spots and tracks trackscheme = TrackScheme(model, sm) trackscheme.setDisplaySettings('TrackColoring', color) trackscheme.render() # Update image with TrackScheme commands view = HyperStackDisplayer(model, sm, imp) view.setDisplaySettings('TrackColoring', color) view.render() # Wait for the user to select correct spots and tracks before collecting data dialog = WaitForUserDialog( "Spots", "Delete incorrect spots and edit tracks if necessary. (Press ESC to cancel analysis)" ) dialog.show() if dialog.escPressed(): IJ.run("Remove Overlay", "") imp.close() return ([], nFrames) # The feature model, that stores edge and track features. #model.getLogger().log('Found ' + str(model.getTrackModel().nTracks(True)) + ' tracks.') fm = model.getFeatureModel() crds_perSpot = [] for id in model.getTrackModel().trackIDs(True): # Fetch the track feature from the feature model.(remove """ to enable) """v = fm.getTrackFeature(id, 'TRACK_MEAN_SPEED') model.getLogger().log('') model.getLogger().log('Track ' + str(id) + ': mean velocity = ' + str(v) + ' ' + model.getSpaceUnits() + '/' + model.getTimeUnits())""" trackID = str(id) track = model.getTrackModel().trackSpots(id) spot_track = {} for spot in track: sid = spot.ID() # Fetch spot features directly from spot. x = spot.getFeature('POSITION_X') y = spot.getFeature('POSITION_Y') t = spot.getFeature('FRAME') q = spot.getFeature('QUALITY') snr = spot.getFeature('SNR') mean = spot.getFeature('MEAN_INTENSITY') #model.getLogger().log('\tspot ID = ' + str(sid) + ', x='+str(x)+', y='+str(y)+', t='+str(t)+', q='+str(q) + ', snr='+str(snr) + ', mean = ' + str(mean)) spot_track[t] = (x, y) crds_perSpot.append(spot_track) #print ("Spot", crds_perSpot.index(spot_track),"has the following coordinates:", crds_perSpot[crds_perSpot.index(spot_track)]) return (crds_perSpot, nFrames)
def process(srcDir, dstDir, currentDir, fileName, keepDirectories): print "Processing:" # Opening the image print "Open image file", fileName imp = IJ.openImage(os.path.join(currentDir, fileName)) #Here we make sure the calibration are correct units = "pixel" TimeUnit = "unit" newCal = Calibration() newCal.pixelWidth = 1 newCal.pixelHeight = 1 newCal.frameInterval = 1 newCal.setXUnit(units) newCal.setYUnit(units) newCal.setTimeUnit(TimeUnit) imp.setCalibration(newCal) cal = imp.getCalibration() dims = imp.getDimensions() # default order: XYCZT if (dims[4] == 1): imp.setDimensions(1, 1, dims[3]) # Start the tracking model = Model() #Read the image calibration model.setPhysicalUnits(cal.getUnit(), cal.getTimeUnit()) # Send all messages to ImageJ log window. model.setLogger(Logger.IJ_LOGGER) settings = Settings() settings.setFrom(imp) # Configure detector - We use the Strings for the keys # Configure detector - We use the Strings for the keys settings.detectorFactory = DownsampleLogDetectorFactory() settings.detectorSettings = { DetectorKeys.KEY_RADIUS: 2., DetectorKeys.KEY_DOWNSAMPLE_FACTOR: 2, DetectorKeys.KEY_THRESHOLD: 1., } print(settings.detectorSettings) # Configure spot filters - Classical filter on quality filter1 = FeatureFilter('QUALITY', 0, True) settings.addSpotFilter(filter1) # Configure tracker - We want to allow merges and fusions settings.trackerFactory = SparseLAPTrackerFactory() settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap( ) # almost good enough settings.trackerSettings['LINKING_MAX_DISTANCE'] = LINKING_MAX_DISTANCE settings.trackerSettings['ALLOW_TRACK_SPLITTING'] = ALLOW_TRACK_SPLITTING settings.trackerSettings['SPLITTING_MAX_DISTANCE'] = SPLITTING_MAX_DISTANCE settings.trackerSettings['ALLOW_TRACK_MERGING'] = ALLOW_TRACK_MERGING settings.trackerSettings['MERGING_MAX_DISTANCE'] = MERGING_MAX_DISTANCE settings.trackerSettings[ 'GAP_CLOSING_MAX_DISTANCE'] = GAP_CLOSING_MAX_DISTANCE settings.trackerSettings['MAX_FRAME_GAP'] = MAX_FRAME_GAP # Configure track analyzers - Later on we want to filter out tracks # based on their displacement, so we need to state that we want # track displacement to be calculated. By default, out of the GUI, # not features are calculated. # The displacement feature is provided by the TrackDurationAnalyzer. settings.addTrackAnalyzer(TrackDurationAnalyzer()) settings.addTrackAnalyzer(TrackSpeedStatisticsAnalyzer()) filter2 = FeatureFilter('TRACK_DISPLACEMENT', 10, True) settings.addTrackFilter(filter2) #------------------- # Instantiate plugin #------------------- trackmate = TrackMate(model, settings) #-------- # Process #-------- ok = trackmate.checkInput() if not ok: sys.exit(str(trackmate.getErrorMessage())) ok = trackmate.process() if not ok: sys.exit(str(trackmate.getErrorMessage())) #---------------- # Display results #---------------- if showtracks: model.getLogger().log('Found ' + str(model.getTrackModel().nTracks(True)) + ' tracks.') selectionModel = SelectionModel(model) displayer = HyperStackDisplayer(model, selectionModel, imp) displayer.render() displayer.refresh() # The feature model, that stores edge and track features. fm = model.getFeatureModel() with open(dstDir + fileName + 'tracks_properties.csv', "w") as file: writer1 = csv.writer(file) writer1.writerow([ "track #", "TRACK_MEAN_SPEED (micrometer.secs)", "TRACK_MAX_SPEED (micrometer.secs)", "NUMBER_SPLITS", "TRACK_DURATION (secs)", "TRACK_DISPLACEMENT (micrometer)" ]) with open(dstDir + fileName + 'spots_properties.csv', "w") as trackfile: writer2 = csv.writer(trackfile) #writer2.writerow(["spot ID","POSITION_X","POSITION_Y","Track ID", "FRAME"]) writer2.writerow( ["Tracking ID", "Timepoint", "Time (secs)", "X pos", "Y pos"]) for id in model.getTrackModel().trackIDs(True): # Fetch the track feature from the feature model. v = (fm.getTrackFeature(id, 'TRACK_MEAN_SPEED') * Pixel_calibration) / Time_interval ms = (fm.getTrackFeature(id, 'TRACK_MAX_SPEED') * Pixel_calibration) / Time_interval s = fm.getTrackFeature(id, 'NUMBER_SPLITS') d = fm.getTrackFeature(id, 'TRACK_DURATION') * Time_interval e = fm.getTrackFeature( id, 'TRACK_DISPLACEMENT') * Pixel_calibration model.getLogger().log('') model.getLogger().log('Track ' + str(id) + ': mean velocity = ' + str(v) + ' ' + model.getSpaceUnits() + '/' + model.getTimeUnits()) track = model.getTrackModel().trackSpots(id) writer1.writerow( [str(id), str(v), str(ms), str(s), str(d), str(e)]) for spot in track: sid = spot.ID() x = spot.getFeature('POSITION_X') y = spot.getFeature('POSITION_Y') z = spot.getFeature('TRACK_ID') t = spot.getFeature('FRAME') time = int(t) * int(Time_interval) writer2.writerow( [str(id), str(t), str(time), str(x), str(y)])
def processImages(cfg, wellName, wellPath, images): firstImage = IJ.openImage(images[0][0][0][0]) imgWidth = firstImage.getWidth() imgHeight = firstImage.getHeight() for c in range(0, cfg.getValue(ELMConfig.numChannels)): chanName = cfg.getValue(ELMConfig.chanLabel)[c] if cfg.getValue(ELMConfig.chanLabel)[c] in cfg.getValue( ELMConfig.chansToSkip): continue imColorSeq = ImageStack(imgWidth, imgHeight) imSeq = ImageStack(imgWidth, imgHeight) totalHist = [] for z in range(0, cfg.getValue(ELMConfig.numZ)): for t in range(0, cfg.getValue(ELMConfig.numT)): currIP = IJ.openImage(images[c][z][t][0]) imColorSeq.addSlice(currIP.duplicate().getProcessor()) currIP = ELMImageUtils.getGrayScaleImage( currIP, c, chanName, cfg) imSeq.addSlice(currIP.getProcessor()) imgStats = currIP.getStatistics() currHist = imgStats.getHistogram() if not totalHist: for i in range(len(currHist)): totalHist.append(currHist[i]) else: for i in range(len(currHist)): totalHist[i] += currHist[i] if cfg.hasValue(ELMConfig.thresholdFromWholeRange) and cfg.getValue( ELMConfig.thresholdFromWholeRange) == True: threshMethod = "Otsu" # Default works very poorly for this data if cfg.hasValue(ELMConfig.thresholdMethod): threshMethod = cfg.getValue(ELMConfig.thresholdMethod) thresholder = AutoThresholder() computedThresh = thresholder.getThreshold(threshMethod, totalHist) cfg.setValue(ELMConfig.imageThreshold, computedThresh) print("\tComputed threshold from total hist (" + threshMethod + "): " + str(computedThresh)) print() else: print("\tUsing threshold computed on individual images!") print() computedThresh = 0 chanName = cfg.getValue(ELMConfig.chanLabel)[c] imp = ImagePlus() imp.setStack(imSeq) imp.setDimensions(1, 1, cfg.getValue(ELMConfig.numT)) imp.setTitle(wellName + ", channel " + str(c)) impColor = ImagePlus() impColor.setStack(imColorSeq) impColor.setDimensions(1, 1, cfg.getValue(ELMConfig.numT)) impColor.setTitle(wellName + ", channel " + str(c) + " (Color)") #---------------------------- # Create the model object now #---------------------------- # Some of the parameters we configure below need to have # a reference to the model at creation. So we create an # empty model now. model = Model() # Send all messages to ImageJ log window. model.setLogger(Logger.IJ_LOGGER) pa_features = [ "Area", "PercentArea", "Mean", "StdDev", "Mode", "Min", "Max", "X", "Y", "XM", "YM", "Perim.", "BX", "BY", "Width", "Height", "Major", "Minor", "Angle", "Circ.", "Feret", "IntDen", "Median", "Skew", "Kurt", "RawIntDen", "FeretX", "FeretY", "FeretAngle", "MinFeret", "AR", "Round", "Solidity" ] featureNames = {} featureShortNames = {} featureDimensions = {} isInt = {} for feature in pa_features: featureNames[feature] = feature featureShortNames[feature] = feature featureDimensions[feature] = Dimension.STRING isInt[feature] = False model.getFeatureModel().declareSpotFeatures(pa_features, featureNames, featureShortNames, featureDimensions, isInt) #------------------------ # Prepare settings object #------------------------ settings = Settings() settings.setFrom(imp) dbgPath = os.path.join(wellPath, 'debugImages_' + chanName) if not os.path.exists(dbgPath): os.makedirs(dbgPath) if cfg.hasValue(ELMConfig.thresholdMethod): threshMethod = cfg.getValue(ELMConfig.thresholdMethod) else: threshMethod = "Default" # Configure detector - We use the Strings for the keys settings.detectorFactory = ThresholdDetectorFactory() settings.detectorSettings = { 'THRESHOLD': computedThresh, 'ABOVE': True, 'DEBUG_MODE': True, 'DEBUG_OUTPATH': dbgPath, 'THRESHOLD_METHOD': threshMethod } #settings.detectorFactory = LocalThresholdDetectorFactory() #settings.detectorSettings = { # 'THRESHOLD' : computedThresh, # 'DEBUG_MODE' : True, # 'DEBUG_OUTPATH' : dbgPath #} # Configure spot filters - Classical filter on quality filter1 = FeatureFilter('QUALITY', 150, True) settings.addSpotFilter(filter1) # Configure tracker - We want to allow merges and fusions settings.trackerFactory = SparseLAPTrackerFactory() settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap( ) # almost good enough # Linking settings.trackerSettings[TrackerKeys.KEY_LINKING_MAX_DISTANCE] = 220.0 # in pixels linkFeaturePenalties = HashMap() linkFeaturePenalties['Area'] = 1.0 linkFeaturePenalties['POSITION_X'] = 1.0 linkFeaturePenalties['POSITION_Y'] = 1.0 #linkFeaturePenalties['Circ.'] = 1.0 #linkFeaturePenalties['Mean'] = 1.0 settings.trackerSettings[ TrackerKeys.KEY_LINKING_FEATURE_PENALTIES] = linkFeaturePenalties # Gap closing settings.trackerSettings[TrackerKeys.KEY_ALLOW_GAP_CLOSING] = True settings.trackerSettings[TrackerKeys.KEY_GAP_CLOSING_MAX_FRAME_GAP] = 8 settings.trackerSettings[ TrackerKeys.KEY_GAP_CLOSING_MAX_DISTANCE] = 120.0 # in pixels #settings.trackerSettings[TrackerKeys.KEY_GAP_CLOSING_FEATURE_PENALTIES] = new HashMap<>(DEFAULT_GAP_CLOSING_FEATURE_PENALTIES)); # Track splitting settings.trackerSettings[TrackerKeys.KEY_ALLOW_TRACK_SPLITTING] = False settings.trackerSettings[TrackerKeys.KEY_SPLITTING_MAX_DISTANCE] = 45.0 # in pixels #settings.trackerSettings[TrackerKeys.KEY_SPLITTING_FEATURE_PENALTIES] = new HashMap<>(DEFAULT_SPLITTING_FEATURE_PENALTIES)); # Track merging settings.trackerSettings[TrackerKeys.KEY_ALLOW_TRACK_MERGING] = True settings.trackerSettings[TrackerKeys.KEY_MERGING_MAX_DISTANCE] = 45.0 # in pixels #settings.trackerSettings[TrackerKeys.KEY_MERGING_FEATURE_PENALTIES] = new HashMap<>(DEFAULT_MERGING_FEATURE_PENALTIES)); # Others settings.trackerSettings[TrackerKeys.KEY_BLOCKING_VALUE] = float("inf") settings.trackerSettings[ TrackerKeys.KEY_ALTERNATIVE_LINKING_COST_FACTOR] = 1.05 settings.trackerSettings[TrackerKeys.KEY_CUTOFF_PERCENTILE] = 0.9 # Configure track analyzers - Later on we want to filter out tracks # based on their displacement, so we need to state that we want # track displacement to be calculated. By default, out of the GUI, # no features are calculated. # The displacement feature is provided by the TrackDurationAnalyzer. settings.addTrackAnalyzer(TrackDurationAnalyzer()) settings.addTrackAnalyzer(TrackBranchingAnalyzer()) settings.addTrackAnalyzer(TrackIndexAnalyzer()) settings.addTrackAnalyzer(TrackLocationAnalyzer()) settings.addTrackAnalyzer(TrackSpeedStatisticsAnalyzer()) settings.addSpotAnalyzerFactory(SpotIntensityAnalyzerFactory()) settings.addSpotAnalyzerFactory(SpotContrastAndSNRAnalyzerFactory()) # Configure track filters - We want to get rid of the two immobile spots at # the bottom right of the image. Track displacement must be above 10 pixels. #filter2 = FeatureFilter('TRACK_DISPLACEMENT', 1, True) #settings.addTrackFilter(filter2) #filter2 = FeatureFilter('TRACK_DISPLACEMENT', 1, True) #settings.addTrackFilter(filter2) #print("Spot feature analyzers: " + settings.toStringFeatureAnalyzersInfo()) #------------------- # Instantiate plugin #------------------- trackmate = TrackMate(model, settings) trackmate.setNumThreads(1) #-------- # Process #-------- ok = trackmate.checkInput() if not ok: sys.exit(str(trackmate.getErrorMessage())) print("Processing " + chanName + "...") ok = trackmate.process() if not ok: sys.exit(str(trackmate.getErrorMessage())) #---------------- # Display results #---------------- print("Rendering...") # Set spot names based on track IDs # This allows track IDs to be displayed in the rendered video for tId in model.getTrackModel().trackIDs(True): trackSpots = model.getTrackModel().trackSpots(tId) for spot in trackSpots: spot.setName(str(tId)) # Determine sub-tracks within a track # Since tracks can merge, we want to keep track of which track a spot is # in prior to the merge spotToSubTrackMap = {} spotIt = model.getSpots().iterator(False) trackModel = model.getTrackModel() subTrackCount = {} while spotIt.hasNext(): spot = spotIt.next() spotEdges = trackModel.edgesOf(spot) # Find merge points within a track: ignore spots with fewer than 2 edges if (len(spotEdges) < 2): continue # We have a merge if we have multiple incoming edges incomingEdges = 0 edgeIt = spotEdges.iterator() ancestorSpots = [] while edgeIt.hasNext(): edge = edgeIt.next() src = trackModel.getEdgeSource(edge) dst = trackModel.getEdgeTarget(edge) if dst.ID() == spot.ID(): ancestorSpots.append(src) incomingEdges += 1 # Ignore non-merges if incomingEdges < 2: continue trackId = trackModel.trackIDOf(spot) if trackId in subTrackCount: subTrackId = subTrackCount[trackId] else: subTrackId = 1 for ancestorSpot in ancestorSpots: labelSubTrackAncestors(trackModel, spotToSubTrackMap, ancestorSpot, subTrackId, trackId, False) subTrackId += 1 subTrackCount[trackId] = subTrackId # Spots after the last merge still need to be labeled for tId in trackModel.trackIDs(True): trackSpots = trackModel.trackSpots(tId) spotIt = trackSpots.iterator() lastSpot = None while spotIt.hasNext(): spot = spotIt.next() outgoingEdges = 0 spotEdges = trackModel.edgesOf(spot) edgeIt = spotEdges.iterator() while edgeIt.hasNext(): edge = edgeIt.next() src = trackModel.getEdgeSource(edge) dst = trackModel.getEdgeTarget(edge) if src.ID() == spot.ID(): outgoingEdges += 1 if outgoingEdges == 0 and len(spotEdges) > 0: lastSpot = spot if tId in subTrackCount: subTrackId = subTrackCount[tId] else: subTrackId = 1 if not lastSpot == None: labelSubTrackAncestors(trackModel, spotToSubTrackMap, lastSpot, subTrackId, tId, True) # Create output file trackOut = os.path.join(wellPath, chanName + "_spotToTrackMap.csv") trackFile = open(trackOut, 'w') # Fetch the track feature from the feature model. trackFile.write('Spot Id, Track Sub Id, Track Id, Frame \n') for spotId in spotToSubTrackMap: trackFile.write( str(spotId) + ', ' + ','.join(spotToSubTrackMap[spotId]) + '\n') trackFile.close() # Write Edge Set trackOut = os.path.join(wellPath, chanName + "_mergeEdgeSet.csv") trackFile = open(trackOut, 'w') trackFile.write('Track Id, Spot Id, Spot Id \n') edgeIt = trackModel.edgeSet().iterator() while edgeIt.hasNext(): edge = edgeIt.next() src = trackModel.getEdgeSource(edge) dst = trackModel.getEdgeTarget(edge) trackId = trackModel.trackIDOf(edge) srcSubTrack = spotToSubTrackMap[src.ID()][0] dstSubTrack = spotToSubTrackMap[dst.ID()][0] if not srcSubTrack == dstSubTrack: trackFile.write( str(trackId) + ', ' + str(src.ID()) + ', ' + str(dst.ID()) + '\n') trackFile.close() selectionModel = SelectionModel(model) displayer = HyperStackDisplayer(model, selectionModel, impColor) displayer.setDisplaySettings( TrackMateModelView.KEY_TRACK_COLORING, PerTrackFeatureColorGenerator(model, TrackIndexAnalyzer.TRACK_INDEX)) displayer.setDisplaySettings( TrackMateModelView.KEY_SPOT_COLORING, SpotColorGeneratorPerTrackFeature(model, TrackIndexAnalyzer.TRACK_INDEX)) displayer.setDisplaySettings(TrackMateModelView.KEY_DISPLAY_SPOT_NAMES, True) displayer.setDisplaySettings( TrackMateModelView.KEY_TRACK_DISPLAY_MODE, TrackMateModelView.TRACK_DISPLAY_MODE_LOCAL_BACKWARD_QUICK) displayer.setDisplaySettings( TrackMateModelView.KEY_TRACK_DISPLAY_DEPTH, 2) displayer.render() displayer.refresh() trackmate.getSettings().imp = impColor coa = CaptureOverlayAction(None) coa.execute(trackmate) WindowManager.setTempCurrentImage(coa.getCapture()) IJ.saveAs('avi', os.path.join(wellPath, chanName + "_out.avi")) imp.close() impColor.close() displayer.clear() displayer.getImp().hide() displayer.getImp().close() coa.getCapture().hide() coa.getCapture().close() # Echo results with the logger we set at start: model.getLogger().log(str(model)) # The feature model, that stores edge and track features. fm = model.getFeatureModel() # Write output for tracks numTracks = model.getTrackModel().trackIDs(True).size() print "Writing track data for " + str(numTracks) + " tracks." trackDat = {} for tId in model.getTrackModel().trackIDs(True): track = model.getTrackModel().trackSpots(tId) # Ensure track spots dir exists trackOut = os.path.join(wellPath, chanName + "_track_spots") if not os.path.exists(trackOut): os.makedirs(trackOut) # Create output file trackOut = os.path.join(trackOut, "track_" + str(tId) + ".csv") trackFile = open(trackOut, 'w') # Write Header header = 'Name, ID, Frame, ' for feature in track.toArray()[0].getFeatures().keySet(): if feature == 'Frame': continue header += feature + ", " header = header[0:len(header) - 2] header += '\n' trackFile.write(header) # Write spot data avgTotalIntensity = 0 for spot in track: #print spot.echo() data = [ spot.getName(), str(spot.ID()), str(spot.getFeature('FRAME')) ] for feature in spot.getFeatures(): if feature == 'Frame': continue elif feature == 'TOTAL_INTENSITY': avgTotalIntensity += spot.getFeature(feature) data.append(str(spot.getFeature(feature))) trackFile.write(','.join(data) + '\n') trackFile.close() avgTotalIntensity /= len(track) # Write out track stats # Make sure dir exists trackOut = os.path.join(wellPath, chanName + "_tracks") if not os.path.exists(trackOut): os.makedirs(trackOut) # Create output file trackOut = os.path.join(trackOut, "track_" + str(tId) + ".csv") trackFile = open(trackOut, 'w') # Fetch the track feature from the feature model. header = '' for featName in fm.getTrackFeatureNames(): header += featName + ", " header = header[0:len(header) - 2] header += '\n' trackFile.write(header) features = '' for featName in fm.getTrackFeatureNames(): features += str(fm.getTrackFeature(tId, featName)) + ', ' features = features[0:len(features) - 2] features += '\n' trackFile.write(features) trackFile.write('\n') trackFile.close() trackDat[tId] = [ str(tId), str(fm.getTrackFeature(tId, 'TRACK_DURATION')), str(avgTotalIntensity), str(fm.getTrackFeature(tId, 'TRACK_START')), str(fm.getTrackFeature(tId, 'TRACK_STOP')) ] # Create output file trackOut = os.path.join(wellPath, chanName + "_trackSummary.csv") trackFile = open(trackOut, 'w') # Fetch the track feature from the feature model. trackFile.write( 'Track Id, Duration, Avg Total Intensity, Start Frame, Stop Frame \n' ) for track in trackDat: trackFile.write(','.join(trackDat[track]) + '\n') trackFile.close() trackOut = os.path.join(wellPath, chanName + "_trackModel.xml") trackFile = File(trackOut) writer = TmXmlWriter(trackFile, model.getLogger()) #writer.appendLog( logPanel.getTextContent() ); writer.appendModel(trackmate.getModel()) writer.appendSettings(trackmate.getSettings()) #writer.appendGUIState( controller.getGuimodel() ); writer.writeToFile() model.clearSpots(True) model.clearTracks(True) return trackDat
def run_process(input_path, output_path): IJ.run("Image Sequence...", "open=[" + input_path + "] convert sort") imp = WindowManager.getCurrentImage() dims = imp.getDimensions() imp.setDimensions(dims[2], dims[4], dims[3]) dims = imp.getDimensions() ImageConverter(imp).convertToGray8() model = Model() model.setLogger(Logger.IJ_LOGGER) settings = Settings() settings.setFrom(imp) settings.detectorFactory = LogDetectorFactory() settings.detectorSettings = { 'DO_SUBPIXEL_LOCALIZATION': True, 'RADIUS': float(11.0), 'THRESHOLD': float(0.0), 'DO_MEDIAN_FILTERING': True } # Configure spot filters - Classical filter on quality # filter1 = FeatureFilter('QUALITY', 30, True) # settings.addSpotFilter(filter1) settings.trackerFactory = SparseLAPTrackerFactory() settings.trackerSettings = LAPUtils.getDefaultLAPSettingsMap( ) #this sets tens of madatory settings settings.trackerSettings['LINKING_MAX_DISTANCE'] = 15.0 settings.trackerSettings['GAP_CLOSING_MAX_DISTANCE'] = 15.0 settings.trackerSettings['MAX_FRAME_GAP'] = 2 # print(LAPUtils.getDefaultLAPSettingsMap()) # # settings.trackerFactory = SimpleLAPTrackerFactory() ## settings.trackerSettings = LAPUtils.SimpleLAPTrackerFactory() #this sets tens of madatory settings # settings.trackerSettings['LINKING_MAX_DISTANCE'] = 15.0 # settings.trackerSettings['GAP_CLOSING_MAX_DISTANCE']=15.0 # settings.trackerSettings['MAX_FRAME_GAP']= 2 # settings.trackerSettings['ALLOW_GAP_CLOSING']= True # settings.trackerSettings['ALLOW_TRACK_SPLITTING']= False # settings.trackerSettings['ALLOW_TRACK_MERGING']= False # settings.trackerSettings['SPLITTING_MAX_DISTANCE']= 1000.0 # settings.trackerSettings['MERGING_MAX_DISTANCE']= 1000.0 # settings.trackerSettings['ALTERNATIVE_LINKING_COST_FACTOR']= 1000.0 # # ? # settings.trackerSettings['CUTOFF_PERCENTILE']= 1000.0 # settings.trackerSettings['BLOCKING_VALUE']= 1000.0 # # filter2 = FeatureFilter('NUMBER_OF_SPOTS_IN_TRACK', 6.86, True) # settings.addTrackFilter(filter2) trackmate = TrackMate(model, settings) ok = trackmate.checkInput() if not ok: sys.exit(str(trackmate.getErrorMessage())) raise Exception("trackmate: checkInput failed") # if ok: # print("Input ok") ok = trackmate.process() if not ok: raise Exception("trackmate: process failed") # if ok: # print("Process ok") #---------------- # Display results #---------------- model.getLogger().log('Found ' + str(model.getTrackModel().nTracks(True)) + ' tracks.') selectionModel = SelectionModel(model) displayer = HyperStackDisplayer(model, selectionModel, imp) # displayer.render() # The feature model, that stores edge and track features. fm = model.getFeatureModel() # print(fm) labels_row = [ 'id', 'spot_id', 'x', 'y', 'frame', 'quality', 'type', 'length' ] #'qualitiy','visability', 'track_length'] #rows = [] track_ids = model.getTrackModel().trackIDs(True) with open(output_path, 'w') as file: writer = csv.writer(file) writer.writerow(labels_row) for id in track_ids: # Fetch the track feature from the feature model. # model.getLogger().log('') # model.getLogger().log('Track ' + str(id) + ': mean velocity = ' + str(v) + ' ' + model.getSpaceUnits() + '/' + model.getTimeUnits()) track = model.getTrackModel().trackSpots(id) num_spots = track.size() for spot in track: # print(spot.getFeatures()) row = [] row.append(id) sid = spot.ID() row.append(sid) # Fetch spot features directly from spot. x = spot.getFeature('POSITION_X') row.append(x) y = spot.getFeature('POSITION_Y') row.append(y) t = spot.getFeature('FRAME') row.append(int(t)) # print("x: {} y: {} t: {}".format(x, y, t)) q = spot.getFeature('QUALITY') row.append(q) # snr=spot.getFeature('SNR') # row.append(snr) # mean=spot.getFeature('MEAN_INTENSITY') # row.append(mean) # visibility=spot.getFeature('VISIBILITY') # print(visibility) # break # row.append(visability) # model.getLogger().log('\tspot ID = ' + str(sid) + ': x='+str(x)+', y='+str(y)+', t='+str(t)+', q='+str(q) + ', snr='+str(snr) + ', mean = ' + str(mean)) row.append(1) row.append(num_spots) writer.writerow(row) # rows.append(row) file.close() return IJ