use of gnu.trove.set.hash.TIntHashSet in project GDSC-SMLM by aherbert.
the class TrackPopulationAnalysis method extractTrackData.
/**
* Extract the track data. This extracts different descriptors of the track using a rolling local
* window.
*
* <p>Distances are converted to {@code unit} using the provided converter and time units are
* converted from frame to seconds (s). The diffusion coefficients is in unit^2/s.
*
* <p>If categories are added they are remapped to be a natural sequence starting from 0.
*
* @param tracks the tracks
* @param distanceConverter the distance converter
* @param deltaT the time step of each frame in seconds (delta T)
* @param hasCategory if true add the category from the result to the end of the data
* @return the track data (track lengths and descriptors)
*/
private Pair<int[], double[][]> extractTrackData(List<Trace> tracks, TypeConverter<DistanceUnit> distanceConverter, double deltaT, boolean hasCategory) {
final List<double[]> data = new LocalList<>(tracks.size());
double[] x = new double[0];
double[] y = new double[0];
final int wm1 = settings.window - 1;
final int valuesLength = hasCategory ? 5 : 4;
final int mid = settings.window / 2;
final MsdFitter msdFitter = new MsdFitter(settings, deltaT);
final double significance = settings.significance;
final int[] fitResult = new int[4];
// Factor for the diffusion coefficient: 1/N * 1/(2*dimensions*deltaT) = 1 / 4Nt
// with N the number of points to average.
final double diffusionCoefficientFactor = 1.0 / (4 * wm1 * deltaT);
// Used for the standard deviations
final Statistics statsX = new Statistics();
final Statistics statsY = new Statistics();
final Ticker ticker = ImageJUtils.createTicker(tracks.size(), 1, "Computing track features...");
// Collect the track categories. Later these are renumbered to a natural sequence from 0.
final TIntHashSet catSet = new TIntHashSet();
// final StoredDataStatistics statsAlpha = new StoredDataStatistics(tracks.size());
// Process each track
final TIntArrayList lengths = new TIntArrayList(tracks.size());
for (final Trace track : tracks) {
// Get xy coordinates
final int size = track.size();
if (x.length < size) {
x = new double[size];
y = new double[size];
}
for (int i = 0; i < size; i++) {
final PeakResult peak = track.get(i);
x[i] = distanceConverter.convert(peak.getXPosition());
y[i] = distanceConverter.convert(peak.getYPosition());
}
final int smwm1 = size - wm1;
final int previousSize = data.size();
for (int k = 0; k < smwm1; k++) {
final double[] values = new double[valuesLength];
data.add(values);
// middle of even sized windows is between two localisations.
if (hasCategory) {
final int cat = track.get(k + mid).getCategory();
values[4] = cat;
catSet.add(cat);
}
// First point in window = k
// Last point in window = k + w - 1 = k + wm1
final int end = k + wm1;
// 1. Anomalous exponent.
msdFitter.setData(x, y);
try {
msdFitter.fit(k, null);
// statsAlpha.add(msdFitter.alpha);
int fitIndex = msdFitter.positiveSlope ? 0 : 2;
// If better then this is anomalous diffusion
final double alpha = msdFitter.lvmSolution2.getPoint().getEntry(2);
values[0] = alpha;
if (msdFitter.pValue > significance) {
fitIndex++;
}
fitResult[fitIndex]++;
// values[0] = msdFitter.alpha;
// // Debug
// if (
// // msdFitter.pValue < 0.2
// msdFitter.pValue < 0.2 && values[0] < 0
// // !msdFitter.positiveSlope
// ) {
// final RealVector p = msdFitter.lvmSolution2.getPoint();
// final String title = "anomalous exponent";
// final Plot plot = new Plot(title, "time (s)", "MSD (um^2)");
// final double[] t = SimpleArrayUtils.newArray(msdFitter.s.length, deltaT, deltaT);
// plot.addLabel(0, 0, msdFitter.lvmSolution2.getPoint().toString() + " p="
// + msdFitter.pValue + ". " + msdFitter.lvmSolution1.getPoint().toString());
// plot.addPoints(t, msdFitter.s, Plot.CROSS);
// plot.addPoints(t, msdFitter.model2.value(p).getFirst().toArray(), Plot.LINE);
// plot.setColor(Color.BLUE);
// plot.addPoints(t,
// msdFitter.model1.value(msdFitter.lvmSolution1.getPoint()).getFirst().toArray(),
// Plot.LINE);
// plot.setColor(Color.RED);
// final double[] yy = Arrays.stream(t).map(msdFitter.reg::predict).toArray();
// plot.addPoints(t, yy, Plot.CIRCLE);
// System.out.printf("%s : %s", msdFitter.lvmSolution2.getPoint(), values[0]);
// ImageJUtils.display(title, plot, ImageJUtils.NO_TO_FRONT);
// System.out.println();
// }
} catch (TooManyIterationsException | ConvergenceException ex) {
if (settings.debug) {
ImageJUtils.log("Failed to fit anomalous exponent: " + ex.getMessage());
}
// Ignore this and leave as Brownian motion
values[0] = 1.0;
}
// Referenced papers:
// Hozé, N. H., D. (2017) Statistical methods for large ensembles of super-resolution
// stochastic single particle trajectories in cell biology.
// Annual Review of Statistics and Its Application 4, 189-223
//
// Amitai, A., Seeber, A., Gasser, S. M. & Holcman, D. (2017) Visualization of Chromatin
// Decompaction and Break Site Extrusion as Predicted by Statistical Polymer
// Modeling of Single-Locus Trajectories. Cell reports 18, 1200-1214
// 2. Effective diffusion coefficient (Hozé, eq 10).
// This is the average squared jump distance between successive points
// divided by 1 / (2 * dimensions * deltaT), i.e. 1 / 4t.
double sum = 0;
for (int i = k; i < end; i++) {
sum += MathUtils.distance2(x[i], y[i], x[i + 1], y[i + 1]);
}
values[1] = sum * diffusionCoefficientFactor;
// 3. Length of confinement (Amitai et al, eq 1).
// Compute the average of the standard deviation of the position in each dimension.
statsX.reset();
statsY.reset();
for (int i = k; i <= end; i++) {
statsX.add(x[i]);
statsY.add(y[i]);
}
values[2] = (statsX.getStandardDeviation() + statsY.getStandardDeviation()) / 2;
// 4. Magnitude of drift vector (Hozé, eq 9).
// Note: The drift field is given as the expected distance between successive points, i.e.
// the average step. Since all track windows are the same length this is the same
// as the distance between the first and last point divided by the number of points.
// The drift field in each dimension is combined to create a drift norm, i.e. Euclidean
// distance.
values[3] = MathUtils.distance(x[k], y[k], x[end], y[end]) / wm1;
}
lengths.add(data.size() - previousSize);
ticker.tick();
}
ImageJUtils.finished();
if (settings.debug) {
ImageJUtils.log(" +Slope, significant: %d", fitResult[0]);
ImageJUtils.log(" +Slope, insignificant: %d", fitResult[1]);
ImageJUtils.log(" -Slope, significant: %d", fitResult[2]);
ImageJUtils.log(" -Slope, insignificant: %d", fitResult[3]);
}
ImageJUtils.log("Insignificant anomalous exponents: %d / %d", fitResult[1] + fitResult[3], data.size());
// System.out.println(statsAlpha.getStatistics().toString());
final double[][] trackData = data.toArray(new double[0][0]);
if (hasCategory) {
final int[] categories = catSet.toArray();
Arrays.sort(categories);
// Only remap if non-compact (i.e. not 0 to n)
final int max = categories[categories.length - 1];
if (categories[0] != 0 || max + 1 != categories.length) {
final int[] remap = new int[max + 1];
for (int i = 0; i < categories.length; i++) {
remap[categories[i]] = i;
}
final int end = valuesLength - 1;
for (final double[] values : trackData) {
values[end] = remap[(int) values[end]];
}
}
}
return Pair.create(lengths.toArray(), trackData);
}
use of gnu.trove.set.hash.TIntHashSet in project GDSC-SMLM by aherbert.
the class BenchmarkFilterAnalysis method showOverlay.
/**
* Show overlay.
*
* <ul>
*
* <li>Green = TP
*
* <li>Red = FP
*
* <li>Magenta = FP (Ignored from analysis)
*
* <li>Yellow = FN
*
* <li>Orange = FN (Outside border)
*
* </ul>
*
* @param allAssignments The assignments generated from running the filter (or null)
* @param filter the filter
* @return The results from running the filter (or null)
*/
@Nullable
@SuppressWarnings("null")
private PreprocessedPeakResult[] showOverlay(ArrayList<FractionalAssignment[]> allAssignments, DirectFilter filter) {
final ImagePlus imp = CreateData.getImage();
if (imp == null) {
return null;
}
// Run the filter manually to get the results that pass.
if (allAssignments == null) {
allAssignments = getAssignments(filter);
}
final Overlay o = new Overlay();
// Do TP
final TIntHashSet actual = new TIntHashSet();
final TIntHashSet predicted = new TIntHashSet();
for (final FractionalAssignment[] assignments : allAssignments) {
if (assignments == null || assignments.length == 0) {
continue;
}
float[] tx = null;
float[] ty = null;
int count = 0;
if (settings.showTP) {
tx = new float[assignments.length];
ty = new float[assignments.length];
}
int frame = 0;
for (int i = 0; i < assignments.length; i++) {
final CustomFractionalAssignment c = (CustomFractionalAssignment) assignments[i];
final UniqueIdPeakResult peak = (UniqueIdPeakResult) c.peak;
final BasePreprocessedPeakResult spot = (BasePreprocessedPeakResult) c.peakResult;
actual.add(peak.uniqueId);
predicted.add(spot.getUniqueId());
frame = spot.getFrame();
if (settings.showTP) {
tx[count] = spot.getX();
ty[count++] = spot.getY();
}
}
if (settings.showTP) {
SpotFinderPreview.addRoi(frame, o, tx, ty, count, Color.green);
}
}
float[] x = new float[10];
float[] y = new float[x.length];
float[] x2 = new float[10];
float[] y2 = new float[x2.length];
// Do FP (all remaining results that are not a TP)
PreprocessedPeakResult[] filterResults = null;
if (settings.showFP) {
final MultiPathFilter multiPathFilter = createMpf(filter, defaultMinimalFilter);
filterResults = filterResults(multiPathFilter);
int frame = 0;
int c1 = 0;
int c2 = 0;
for (int i = 0; i < filterResults.length; i++) {
if (frame != filterResults[i].getFrame()) {
if (c1 != 0) {
SpotFinderPreview.addRoi(frame, o, x, y, c1, Color.red);
}
if (c2 != 0) {
SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
}
c1 = c2 = 0;
}
frame = filterResults[i].getFrame();
if (predicted.contains(filterResults[i].getUniqueId())) {
continue;
}
if (filterResults[i].ignore()) {
if (x2.length == c2) {
x2 = Arrays.copyOf(x2, c2 * 2);
y2 = Arrays.copyOf(y2, c2 * 2);
}
x2[c2] = filterResults[i].getX();
y2[c2++] = filterResults[i].getY();
} else {
if (x.length == c1) {
x = Arrays.copyOf(x, c1 * 2);
y = Arrays.copyOf(y, c1 * 2);
}
x[c1] = filterResults[i].getX();
y[c1++] = filterResults[i].getY();
}
}
if (c1 != 0) {
SpotFinderPreview.addRoi(frame, o, x, y, c1, Color.red);
}
if (c2 != 0) {
SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.magenta);
}
}
// Do FN (all remaining peaks that have not been matched)
if (settings.showFN) {
final boolean checkBorder = (filterResult.analysisBorder != null && filterResult.analysisBorder.x != 0);
final float border;
final float xlimit;
final float ylimit;
if (checkBorder) {
final Rectangle lastAnalysisBorder = filterResult.analysisBorder;
border = lastAnalysisBorder.x;
xlimit = lastAnalysisBorder.x + lastAnalysisBorder.width;
ylimit = lastAnalysisBorder.y + lastAnalysisBorder.height;
} else {
border = xlimit = ylimit = 0;
}
// Add the results to the lists
actualCoordinates.forEachEntry(new CustomTIntObjectProcedure(x, y, x2, y2) {
@Override
public boolean execute(int frame, UniqueIdPeakResult[] results) {
int c1 = 0;
int c2 = 0;
if (x.length <= results.length) {
x = new float[results.length];
y = new float[results.length];
}
if (x2.length <= results.length) {
x2 = new float[results.length];
y2 = new float[results.length];
}
for (int i = 0; i < results.length; i++) {
// Ignore those that were matched by TP
if (actual.contains(results[i].uniqueId)) {
continue;
}
if (checkBorder && outsideBorder(results[i], border, xlimit, ylimit)) {
x2[c2] = results[i].getXPosition();
y2[c2++] = results[i].getYPosition();
} else {
x[c1] = results[i].getXPosition();
y[c1++] = results[i].getYPosition();
}
}
if (c1 != 0) {
SpotFinderPreview.addRoi(frame, o, x, y, c1, Color.yellow);
}
if (c2 != 0) {
SpotFinderPreview.addRoi(frame, o, x2, y2, c2, Color.orange);
}
return true;
}
});
}
imp.setOverlay(o);
return filterResults;
}
use of gnu.trove.set.hash.TIntHashSet in project GDSC-SMLM by aherbert.
the class ResultsMatchCalculator method showResults.
@SuppressWarnings("null")
private void showResults(MemoryPeakResults results1, MemoryPeakResults results2, final List<PointPair> allMatches, int n1, int n2, final boolean doIdAnalysis1, final boolean doIdAnalysis2, TextWindow resultsWindow) {
if (!settings.showTable) {
return;
}
// Output the results
Consumer<String> output;
if (resultsWindow != null) {
output = resultsWindow::append;
} else {
// Headless mode
output = IJ::log;
if (writeHeader.get()) {
writeHeader.set(false);
IJ.log(createResultsHeader(settings.idAnalysis));
}
}
// We have the results for the largest distance.
// Now reduce the distance threshold and recalculate the results
final double[] distanceThresholds = getDistances(settings.distanceThreshold, settings.increments, settings.delta);
final double[] pairDistances = getPairDistances(allMatches);
// Re-use storage for the ID analysis
TIntHashSet id1 = null;
TIntHashSet id2 = null;
TIntHashSet matchId1 = null;
TIntHashSet matchId2 = null;
final boolean doIdAnalysis = doIdAnalysis1 || doIdAnalysis2;
if (doIdAnalysis) {
if (doIdAnalysis1) {
id1 = getIds(results1);
matchId1 = new TIntHashSet(id1.size());
}
if (doIdAnalysis2) {
id2 = getIds(results2);
matchId2 = new TIntHashSet(id2.size());
}
}
final StringBuilder sb = new StringBuilder();
for (final double distanceThreshold : distanceThresholds) {
double rms = 0;
int tp2 = 0;
final double d2 = distanceThreshold * distanceThreshold;
for (final double d : pairDistances) {
if (d <= d2) {
rms += d;
tp2++;
}
}
// All non-true positives must be added to the false totals.
final int fp2 = n2 - tp2;
final int fn2 = n1 - tp2;
// RMSD to be the root mean square deviation in a single dimension so divide by 2.
// (This assumes 2D Euclidean distances.)
final MatchResult result = new MatchResult(tp2, fp2, fn2, Math.sqrt(MathUtils.div0(rms / 2, tp2)));
MatchResult idResult1 = null;
MatchResult idResult2 = null;
if (doIdAnalysis) {
if (doIdAnalysis1) {
matchId1.clear();
}
if (doIdAnalysis2) {
matchId2.clear();
}
int index = 0;
for (final PointPair pair : allMatches) {
if (pairDistances[index++] <= d2) {
if (doIdAnalysis1) {
matchId1.add(((PeakResultPoint) pair.getPoint1()).getPeakResult().getId());
}
if (doIdAnalysis2) {
matchId2.add(((PeakResultPoint) pair.getPoint2()).getPeakResult().getId());
}
}
}
// => Only the recall will be valid: tp / (tp + fn)
if (doIdAnalysis1) {
idResult1 = new MatchResult(matchId1.size(), 0, id1.size() - matchId1.size(), 0);
}
if (doIdAnalysis2) {
idResult2 = new MatchResult(matchId2.size(), 0, id2.size() - matchId2.size(), 0);
}
}
addResult(sb, settings.inputOption1, settings.inputOption2, distanceThreshold, result, idResult1, idResult2);
output.accept(sb.toString());
}
}
use of gnu.trove.set.hash.TIntHashSet in project GDSC-SMLM by aherbert.
the class ClassificationMatchCalculator method getTimepoints.
/**
* Merge the time points from each map into a single sorted list of unique time points.
*
* @param actualCoordinates the actual coordinates
* @param predictedCoordinates the predicted coordinates
* @return a list of time points
*/
private static int[] getTimepoints(TIntObjectHashMap<List<PeakResultPoint>> actualCoordinates, TIntObjectHashMap<List<PeakResultPoint>> predictedCoordinates) {
// Do inline to avoid materialising the keys arrays
final TIntHashSet hashset = new TIntHashSet(Math.max(actualCoordinates.size(), predictedCoordinates.size()));
final TIntProcedure p = value -> {
hashset.add(value);
return true;
};
actualCoordinates.forEachKey(p);
predictedCoordinates.forEachKey(p);
final int[] set = hashset.toArray();
Arrays.sort(set);
return set;
}
use of gnu.trove.set.hash.TIntHashSet in project JGibbLabeledLDA by myleott.
the class LDADataset method addDoc.
/**
* add a new document
* @param str string contains doc
*/
public void addDoc(String str, boolean unlabeled) {
// read document labels (if provided)
TIntArrayList labels = null;
if (str.startsWith("[")) {
String[] labelsBoundary = str.substring(// remove initial '['
1).split("]", // separate labels and str between ']'
2);
String[] labelStrs = labelsBoundary[0].trim().split("[ \\t]");
str = labelsBoundary[1].trim();
// parse labels (unless we're ignoring the labels)
if (!unlabeled) {
// store labels in a HashSet to ensure uniqueness
TIntHashSet label_set = new TIntHashSet();
for (String labelStr : labelStrs) {
try {
label_set.add(Integer.parseInt(labelStr.trim()));
} catch (NumberFormatException nfe) {
System.err.println("Unknown document label ( " + labelStr + " ) for document " + docs.size() + ".");
}
}
labels = new TIntArrayList(label_set);
labels.sort();
}
}
String[] words = str.split("[ \\t\\n]");
TIntArrayList ids = new TIntArrayList();
for (String word : words) {
if (word.trim().equals("")) {
continue;
}
int _id = localDict.word2id.size();
if (localDict.contains(word))
_id = localDict.getID(word);
if (globalDict != null) {
// get the global id
if (globalDict.contains(word)) {
localDict.addWord(word);
lid2gid.put(_id, globalDict.getID(word));
ids.add(_id);
}
} else {
localDict.addWord(word);
ids.add(_id);
}
}
setDoc(new Document(ids, str, labels), docs.size());
V = localDict.word2id.size();
}
Aggregations