Search in sources :

Example 6 with DataException

use of uk.ac.sussex.gdsc.core.data.DataException in project GDSC-SMLM by aherbert.

the class TranslateResults method run.

@Override
public void run(String arg) {
    SmlmUsageTracker.recordPlugin(this.getClass(), arg);
    if (MemoryPeakResults.isMemoryEmpty()) {
        IJ.error(TITLE, "There are no fitting results in memory");
        return;
    }
    final TranslateResultsSettings.Builder settings = SettingsManager.readTranslateResultsSettings(0).toBuilder();
    // Show a dialog allowing the results set to be filtered
    final ExtendedGenericDialog gd = new ExtendedGenericDialog(TITLE);
    gd.addMessage("Select a dataset to translate");
    ResultsManager.addInput(gd, settings.getInputOption(), InputSource.MEMORY);
    gd.addNumericField("x", settings.getDx(), 3);
    gd.addNumericField("y", settings.getDy(), 3);
    gd.addNumericField("z", settings.getDz(), 3);
    gd.addChoice("Distance_unit", SettingsManager.getDistanceUnitNames(), settings.getDistanceUnitValue());
    gd.addHelp(HelpUrls.getUrl("translate-results"));
    gd.showDialog();
    if (gd.wasCanceled()) {
        return;
    }
    settings.setInputOption(ResultsManager.getInputSource(gd));
    settings.setDx(gd.getNextNumber());
    settings.setDy(gd.getNextNumber());
    settings.setDz(gd.getNextNumber());
    settings.setDistanceUnitValue(gd.getNextChoiceIndex());
    SettingsManager.writeSettings(settings);
    final MemoryPeakResults results = ResultsManager.loadInputResults(settings.getInputOption(), false, null, null);
    if (MemoryPeakResults.isEmpty(results)) {
        IJ.error(TITLE, "No results could be loaded");
        return;
    }
    TypeConverter<DistanceUnit> converter;
    try {
        converter = results.getDistanceConverter(settings.getDistanceUnit());
    } catch (final DataException ex) {
        IJ.error(TITLE, "Unit conversion error: " + ex.getMessage());
        return;
    }
    final float x = (float) converter.convertBack(settings.getDx());
    final float y = (float) converter.convertBack(settings.getDy());
    final float z = (float) converter.convertBack(settings.getDz());
    // Reset the 2D bounds
    if (x != 0 || y != 0) {
        results.setBounds(null);
    }
    results.forEach((PeakResultProcedure) peakResult -> {
        final float[] params = peakResult.getParameters();
        params[PeakResult.X] += x;
        params[PeakResult.Y] += y;
        params[PeakResult.Z] += z;
    });
}
Also used : MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) IJ(ij.IJ) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) InputSource(uk.ac.sussex.gdsc.smlm.ij.plugins.ResultsManager.InputSource) TranslateResultsSettings(uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.TranslateResultsSettings) DataException(uk.ac.sussex.gdsc.core.data.DataException) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) PeakResultProcedure(uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure) PlugIn(ij.plugin.PlugIn) TypeConverter(uk.ac.sussex.gdsc.core.data.utils.TypeConverter) SettingsManager(uk.ac.sussex.gdsc.smlm.ij.settings.SettingsManager) DataException(uk.ac.sussex.gdsc.core.data.DataException) TranslateResultsSettings(uk.ac.sussex.gdsc.smlm.ij.settings.GUIProtos.TranslateResultsSettings) MemoryPeakResults(uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults) ExtendedGenericDialog(uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog) DistanceUnit(uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit)

Example 7 with DataException

use of uk.ac.sussex.gdsc.core.data.DataException in project GDSC-SMLM by aherbert.

the class TrackPopulationAnalysis method getTracks.

/**
 * Gets the tracks. Each track has contiguous frames and the length is enough to fit
 * {@code minTrackLength} overlapping windows of the specified size:
 *
 * <pre>
 * length >= window + minTrackLength - 1
 * </pre>
 *
 * @param combinedResults the combined results
 * @param window the window size
 * @param minTrackLength the minimum track length (assumed to be {@code >= 1})
 * @return the tracks
 */
private static List<Trace> getTracks(List<MemoryPeakResults> combinedResults, int window, int minTrackLength) {
    final LocalList<Trace> tracks = new LocalList<>();
    final Statistics stats = new Statistics();
    final int minSize = window + Math.max(minTrackLength, 1) - 1;
    combinedResults.forEach(results -> {
        final int start = tracks.size();
        // Sort by id then frame
        results = results.copy();
        results.sort(IdFramePeakResultComparator.INSTANCE);
        final int size = results.size();
        // Skip IDs not associated with clustering
        int index = 0;
        while (index < size && results.get(index).getId() < 1) {
            index++;
        }
        // Initialise current id and frame
        int id = results.get(index).getId() - 1;
        int frame = results.get(index).getFrame();
        Trace track = new Trace();
        for (; index < size; index++) {
            final PeakResult result = results.get(index);
            // Same ID and contiguous frames
            if (result.getId() != id || result.getFrame() != frame + 1) {
                addTrack(minSize, tracks, track);
                track = new Trace();
            }
            id = result.getId();
            frame = result.getFrame();
            track.add(result);
        }
        addTrack(minSize, tracks, track);
        stats.reset();
        for (int i = start; i < tracks.size(); i++) {
            stats.add(tracks.unsafeGet(i).size());
        }
        final StringBuilder sb = new StringBuilder(256);
        TextUtils.formatTo(sb, "%s tracks=%d, length=%s +/- %s", results.getName(), stats.getN(), MathUtils.rounded(stats.getMean(), 3), MathUtils.rounded(stats.getStandardDeviation(), 3));
        // Limit of diffusion coefficient from the localisation precision.
        // Just use the entire dataset for simplicity (i.e. not the tracks of min length).
        final PrecisionResultProcedure pp = new PrecisionResultProcedure(results);
        try {
            pp.getPrecision();
            final Mean mean = new Mean();
            for (final double p : pp.precisions) {
                mean.add(p);
            }
            // 2nDt = MSD (n = number of dimensions)
            // D = MSD / 2nt
            final CalibrationReader reader = results.getCalibrationReader();
            final double t = reader.getExposureTime() / 1000.0;
            // Assume computed in nm. Convert to um.
            final double x = mean.getMean() / 1000;
            final double d = x * x / (2 * t);
            TextUtils.formatTo(sb, ", precision=%s nm, D limit=%s um^2/s", MathUtils.rounded(x * 1000, 4), MathUtils.rounded(d, 4));
        } catch (final DataException ex) {
        // No precision
        }
        IJ.log(sb.toString());
    });
    return tracks;
}
Also used : Trace(uk.ac.sussex.gdsc.smlm.results.Trace) LocalList(uk.ac.sussex.gdsc.core.utils.LocalList) Mean(uk.ac.sussex.gdsc.core.math.Mean) DataException(uk.ac.sussex.gdsc.core.data.DataException) PrecisionResultProcedure(uk.ac.sussex.gdsc.smlm.results.procedures.PrecisionResultProcedure) CalibrationReader(uk.ac.sussex.gdsc.smlm.data.config.CalibrationReader) Statistics(uk.ac.sussex.gdsc.core.utils.Statistics) PeakResult(uk.ac.sussex.gdsc.smlm.results.PeakResult) AttributePeakResult(uk.ac.sussex.gdsc.smlm.results.AttributePeakResult)

Example 8 with DataException

use of uk.ac.sussex.gdsc.core.data.DataException in project GDSC-SMLM by aherbert.

the class PoissonCalculatorTest method canComputeLogLikelihoodRatio.

private static void canComputeLogLikelihoodRatio(RandomSeed seed, BaseNonLinearFunction nlf) {
    logger.log(TestLogUtils.getRecord(LOG_LEVEL, nlf.name));
    final int n = maxx * maxx;
    final double[] a = new double[] { 1 };
    // Simulate Poisson process
    nlf.initialise(a);
    final UniformRandomProvider rng = RngUtils.create(seed.getSeed());
    final double[] x = new double[n];
    final double[] u = new double[n];
    for (int i = 0; i < n; i++) {
        u[i] = nlf.eval(i);
        if (u[i] > 0) {
            x[i] = GdscSmlmTestUtils.createPoissonSampler(rng, u[i]).sample();
        }
    }
    final DoubleDoubleBiPredicate predicate = TestHelper.doublesAreClose(1e-10, 0);
    double ll = PoissonCalculator.logLikelihood(u, x);
    final double mll = PoissonCalculator.maximumLogLikelihood(x);
    double llr = -2 * (ll - mll);
    double llr2 = PoissonCalculator.logLikelihoodRatio(u, x);
    logger.log(TestLogUtils.getRecord(LOG_LEVEL, "llr=%f, llr2=%f", llr, llr2));
    TestAssertions.assertTest(llr, llr2, predicate, "Log-likelihood ratio");
    final double[] op = new double[x.length];
    for (int i = 0; i < n; i++) {
        op[i] = PoissonCalculator.maximumLikelihood(x[i]);
    }
    // TestSettings.setLogLevel(uk.ac.sussex.gdsc.smlm.TestLog.Level.FINE);
    final int df = n - 1;
    final ChiSquaredDistributionTable table = ChiSquaredDistributionTable.createUpperTailed(0.05, df);
    final ChiSquaredDistributionTable table2 = ChiSquaredDistributionTable.createUpperTailed(0.001, df);
    if (logger.isLoggable(LOG_LEVEL)) {
        logger.log(TestLogUtils.getRecord(LOG_LEVEL, "Chi2 = %f (q=%.3f), %f (q=%.3f)  %f %b  %f", table.getCrititalValue(df), table.getSignificanceValue(), table2.getCrititalValue(df), table2.getSignificanceValue(), ChiSquaredDistributionTable.computeQValue(24, 2), ChiSquaredDistributionTable.createUpperTailed(0.05, 2).reject(24, 2), ChiSquaredDistributionTable.getChiSquared(1e-6, 2)));
    }
    final TDoubleArrayList list = new TDoubleArrayList();
    final int imin = 5;
    final int imax = 15;
    for (int i = imin; i <= imax; i++) {
        a[0] = (double) i / 10;
        nlf.initialise(a);
        for (int j = 0; j < n; j++) {
            u[j] = nlf.eval(j);
        }
        ll = PoissonCalculator.logLikelihood(u, x);
        list.add(ll);
        llr = PoissonCalculator.logLikelihoodRatio(u, x);
        BigDecimal product = new BigDecimal(1);
        double ll2 = 0;
        for (int j = 0; j < n; j++) {
            final double p1 = PoissonCalculator.likelihood(u[j], x[j]);
            ll2 += Math.log(p1);
            final double ratio = p1 / op[j];
            product = product.multiply(new BigDecimal(ratio));
        }
        llr2 = -2 * Math.log(product.doubleValue());
        final double p = ChiSquaredDistributionTable.computePValue(llr, df);
        final double q = ChiSquaredDistributionTable.computeQValue(llr, df);
        logger.log(TestLogUtils.getRecord(LOG_LEVEL, "a=%f, ll=%f, ll2=%f, llr=%f, llr2=%f, product=%s, p=%f, q=%f " + "(reject=%b @ %.3f, reject=%b @ %.3f)", a[0], ll, ll2, llr, llr2, product.round(new MathContext(4)).toString(), p, q, table.reject(llr, df), table.getSignificanceValue(), table2.reject(llr, df), table2.getSignificanceValue()));
        // too small to store in a double.
        if (product.doubleValue() > 0) {
            TestAssertions.assertTest(ll, ll2, predicate, "Log-likelihood");
            TestAssertions.assertTest(llr, llr2, predicate, "Log-likelihood ratio");
        }
    }
    // Find max using quadratic fit
    final double[] data = list.toArray();
    int index = SimpleArrayUtils.findMaxIndex(data);
    final double maxa = (double) (imin + index) / 10;
    double fita = maxa;
    try {
        if (index == 0) {
            index++;
        }
        if (index == data.length - 1) {
            index--;
        }
        final int i1 = index - 1;
        final int i2 = index;
        final int i3 = index + 1;
        fita = QuadraticUtils.findMinMax((double) (imin + i1) / 10, data[i1], (double) (imin + i2) / 10, data[i2], (double) (imin + i3) / 10, data[i3]);
    } catch (final DataException ex) {
    // Ignore
    }
    // Allow a tolerance as the random data may alter the p-value computation.
    // Should allow it to be less than 2 increment either side of the answer.
    logger.log(TestLogUtils.getRecord(LOG_LEVEL, "max fit = %g => %g", maxa, fita));
    Assertions.assertEquals(1, fita, 0.199, "max");
}
Also used : DataException(uk.ac.sussex.gdsc.core.data.DataException) DoubleDoubleBiPredicate(uk.ac.sussex.gdsc.test.api.function.DoubleDoubleBiPredicate) TDoubleArrayList(gnu.trove.list.array.TDoubleArrayList) UniformRandomProvider(org.apache.commons.rng.UniformRandomProvider) BigDecimal(java.math.BigDecimal) MathContext(java.math.MathContext)

Example 9 with DataException

use of uk.ac.sussex.gdsc.core.data.DataException in project GDSC-SMLM by aherbert.

the class ScmosLikelihoodWrapperTest method canComputePValue.

private static void canComputePValue(RandomSeed seed, BaseNonLinearFunction nlf) {
    logger.log(TestLogUtils.getRecord(Level.INFO, nlf.name));
    final int n = maxx * maxx;
    final double[] a = new double[] { 1 };
    // Simulate sCMOS camera
    nlf.initialise(a);
    final SCcmosLikelihoodWrapperTestData testData = (SCcmosLikelihoodWrapperTestData) dataCache.computeIfAbsent(seed, ScmosLikelihoodWrapperTest::createData);
    final float[] var = testData.var;
    final float[] g = testData.gain;
    final float[] o = testData.offset;
    final float[] sd = testData.sd;
    final UniformRandomProvider r = RngUtils.create(seed.getSeed());
    final SharedStateContinuousSampler gs = SamplerUtils.createGaussianSampler(r, 0, 1);
    final double[] k = SimpleArrayUtils.newArray(n, 0, 1.0);
    for (int i = 0; i < n; i++) {
        double mean = nlf.eval(i);
        if (mean > 0) {
            mean = GdscSmlmTestUtils.createPoissonSampler(r, mean).sample();
        }
        k[i] = mean * g[i] + o[i] + gs.sample() * sd[i];
    }
    final ScmosLikelihoodWrapper f = new ScmosLikelihoodWrapper(nlf, a, k, n, var, g, o);
    final double oll = f.computeObservedLikelihood();
    double oll2 = 0;
    final double[] op = new double[n];
    for (int j = 0; j < n; j++) {
        op[j] = ScmosLikelihoodWrapper.likelihood((k[j] - o[j]) / g[j], var[j], g[j], o[j], k[j]);
        oll2 -= Math.log(op[j]);
    }
    logger.log(TestLogUtils.getRecord(Level.INFO, "oll=%f, oll2=%f", oll, oll2));
    final DoubleDoubleBiPredicate predicate = TestHelper.doublesAreClose(1e-10, 0);
    TestAssertions.assertTest(oll2, oll, predicate, "Observed Log-likelihood");
    final TDoubleArrayList list = new TDoubleArrayList();
    final int imin = 5;
    final int imax = 15;
    for (int i = imin; i <= imax; i++) {
        a[0] = (double) i / 10;
        final double ll = f.likelihood(a);
        list.add(ll);
        final double llr = f.computeLogLikelihoodRatio(ll);
        BigDecimal product = new BigDecimal(1);
        double ll2 = 0;
        for (int j = 0; j < n; j++) {
            final double p1 = ScmosLikelihoodWrapper.likelihood(nlf.eval(j), var[j], g[j], o[j], k[j]);
            ll2 -= Math.log(p1);
            final double ratio = p1 / op[j];
            product = product.multiply(new BigDecimal(ratio));
        }
        final double llr2 = -2 * Math.log(product.doubleValue());
        final double q = f.computeQValue(ll);
        logger.log(TestLogUtils.getRecord(Level.INFO, "a=%f, ll=%f, ll2=%f, llr=%f, llr2=%f, product=%s, p=%f", a[0], ll, ll2, llr, llr2, product.round(new MathContext(4)).toString(), q));
        // too small to store in a double.
        if (product.doubleValue() > 0) {
            TestAssertions.assertTest(llr, llr2, predicate, "Log-likelihood");
        }
    }
    // Find min using quadratic fit
    final double[] data = list.toArray();
    int index = SimpleArrayUtils.findMinIndex(data);
    final double mina = (double) (imin + index) / 10;
    double fita = mina;
    try {
        if (index == 0) {
            index++;
        }
        if (index == data.length - 1) {
            index--;
        }
        final int i1 = index - 1;
        final int i2 = index;
        final int i3 = index + 1;
        fita = QuadraticUtils.findMinMax((double) (imin + i1) / 10, data[i1], (double) (imin + i2) / 10, data[i2], (double) (imin + i3) / 10, data[i3]);
    } catch (final DataException ex) {
    // Ignore
    }
    // Allow a tolerance as the random data may alter the p-value computation.
    // Should allow it to be less than 2 increment either side of the answer.
    logger.log(TestLogUtils.getRecord(Level.INFO, "min fit = %g => %g", mina, fita));
    Assertions.assertEquals(1, fita, 0.199, "min");
}
Also used : DoubleDoubleBiPredicate(uk.ac.sussex.gdsc.test.api.function.DoubleDoubleBiPredicate) SharedStateContinuousSampler(org.apache.commons.rng.sampling.distribution.SharedStateContinuousSampler) BigDecimal(java.math.BigDecimal) MathContext(java.math.MathContext) DataException(uk.ac.sussex.gdsc.core.data.DataException) TDoubleArrayList(gnu.trove.list.array.TDoubleArrayList) UniformRandomProvider(org.apache.commons.rng.UniformRandomProvider)

Example 10 with DataException

use of uk.ac.sussex.gdsc.core.data.DataException in project GDSC-SMLM by aherbert.

the class CreateFilters method processElement.

private int processElement(StringWriter sw, Node node) throws TransformerFactoryConfigurationError {
    // Get entire element as a string
    final String xmlString = uk.ac.sussex.gdsc.core.utils.XmlUtils.getString(node, false);
    ArrayList<StringBuilder> out = new ArrayList<>();
    // Process through the XML appending to the current output.
    final String[] tokens = xmlString.split("\\s+");
    for (final String token : tokens) {
        // Any attributes with enumerations should be expanded.
        final Matcher match = pattern.matcher(token);
        if (match.find()) {
            final String prefix = " " + match.group(1) + "=\"";
            // Use Big Decimal for the enumeration to preserve the precision of the input text
            // (i.e. using doubles for an enumeration can lose precision and fail to correctly
            // enumerate)
            BigDecimal min;
            BigDecimal max;
            BigDecimal inc;
            try {
                min = new BigDecimal(match.group(2));
                max = new BigDecimal(match.group(3));
                inc = new BigDecimal(match.group(4));
                if (min.compareTo(max) > 0 || inc.compareTo(BigDecimal.ZERO) <= 0) {
                    throw new DataException("Invalid 'min:max:increment' attribute: " + token);
                }
            } catch (final NumberFormatException ex) {
                throw new DataException("Invalid 'min:max:increment' attribute: " + token, ex);
            }
            final String suffix = "\"" + match.group(5);
            // Enumerate the attribute
            final ArrayList<String> attributeText = new ArrayList<>();
            for (BigDecimal bd = min; bd.compareTo(max) <= 0; bd = bd.add(inc)) {
                attributeText.add(prefix + bd.toString() + suffix);
            }
            // Add to the current output
            final ArrayList<StringBuilder> out2 = new ArrayList<>(out.size() * attributeText.size());
            if (enumerateEarly) {
                // Enumerate earlier attributes first
                for (final String text : attributeText) {
                    for (final StringBuilder sb : out) {
                        out2.add(new StringBuilder(sb.toString()).append(text));
                    }
                }
            } else {
                // Enumerate later attributes first
                for (final StringBuilder sb : out) {
                    final String current = sb.toString();
                    for (final String text : attributeText) {
                        out2.add(new StringBuilder(current).append(text));
                    }
                }
            }
            out = out2;
        } else if (out.isEmpty()) {
            out.add(new StringBuilder(token));
        } else {
            for (final StringBuilder sb : out) {
                sb.append(" ").append(token);
            }
        }
    }
    if (!out.isEmpty()) {
        sw.write("<FilterSet name=\"");
        sw.write(getName(out.get(0)));
        sw.write("\"><filters class=\"linked-list\">");
        for (final StringBuilder sb : out) {
            sw.write(sb.toString());
        }
        sw.write("</filters></FilterSet>");
    }
    return out.size();
}
Also used : DataException(uk.ac.sussex.gdsc.core.data.DataException) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) BigDecimal(java.math.BigDecimal)

Aggregations

DataException (uk.ac.sussex.gdsc.core.data.DataException)15 PrecisionResultProcedure (uk.ac.sussex.gdsc.smlm.results.procedures.PrecisionResultProcedure)6 ExtendedGenericDialog (uk.ac.sussex.gdsc.core.ij.gui.ExtendedGenericDialog)5 Rectangle (java.awt.Rectangle)4 PeakResult (uk.ac.sussex.gdsc.smlm.results.PeakResult)4 GenericDialog (ij.gui.GenericDialog)3 BigDecimal (java.math.BigDecimal)3 ArrayList (java.util.ArrayList)3 UniformRandomProvider (org.apache.commons.rng.UniformRandomProvider)3 TDoubleArrayList (gnu.trove.list.array.TDoubleArrayList)2 IJ (ij.IJ)2 ImageStack (ij.ImageStack)2 PlugIn (ij.plugin.PlugIn)2 ImageProcessor (ij.process.ImageProcessor)2 FileInputStream (java.io.FileInputStream)2 IOException (java.io.IOException)2 MathContext (java.math.MathContext)2 TypeConverter (uk.ac.sussex.gdsc.core.data.utils.TypeConverter)2 WindowOrganiser (uk.ac.sussex.gdsc.core.ij.plugin.WindowOrganiser)2 LocalList (uk.ac.sussex.gdsc.core.utils.LocalList)2