diff --git a/src/main/java/plugins/fab/trackmanager/processors/TrackProcessorMSD.java b/src/main/java/plugins/fab/trackmanager/processors/TrackProcessorMSD.java index b24368184e1934275a557eb4c48ee189a11dfb8d..2f1fac8c4a5f44ececd3659c1d1a424b21ea1038 100644 --- a/src/main/java/plugins/fab/trackmanager/processors/TrackProcessorMSD.java +++ b/src/main/java/plugins/fab/trackmanager/processors/TrackProcessorMSD.java @@ -105,14 +105,19 @@ public class TrackProcessorMSD extends PluginTrackManagerProcessor implements Ac { XYSeries series = new XYSeries("Track " + trackPool.getTrackIndex(ts)); - if (ts.isAllDetectionEnabled()) + // Better to allow partially clipped tracks otherwise we cannot get MSD for them (Stephane) + // TODO: check that it doesn't bring any regression + // if (ts.isAllDetectionEnabled()) { double[] msd = scaledMeanSquaredDisplacement(seq, ts); - for (int i = 0; i < msd.length; i++) - series.add(i * tScale, msd[i]); + if (msd.length > 0) + { + for (int i = 0; i < msd.length; i++) + series.add(i * tScale, msd[i]); - xyDataset.addSeries(series); + xyDataset.addSeries(series); + } } } } @@ -122,14 +127,19 @@ public class TrackProcessorMSD extends PluginTrackManagerProcessor implements Ac { XYSeries series = new XYSeries("Track " + trackPool.getTrackIndex(ts)); - if (ts.isAllDetectionEnabled()) + // Better to allow partially clipped tracks otherwise we cannot get MSD for them (Stephane) + // TODO: check that it doesn't bring any regression + // if (ts.isAllDetectionEnabled()) { double[] msd = scaledMeanSquaredDisplacement(null, ts); - for (int i = 0; i < msd.length; i++) - series.add(i, msd[i]); + if (msd.length > 0) + { + for (int i = 0; i < msd.length; i++) + series.add(i, msd[i]); - xyDataset.addSeries(series); + xyDataset.addSeries(series); + } } } } @@ -203,9 +213,11 @@ public class TrackProcessorMSD extends PluginTrackManagerProcessor implements Ac outputName = trackPool.getDisplaySequence().getFilename(); outputName += ".msd.xls"; } - else outputName = SaveDialog.chooseFileForResult("XLS MSD export", "tracks-msd", ".xls"); + else + outputName = SaveDialog.chooseFileForResult("XLS MSD export", "tracks-msd", ".xls"); - if (StringUtil.isEmpty(outputName)) return; + if (StringUtil.isEmpty(outputName)) + return; try { @@ -229,25 +241,31 @@ public class TrackProcessorMSD extends PluginTrackManagerProcessor implements Ac int row = 0; for (TrackSegment ts : trackPool.getTrackSegmentList()) { - if (ts.isAllDetectionEnabled()) + // Better to allow partially clipped tracks otherwise we cannot get MSD for them (Stephane) + // TODO: check that it doesn't bring any regression + // if (ts.isAllDetectionEnabled()) { - System.out.println("track " + cnt); - - if (page != null) - XLSUtil.setCellString(page, 0, row, "track " + cnt); - double[] msd = scaledMeanSquaredDisplacement(seq, ts); - for (int i = 0; i < msd.length; i++) + + if (msd.length > 0) { - System.out.println((i * tScale) + "\t" + msd[i]); - // System.out.println(i + "\t" + msd[i]); + System.out.println("track " + cnt); if (page != null) - XLSUtil.setCellNumber(page, i + 1, row, msd[i]); - } + XLSUtil.setCellString(page, 0, row, "track " + cnt); + + for (int i = 0; i < msd.length; i++) + { + System.out.println((i * tScale) + "\t" + msd[i]); + // System.out.println(i + "\t" + msd[i]); + + if (page != null) + XLSUtil.setCellNumber(page, i + 1, row, msd[i]); + } - cnt++; - row++; + cnt++; + row++; + } } } } @@ -258,26 +276,30 @@ public class TrackProcessorMSD extends PluginTrackManagerProcessor implements Ac for (TrackSegment ts : trackPool.getTrackSegmentList()) { - if (ts.isAllDetectionEnabled()) + // Better to allow partially clipped tracks otherwise we cannot get MSD for them (Stephane) + // TODO: check that it doesn't bring any regression + // if (ts.isAllDetectionEnabled()) { - System.out.println("track " + cnt); - - if (page != null) - XLSUtil.setCellString(page, 0, row, "track " + cnt); - double[] msd = scaledMeanSquaredDisplacement(null, ts); - // double[] msd = meanSquaredDisplacement(ts); - for (int i = 0; i < msd.length; i++) + if (msd.length > 0) { - System.out.println(i + "\t" + msd[i]); + System.out.println("track " + cnt); if (page != null) - XLSUtil.setCellNumber(page, i + 1, row, msd[i]); - } + XLSUtil.setCellString(page, 0, row, "track " + cnt); + + for (int i = 0; i < msd.length; i++) + { + System.out.println(i + "\t" + msd[i]); - cnt++; - row++; + if (page != null) + XLSUtil.setCellNumber(page, i + 1, row, msd[i]); + } + + cnt++; + row++; + } } } } @@ -320,65 +342,96 @@ public class TrackProcessorMSD extends PluginTrackManagerProcessor implements Ac sz = 1d; } - int nMSD = ts.getDetectionList().size(); - // double[] dt_n = new double[nMSD]; - double[] msd = new double[nMSD]; + final int numDetection = ts.getDetectionList().size(); + int firstEnabledDetectionIndex = -1; + int numEnabledDetection = 0; + int lastFirstEnabledDetectionIndex = -1; + int lastNumEnabledDetection = 0; - for (int t = 1; t < nMSD; t++) + // Find partially enabled/clipped tracks otherwise we cannot get MSD for them (Stephane) + // TODO: check that it doesn't bring any regression + for (int i = 0; i < numDetection; i++) { - msd[t] = 0d; - for (int j = 1; j <= t; j++) - msd[t] += scaledSquaredDistance(ts.getDetectionAt(0), ts.getDetectionAt(j), sx, sy, sz); - - msd[t] /= t; - } - - // for (int dt = 1; dt < nMSD; dt++) - // { - // for (int j = 0; (j + dt) < nMSD; j += dt) - // { - // msd[dt] += scaledSquaredDistance(ts.getDetectionAt(j), ts.getDetectionAt(j + dt), sx, sy, sz); - // dt_n[dt]++; - // } - // } - // - // for (int dt = 1; dt < nMSD; dt++) - // msd[dt] = (dt_n[dt] != 0) ? msd[dt] / dt_n[dt] : 0; + final Detection d = ts.getDetectionAt(i); - return msd; - } - - // mean squared displacement - private double[] meanSquaredDisplacement(TrackSegment ts) - { - int nMSD = ts.getDetectionList().size(); + if (d.isEnabled()) + { + // start of track + if (lastFirstEnabledDetectionIndex == -1) + { + lastFirstEnabledDetectionIndex = i; + lastNumEnabledDetection = 1; + } + else + lastNumEnabledDetection++; + } + else + { + // check if last track is the longest found + if (lastNumEnabledDetection > numEnabledDetection) + { + numEnabledDetection = lastNumEnabledDetection; + firstEnabledDetectionIndex = lastFirstEnabledDetectionIndex; + } - double[] dt_n = new double[nMSD]; - double[][] msd = new double[nMSD][2]; + // reset track + lastFirstEnabledDetectionIndex = -1; + lastNumEnabledDetection = 0; + } + } - for (int dt = 1; dt < nMSD; dt++) + // check if last track is the longest found + if (lastNumEnabledDetection > numEnabledDetection) { - msd[dt][0] = dt * 1; - - for (int j = 0; j + dt < ts.getDetectionList().size(); j += dt) - { - msd[dt][1] += squaredDistance(ts.getDetectionAt(j), ts.getDetectionAt(j + dt)); - dt_n[dt]++; - } + numEnabledDetection = lastNumEnabledDetection; + firstEnabledDetectionIndex = lastFirstEnabledDetectionIndex; } - for (int dt = 1; dt < nMSD; dt++) - msd[dt][1] = (dt_n[dt] != 0) ? msd[dt][1] / dt_n[dt] : 0; + double[] msd = new double[numEnabledDetection]; - double[] resultmsd = new double[nMSD]; - resultmsd[0] = 0; - for (int dt = 1; dt < nMSD; dt++) - resultmsd[dt] = msd[dt][1]; + for (int t = 1; t < numEnabledDetection; t++) + { + msd[t] = 0d; + for (int j = 1; j <= t; j++) + msd[t] += scaledSquaredDistance(ts.getDetectionAt(firstEnabledDetectionIndex), ts.getDetectionAt(firstEnabledDetectionIndex + j), sx, sy, sz); - return resultmsd; + msd[t] /= t; + } + return msd; } + // mean squared displacement +// private double[] meanSquaredDisplacement(TrackSegment ts) +// { +// int nMSD = ts.getDetectionList().size(); +// +// double[] dt_n = new double[nMSD]; +// double[][] msd = new double[nMSD][2]; +// +// for (int dt = 1; dt < nMSD; dt++) +// { +// msd[dt][0] = dt * 1; +// +// for (int j = 0; j + dt < ts.getDetectionList().size(); j += dt) +// { +// msd[dt][1] += squaredDistance(ts.getDetectionAt(j), ts.getDetectionAt(j + dt)); +// dt_n[dt]++; +// } +// } +// +// for (int dt = 1; dt < nMSD; dt++) +// msd[dt][1] = (dt_n[dt] != 0) ? msd[dt][1] / dt_n[dt] : 0; +// +// double[] resultmsd = new double[nMSD]; +// resultmsd[0] = 0; +// for (int dt = 1; dt < nMSD; dt++) +// resultmsd[dt] = msd[dt][1]; +// +// return resultmsd; +// +// } + private static double squaredDistance(Detection d1, Detection d2) { return scaledSquaredDistance(d1, d2, 1d, 1d, 1d);