All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.ac.sussex.gdsc.smlm.results.MemoryPeakResults Maven / Gradle / Ivy

Go to download

Genome Damage and Stability Centre SMLM Package Software for single molecule localisation microscopy (SMLM)

The newest version!
/*-
 * #%L
 * Genome Damage and Stability Centre SMLM Package
 *
 * Software for single molecule localisation microscopy (SMLM)
 * %%
 * Copyright (C) 2011 - 2023 Alex Herbert
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

package uk.ac.sussex.gdsc.smlm.results;

import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import org.apache.commons.lang3.ArrayUtils;
import uk.ac.sussex.gdsc.core.data.DataException;
import uk.ac.sussex.gdsc.core.data.VisibleForTesting;
import uk.ac.sussex.gdsc.core.data.utils.ConversionException;
import uk.ac.sussex.gdsc.core.data.utils.Converter;
import uk.ac.sussex.gdsc.core.data.utils.IdentityTypeConverter;
import uk.ac.sussex.gdsc.core.data.utils.TypeConverter;
import uk.ac.sussex.gdsc.smlm.data.config.CalibrationHelper;
import uk.ac.sussex.gdsc.smlm.data.config.ConfigurationException;
import uk.ac.sussex.gdsc.smlm.data.config.PSFProtos.PSF;
import uk.ac.sussex.gdsc.smlm.data.config.PsfHelper;
import uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.AngleUnit;
import uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.DistanceUnit;
import uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.IntensityUnit;
import uk.ac.sussex.gdsc.smlm.data.config.UnitProtos.TimeUnit;
import uk.ac.sussex.gdsc.smlm.results.count.FrameCounter;
import uk.ac.sussex.gdsc.smlm.results.procedures.BResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.BirResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.BixyResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.BixyzResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.HResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.IResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.IxyResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.IxyrResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.IxyzResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.IxyzrResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.LsePrecisionBProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.LsePrecisionProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.MlePrecisionBProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.MlePrecisionProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.PeakResultProcedureX;
import uk.ac.sussex.gdsc.smlm.results.procedures.StoredPrecisionProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.TResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.TxyResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.WResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.WxWyResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.XyResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.XyrResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.XyzResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.XyzrResultProcedure;
import uk.ac.sussex.gdsc.smlm.results.procedures.ZResultProcedure;

/**
 * Stores peak results in memory.
 *
 * 

The PeakResults interface add methods are not-thread safe. The results should be wrapped in a * SynchronizedPeakResults object if using on multiple threads. */ public class MemoryPeakResults extends AbstractPeakResults { /** The map of in-memory results sets. */ private static final Map RESULTS_MAP = Collections.synchronizedMap(new LinkedHashMap<>()); /** * The memory size of a PeakResult object without deviations. Only the standard parameters are * included. */ @VisibleForTesting static final int PEAK_RESULT_SIZE = 96; /** * The memory size of a PeakResult object with deviations. Only the standard parameters are * included. */ @VisibleForTesting static final int PEAK_RESULT_SIZE_WITH_DEVIATIONS = 136; /** The preferred distance unit. */ public static final DistanceUnit PREFERRED_DISTANCE_UNIT = DistanceUnit.PIXEL; /** The preferred intensity unit. */ public static final IntensityUnit PREFERRED_INTENSITY_UNIT = IntensityUnit.PHOTON; /** The preferred angle unit. */ public static final AngleUnit PREFERRED_ANGLE_UNIT = AngleUnit.RADIAN; private boolean sortAfterEnd; ///////////////////////////////////////////////////////////////// // START OF RESULTS STORAGE METHODS ///////////////////////////////////////////////////////////////// /** * The results. This is encapsulated to allow changing the data structure used to store the * results. */ protected final PeakResultStoreList results; /** * Gets the result. * * @param index the index * @return the peak result */ public PeakResult get(int index) { if (index >= size()) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size()); } return getfX(index); } /** * Gets the result. Note that this uses the get(int) method from the backing PeakResultStore which * may return stale data if index is outside of the current size. * * @param index the index * @return the peak result */ PeakResult getf(int index) { return this.results.get(index); } /** * Gets the result for external use or modification. Note that this uses the get(int) method from * the backing PeakResultStore which may return stale data if index is outside of the current * size. * * @param index the index * @return the peak result */ PeakResult getfX(int index) { return this.results.get(index); } @Override public int size() { return this.results.size(); } /** * Add a result. Not synchronized. * * @param result the result */ @Override public void add(PeakResult result) { this.results.add(result); } /** * Adds the results. * * @param results the results */ public void add(MemoryPeakResults results) { this.results.addStore(results.results); } /** * Add a result. * *

Not synchronized. Use SynchronizedPeakResults to wrap this instance for use across threads. * * {@inheritDoc} */ @Override public void add(int peak, int origX, int origY, float origValue, double error, float noise, float meanIntensity, float[] params, float[] paramsStdDev) { add(new PeakResult(peak, origX, origY, origValue, error, noise, meanIntensity, params, paramsStdDev)); } /** * {@inheritDoc} * *

Not synchronized. Use SynchronizedPeakResults to wrap this instance for use across threads. */ @Override public void addAll(Collection results) { this.results.addCollection(results); } /** * Add all results. * *

Not synchronized. Use SynchronizedPeakResults to wrap this instance for use across threads. */ @Override public void addAll(PeakResult[] results) { this.results.addArray(results); } /** * Add all results. * *

Not synchronized. Use SynchronizedPeakResults to wrap this instance for use across threads. */ @Override public void addAll(PeakResultStore results) { this.results.addStore(results); } /** * Clear the results. */ private void clear() { this.results.clear(); } /** * Trims the capacity of this instance to be the current size. An application can use this * operation to minimize the storage of an instance. */ public void trimToSize() { this.results.trimToSize(); } /** * Sort the results. The sort order uses the frame in ascending order. */ public void sort() { this.results.sort(); } /** * Sort the results. * * @param comparator the comparator */ public void sort(Comparator comparator) { this.results.sort(comparator); } /** * Convert to an array. This is a new allocation of storage space. * * @return the peak result array */ public PeakResult[] toArray() { return this.results.toArray(); } /** * Removes the null results from the store. */ public void removeNullResults() { this.results.removeIf(Objects::isNull); } /** * Removes the result if it matches the filter. If objects are removed then the order of elements * may change. * * @param filter the filter * @return true, if any were removed */ public boolean removeIf(Predicate filter) { return this.results.removeIf(filter); } ///////////////////////////////////////////////////////////////// // END OF RESULTS STORAGE METHODS ///////////////////////////////////////////////////////////////// /** * Creates a new memory peak results. * * @param store the backing storage implementation * @throws IllegalArgumentException If the store is null */ public MemoryPeakResults(PeakResultStoreList store) { results = Objects.requireNonNull(store, "Store"); } /** * Creates a new memory peak results. */ public MemoryPeakResults() { this(1000); } /** * Creates a new memory peak results. * * @param capacity the capacity */ public MemoryPeakResults(int capacity) { // Use the fast and simple implementation for the store results = new ArrayPeakResultStore(capacity); } /** * Creates a new memory peak results. * * @param results the results * @return the memory peak results */ public static MemoryPeakResults create(Collection results) { final MemoryPeakResults r = new MemoryPeakResults(); r.addAll(results); return r; } /** * Create a new memory peak results. * * @param psf the psf * @return the memory peak results */ public static MemoryPeakResults create(PSF psf) { final MemoryPeakResults r = new MemoryPeakResults(); r.setPsf(psf); return r; } /** * Copy constructor. * * @param source the source * @param copyResults Set to true to copy peak result objects */ protected MemoryPeakResults(MemoryPeakResults source, boolean copyResults) { copyState(source); // Copy the results results = (PeakResultStoreList) source.results.copy(copyResults); } /** * Copy the state from the source. * * @param source the source */ private void copyState(MemoryPeakResults source) { this.sortAfterEnd = source.sortAfterEnd; copySettings(source); // Deep copy the mutable bounds object final Rectangle bounds = source.getBounds(); if (bounds != null) { setBounds(new Rectangle(bounds)); } } ///////////////////////////////////////////////////////////////// // START OF STATIC MEMORY STORAGE METHODS ///////////////////////////////////////////////////////////////// /** * Gets the results. * * @param name The name of the results * @return Get the named results (or null if they do not exist) */ public static MemoryPeakResults getResults(String name) { return RESULTS_MAP.get(name); } /** * Removes the results. * * @param name The name of the results * @return The removed results (or null if they do not exist) */ public static MemoryPeakResults removeResults(String name) { return RESULTS_MAP.remove(name); } /** * Add the results to memory. The name is taken from the results. * * @param results the results */ public static void addResults(MemoryPeakResults results) { Objects.requireNonNull(results, "Results must not be null"); results.trimToSize(); RESULTS_MAP.put(results.getName(), results); } /** * Gets the result names. * * @return A set of the available named results held in memory */ public static Set getResultNames() { return RESULTS_MAP.keySet(); } /** * Gets the all results. * * @return A collection of the results held in memory */ public static Collection getAllResults() { return RESULTS_MAP.values(); } /** * Count the number of result sets in memory. * * @return the results memory size */ public static int getResultsMemorySize() { return RESULTS_MAP.size(); } /** * Return true if there are no non-empty results in memory. * * @return true, if is memory empty */ public static boolean isMemoryEmpty() { if (RESULTS_MAP.isEmpty()) { return true; } for (final MemoryPeakResults r : RESULTS_MAP.values()) { if (!r.isEmpty()) { return false; } } return true; } /** * Performs the specified test on each set of results in memory; any results must pass to return * {@code true}. Returns {@code false} if there are no results in memory. * * @param test the test * @return true, if the test passes on any result */ public static boolean isAnyInMemory(Predicate test) { for (final MemoryPeakResults r : RESULTS_MAP.values()) { if (test.test(r)) { return true; } } return false; } /** * Performs the specified test on each set of results in memory; all results must pass to return * {@code true}. Returns {@code false} if there are no results in memory. * * @param test the test * @return true, if the test passes on all results */ public static boolean isAllInMemory(Predicate test) { if (RESULTS_MAP.isEmpty()) { return false; } for (final MemoryPeakResults r : RESULTS_MAP.values()) { if (!test.test(r)) { return false; } } return true; } /** * Count the total number of results in memory. * * @return the int */ public static int countMemorySize() { int size = 0; for (final MemoryPeakResults r : RESULTS_MAP.values()) { size += r.size(); } return size; } /** * Clear the results from memory. */ public static void clearMemory() { RESULTS_MAP.clear(); } /** * Estimate the total size of results in memory. * * @return the long */ public static long estimateMemorySize() { long memorySize = 0; for (final MemoryPeakResults r : RESULTS_MAP.values()) { memorySize += estimateMemorySize(r); } return memorySize; } /** * Return an estimate of the memory size taken by PeakResult objects. * *

Note: This is just a guess based on measured sizes for the objects in memory. * * @param results the results * @return The memory size */ public static long estimateMemorySize(MemoryPeakResults results) { long memorySize = 0; if (results != null && results.size() > 0) { final boolean includeDeviations = results.getf(0).hasParameterDeviations(); memorySize = estimateMemorySize(results.size(), includeDeviations); } return memorySize; } /** * Return an estimate of the memory size taken by {@link PeakResult} objects. * *

Note: This is just a guess based on measured sizes for the objects in memory. * * @param size the number of results * @param includeDeviations Set to true if the results have deviations * @return The memory size */ public static long estimateMemorySize(int size, boolean includeDeviations) { return (long) size * ((includeDeviations) ? PEAK_RESULT_SIZE : PEAK_RESULT_SIZE_WITH_DEVIATIONS); } ///////////////////////////////////////////////////////////////// // END OF STATIC MEMORY STORAGE METHODS ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // START OF PeakResults interface METHODS // Note: Most of the methods are in the section for // storage of peak results ///////////////////////////////////////////////////////////////// /** * {@inheritDoc} * *

This clears the current results but does not reduce storage allocation. This can be done * with {@link #trimToSize()}. * * @see #trimToSize() */ @Override public void begin() { clear(); } @Override public void end() { if (isSortAfterEnd()) { sort(); } } ///////////////////////////////////////////////////////////////// // END OF PeakResults interface METHODS ///////////////////////////////////////////////////////////////// /** * Gets the bounds. These are returned in Pixel units as the bounds are defined in the PeakResults * interface as the bounds used to create the results. * * @param calculate Set to true to calculate the bounds if they are null or zero width/height * @return the bounds of the result coordinates * @throws DataException if conversion to pixel units is not possible */ public Rectangle getBounds(boolean calculate) { Rectangle bounds = getBounds(); if ((bounds == null || bounds.width == 0 || bounds.height == 0) && calculate) { bounds = new Rectangle(); // Note: The bounds should be in pixels final Rectangle2D.Float b = getDataBounds(DistanceUnit.PIXEL); // Round to integer bounds.x = (int) Math.floor(b.x); bounds.y = (int) Math.floor(b.y); final int maxX = (int) Math.ceil(b.x + b.width); final int maxY = (int) Math.ceil(b.y + b.height); bounds.width = maxX - bounds.x; bounds.height = maxY - bounds.y; setBounds(bounds); } return bounds; } /** * Gets the data bounds. * * @param distanceUnit the distance unit (if null then the data bounds will be in native units) * @return the bounds of the result coordinates * @throws DataException if conversion to the required units is not possible */ public Rectangle2D.Float getDataBounds(DistanceUnit distanceUnit) { if (isEmpty()) { return new Rectangle2D.Float(); } // Create this first to throw an exception if invalid final TypeConverter c; if (distanceUnit == null) { c = new IdentityTypeConverter<>(null); } else { c = CalibrationHelper.getDistanceConverter(getCalibration(), distanceUnit); } // Get the native bounds float minX = getf(0).getXPosition(); float maxX = minX; float minY = getf(0).getYPosition(); float maxY = minY; for (int i = 1, size = size(); i < size; i++) { final PeakResult p = getf(i); final float x = p.getXPosition(); final float y = p.getYPosition(); if (minX > x) { minX = x; } else if (maxX < x) { maxX = x; } if (minY > y) { minY = y; } else if (maxY < y) { maxY = y; } } // Convert the results //@formatter:off return new Rectangle2D.Float( c.convert(minX), c.convert(minY), c.convert(maxX - minX), c.convert(maxY - minY)); //@formatter:on } @Override public boolean isActive() { return true; } /** * Sets the sort after end. * * @param sortAfterEnd True if the results should be sorted after the {@link #end()} method */ public void setSortAfterEnd(boolean sortAfterEnd) { this.sortAfterEnd = sortAfterEnd; } /** * Checks if is sort after end. * * @return True if the results should be sorted after the {@link #end()} method */ public boolean isSortAfterEnd() { return sortAfterEnd; } /** * Copy the results. Create new objects for the properties (avoiding a shallow copy) but does not * deep copy all of the peak results. Allows results to be resorted but not modified. * * @return the memory peak results */ public MemoryPeakResults copy() { return copy(false); } /** * Copy the results. Create new objects for the properties (avoiding a shallow copy) and * optionally a deep copy all of the peak results. Copying the peak results allows modification of * their properties. * * @param copyResults Set to true to copy peak result objects * @return the memory peak results */ public MemoryPeakResults copy(boolean copyResults) { return new MemoryPeakResults(this, copyResults); } /** * Checks if the results are {@code null} or empty. * * @param results the results * @return true if {@code null} or empty */ public static boolean isEmpty(MemoryPeakResults results) { return results == null || results.isEmpty(); } /** * Checks if is empty. * * @return True if empty */ public boolean isEmpty() { return size() == 0; } /** * Checks if is not empty. * * @return True if not empty */ public boolean isNotEmpty() { return size() != 0; } /** * Checks for background. At least one result must have a non-zero background. * * @return true, if successful */ public boolean hasBackground() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).getBackground() != 0) { return true; } } return false; } /** * Checks for noise. At least one result must have a positive noise. * * @return true, if successful */ public boolean hasNoise() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).hasNoise()) { return true; } } return false; } /** * Checks for mean intensity. At least one result must have a positive mean intensity. * * @return true, if successful */ public boolean hasMeanIntensity() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).hasMeanIntensity()) { return true; } } return false; } /** * Checks for intensity. At least one result must have a positive intensity. * * @return true, if successful */ public boolean hasIntensity() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).getIntensity() > 0) { return true; } } return false; } /** * Checks for deviations. All results must have deviations. * * @return true, if successful */ public boolean hasDeviations() { for (int i = 0, size = size(); i < size; i++) { if (!getf(i).hasParameterDeviations()) { return false; } } return !isEmpty(); } /** * Checks for end frame. At least one result must have an end frame. * * @return true, if successful */ public boolean hasEndFrame() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).getFrame() != getf(i).getEndFrame()) { return true; } } return false; } /** * Checks for id. At least one result must have a non-zero ID. * * @return true, if successful */ public boolean hasId() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).getId() != 0) { return true; } } return false; } /** * Checks for category. At least one result must have a non-zero category. * * @return true, if successful */ public boolean hasCategory() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).getCategory() != 0) { return true; } } return false; } /** * Checks for id. At least two results must have different non-zero Ids. If the number of results * is 1 then the id must not be zero. * * @return true, if successful */ public boolean hasMultipleId() { if (isEmpty()) { return false; } if (size() == 1) { return getf(0).getId() != 0; } for (int i = 0, size = size(); i < size; i++) { final int id = getf(i).getId(); if (id != 0) { while (++i < size) { final int id2 = getf(i).getId(); if (id2 != 0 && id2 != id) { return true; } } break; } } return false; } /** * Checks for precision. All results must have a stored precision value. * * @return true, if successful */ public boolean hasPrecision() { for (int i = 0, size = size(); i < size; i++) { if (!getf(i).hasPrecision()) { return false; } } return true; } /** * Checks for 3D results. At least 1 result must have a non-zero z-coordinate. * * @return true, if successful */ public boolean is3D() { for (int i = 0, size = size(); i < size; i++) { if (getf(i).getZPosition() != 0) { return true; } } return false; } /** * Gets the first result. * * @return the first result * @throws IllegalStateException If the size is zero */ public PeakResult getFirst() { checkNotEmpty(); return getfX(0); } private void checkNotEmpty() { if (isEmpty()) { throw new IllegalStateException("Empty"); } } /** * Gets the last result. * * @return the last result * @throws IllegalStateException If the size is zero */ public PeakResult getLast() { checkNotEmpty(); return getfX(size() - 1); } /** * Gets the first frame. * *

This may be different from {@link #getMinFrame()} if the results are not sorted by frame. * * @return the first frame * @throws IllegalStateException If the size is zero */ public int getFirstFrame() { checkNotEmpty(); return getf(0).getFrame(); } /** * Gets the last frame. * *

This may be different from {@link #getMaxFrame()} if the results are not sorted by frame. * * @return the last frame * @throws IllegalStateException If the size is zero */ public int getLastFrame() { checkNotEmpty(); return getf(size() - 1).getEndFrame(); } /** * Gets the minimum frame. * * @return the min frame * @throws IllegalStateException If the size is zero */ public int getMinFrame() { checkNotEmpty(); int min = getf(0).getFrame(); for (int i = 1, size = size(); i < size; i++) { if (min > getf(i).getFrame()) { min = getf(i).getFrame(); } } return min; } /** * Gets the maximum frame. * * @return the max frame * @throws IllegalStateException If the size is zero */ public int getMaxFrame() { checkNotEmpty(); int max = getf(0).getEndFrame(); for (int i = 1, size = size(); i < size; i++) { if (max < getf(i).getEndFrame()) { max = getf(i).getEndFrame(); } } return max; } /** * Checks for null results in the store. * * @return true, if null PeakResult object(s) exist */ public boolean hasNullResults() { for (int i = 0; i < size(); i++) { if (getf(i) == null) { return true; } } return false; } /** * Checks if is distance in preferred units. * * @return true, if is distance in preferred units */ public boolean isDistanceInPreferredUnits() { return getDistanceUnit() == PREFERRED_DISTANCE_UNIT; } /** * Checks if is intensity in preferred units. * * @return true, if is intensity in preferred units */ public boolean isIntensityInPreferredUnits() { return (getIntensityUnit() == PREFERRED_INTENSITY_UNIT); } /** * Checks if is angle in preferred units. * * @return true, if is angle in preferred units */ public boolean isAngleInPreferredUnits() { return getAngleUnit() == PREFERRED_ANGLE_UNIT; } /** * Convert to preferred units. * * @return true, if the data is now stored in the preferred units. */ public boolean convertToPreferredUnits() { return convertToUnits(PREFERRED_DISTANCE_UNIT, PREFERRED_INTENSITY_UNIT, PREFERRED_ANGLE_UNIT); } /** * Convert to the specified units. If the units are null they will remain unchanged. * * @param distanceUnit the distance unit * @param intensityUnit the intensity unit * @param angleUnit the angle unit * @return true, if the data is now stored in the preferred units. */ public boolean convertToUnits(DistanceUnit distanceUnit, IntensityUnit intensityUnit, AngleUnit angleUnit) { if (!hasCalibration()) { return false; } final PeakResultConversionHelper helper = new PeakResultConversionHelper(getCalibration(), getPsf()); helper.setIntensityUnit(intensityUnit); helper.setDistanceUnit(distanceUnit); if (PsfHelper.hasAngleParameters(getPsf())) { helper.setAngleUnit(angleUnit); } final Converter[] converters = helper.getConverters(); if (!helper.isCalibrationChanged()) { // Check if already in the specified units return helper.isValidConversion(); } // Update the calibration setCalibration(helper.getCalibration()); // We must convert the noise and mean intensity final Converter intensityConverter = converters[PeakResult.INTENSITY]; for (int i = 0, size = size(); i < size; i++) { final PeakResult p = getfX(i); p.setNoise(intensityConverter.convert(p.getNoise())); p.setMeanIntensity(intensityConverter.convert(p.getMeanIntensity())); if (p.hasParameterDeviations()) { for (int j = 0; j < converters.length; j++) { p.setParameter(j, converters[j].convert(p.getParameter(j))); p.setParameterDeviation(j, converters[j].convert(p.getParameterDeviation(j))); } } else { for (int j = 0; j < converters.length; j++) { p.setParameter(j, converters[j].convert(p.getParameter(j))); } } } return true; } ///////////////////////////////////////////////////////////////// // START OF PROCEDURE METHODS // Note the converters are always created (and not cached) to // support thread safety, i.e. accessing the results in different // units across threads. ///////////////////////////////////////////////////////////////// /** * For the first result execute the procedure. * * @param procedure the procedure */ public void forFirst(PeakResultProcedure procedure) { if (isEmpty()) { return; } procedure.execute(getfX(0)); } /** * For the first result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forFirstNative(BixyzResultProcedure procedure) { if (isEmpty()) { return; } final PeakResult r = getf(0); procedure.executeBixyz(r.getBackground(), r.getIntensity(), r.getXPosition(), r.getYPosition(), r.getZPosition()); } /** * For the first result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forFirstNative(BResultProcedure procedure) { if (isEmpty()) { return; } final PeakResult r = getf(0); procedure.executeB(r.getBackground()); } /** * For the first result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forFirstNative(IResultProcedure procedure) { if (isEmpty()) { return; } final PeakResult r = getf(0); procedure.executeI(r.getIntensity()); } /** * For the first result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forFirstNative(XyzResultProcedure procedure) { if (isEmpty()) { return; } final PeakResult r = getf(0); procedure.executeXyz(r.getXPosition(), r.getYPosition(), r.getZPosition()); } /** * For each result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forEachNative(BixyzResultProcedure procedure) { for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeBixyz(r.getBackground(), r.getIntensity(), r.getXPosition(), r.getYPosition(), r.getZPosition()); } } /** * For each result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forEachNative(BResultProcedure procedure) { for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeB(r.getBackground()); } } /** * For each result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forEachNative(IResultProcedure procedure) { for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeI(r.getIntensity()); } } /** * For each result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forEachNative(XyzResultProcedure procedure) { for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeXyz(r.getXPosition(), r.getYPosition(), r.getZPosition()); } } /** * For each result execute the procedure. * *

Warning: Results with be in their native units since no unit conversion is performed. * * @param procedure the procedure */ public void forEach(PeakResultProcedure procedure) { for (int i = 0, size = size(); i < size; i++) { procedure.execute(getfX(i)); } } /** * For each result execute the fast-exit procedure. * * @param procedure the procedure * @return true, if a fast exit occurred */ public boolean forEach(PeakResultProcedureX procedure) { for (int i = 0, size = size(); i < size; i++) { if (procedure.execute(getfX(i))) { return true; } } return false; } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, BResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); for (int i = 0, size = size(); i < size; i++) { procedure.executeB(ic.convert(getf(i).getBackground())); } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, BirResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeBir( ic.convert(r.getBackground()), ic.convert(r.getIntensity()), r); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, DistanceUnit distanceUnit, BixyResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeBixy( ic.convert(r.getBackground()), ic.convert(r.getIntensity()), dc.convert(r.getXPosition()), dc.convert(r.getYPosition())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, DistanceUnit distanceUnit, BixyzResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeBixyz( ic.convert(r.getBackground()), ic.convert(r.getIntensity()), dc.convert(r.getXPosition()), dc.convert(r.getYPosition()), dc.convert(r.getZPosition())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This procedure is exclusive to data fit with a Gaussian2D PSF as it computes the height of * the Gaussian from the integral (Intensity) and the widths. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, HResultProcedure procedure) { checkCalibration(); final int[] indices = PsfHelper.getGaussian2DWxWyIndices(getPsf()); final int isx = indices[0]; final int isy = indices[1]; final double twoPi = 2 * Math.PI; final TypeConverter ic = getCalibrationReader().getIntensityConverter(intensityUnit); final TypeConverter dc = getCalibrationReader().getDistanceConverter(DistanceUnit.PIXEL); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); // Convert the widths to pixels final float sx = dc.convert(r.getParameter(isx)); final float sy = dc.convert(r.getParameter(isy)); //@formatter:off procedure.executeH( (float)(ic.convert((double)r.getIntensity()) / (twoPi * sx * sy))); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, IResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeI( ic.convert(r.getIntensity())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, DistanceUnit distanceUnit, IxyResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeIxy( ic.convert(r.getIntensity()), dc.convert(r.getXPosition()), dc.convert(r.getYPosition())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, DistanceUnit distanceUnit, IxyrResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getfX(i); //@formatter:off procedure.executeIxyr( ic.convert(r.getIntensity()), dc.convert(r.getXPosition()), dc.convert(r.getYPosition()), r); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, DistanceUnit distanceUnit, IxyzResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeIxyz( ic.convert(r.getIntensity()), dc.convert(r.getXPosition()), dc.convert(r.getYPosition()), dc.convert(r.getZPosition())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(IntensityUnit intensityUnit, DistanceUnit distanceUnit, IxyzrResultProcedure procedure) { final TypeConverter ic = getIntensityConverter(intensityUnit); final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getfX(i); //@formatter:off procedure.executeIxyzr( ic.convert(r.getIntensity()), dc.convert(r.getXPosition()), dc.convert(r.getYPosition()), dc.convert(r.getZPosition()), r); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(TResultProcedure procedure) { checkCalibration(); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeT( r.getFrame()); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, TxyResultProcedure procedure) { final TypeConverter dc = getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeTxy( r.getFrame(), dc.convert(r.getXPosition()), dc.convert(r.getYPosition())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, WResultProcedure procedure) { checkCalibration(); // Note that in the future we may support more than just Gaussian2D PSF // so this may have to change final int[] indices = PsfHelper.getGaussian2DWxWyIndices(getPsf()); final int isx = indices[0]; final int isy = indices[1]; final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); if (isx == isy) { for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeW(dc.convert(r.getParameter(isx))); } } else { for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); // Convert the separate widths into a single width final double s = Gaussian2DPeakResultHelper.getStandardDeviation(r.getParameter(isx), r.getParameter(isy)); procedure.executeW((float) dc.convert(s)); } } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, WxWyResultProcedure procedure) { checkCalibration(); // Note that in the future we may support more than just Gaussian2D PSF // so this may have to change final int[] indices = PsfHelper.getGaussian2DWxWyIndices(getPsf()); final int isx = indices[0]; final int isy = indices[1]; final TypeConverter dc = getCalibrationReader().getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeWxWy( dc.convert(r.getParameter(isx)), dc.convert(r.getParameter(isy))); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, XyResultProcedure procedure) { final TypeConverter dc = getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeXy( dc.convert(r.getXPosition()), dc.convert(r.getYPosition())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * *

Warning: The peak result with be in native units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, XyrResultProcedure procedure) { final TypeConverter dc = getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getfX(i); //@formatter:off procedure.executeXyr( dc.convert(r.getXPosition()), dc.convert(r.getYPosition()), r); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, XyzResultProcedure procedure) { final TypeConverter dc = getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); //@formatter:off procedure.executeXyz( dc.convert(r.getXPosition()), dc.convert(r.getYPosition()), dc.convert(r.getZPosition())); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, XyzrResultProcedure procedure) { final TypeConverter dc = getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getfX(i); //@formatter:off procedure.executeXyzr( dc.convert(r.getXPosition()), dc.convert(r.getYPosition()), dc.convert(r.getZPosition()), r); //@formatter:on } } /** * For each result execute the procedure using the specified units. * *

This will fail if the calibration is missing information to convert the units. * * @param distanceUnit the distance unit * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(DistanceUnit distanceUnit, ZResultProcedure procedure) { final TypeConverter dc = getDistanceConverter(distanceUnit); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeZ(dc.convert(r.getZPosition())); } } /** * For each result execute the procedure. * *

Note the precision may not be stored in the results. The default precision for a result is * NaN. * * @param procedure the procedure */ public void forEach(StoredPrecisionProcedure procedure) { for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeStoredPrecision(r.getPrecision()); } } /** * For each result execute the procedure. * *

This will fail if the calibration is missing information to convert the units. * * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(LsePrecisionProcedure procedure) { checkCalibration(); final Gaussian2DPeakResultCalculator calculator = Gaussian2DPeakResultHelper.create(getPsf(), getCalibration(), Gaussian2DPeakResultHelper.LSE_PRECISION); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeLsePrecision(calculator.getLsePrecision(r.getParameters(), r.getNoise())); } } /** * For each result execute the procedure. * *

This will fail if the calibration is missing information to convert the units. * * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(LsePrecisionBProcedure procedure) { checkCalibration(); final Gaussian2DPeakResultCalculator calculator = Gaussian2DPeakResultHelper.create(getPsf(), getCalibration(), Gaussian2DPeakResultHelper.LSE_PRECISION_X); for (int i = 0, size = size(); i < size; i++) { procedure.executeLsePrecisionB(calculator.getLsePrecision(getf(i).getParameters())); } } /** * For each result execute the procedure. * *

This will fail if the calibration is missing information to convert the units. * * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(MlePrecisionProcedure procedure) { checkCalibration(); final Gaussian2DPeakResultCalculator calculator = Gaussian2DPeakResultHelper.create(getPsf(), getCalibration(), Gaussian2DPeakResultHelper.MLE_PRECISION); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); procedure.executeMlePrecision(calculator.getMlePrecision(r.getParameters(), r.getNoise())); } } /** * For each result execute the procedure. * *

This will fail if the calibration is missing information to convert the units. * * @param procedure the procedure * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void forEach(MlePrecisionBProcedure procedure) { checkCalibration(); final Gaussian2DPeakResultCalculator calculator = Gaussian2DPeakResultHelper.create(getPsf(), getCalibration(), Gaussian2DPeakResultHelper.MLE_PRECISION_X); for (int i = 0, size = size(); i < size; i++) { procedure.executeMlePrecisionB(calculator.getMlePrecision(getf(i).getParameters())); } } /** * Apply a pixel translation to the results. The original coordinates are updated using a raw * pixel shift. The current XY coordinates are updated by converting the pixel shift to the * current distance units. If there are current bounds then the origin will be updated with a raw * pixel shift. * * @param x the x pixel shift * @param y the y pixel shift * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void translate(int x, int y) { if (x == 0 && y == 0) { return; } checkCalibration(); final Rectangle bounds = getBounds(); if (bounds != null) { bounds.x += x; bounds.y += y; setBounds(bounds); } // Convert the pixel shift to the units of the results final TypeConverter dc = getCalibrationReader().getDistanceConverter(getDistanceUnit()); final float xx = dc.convert(x); final float yy = dc.convert(y); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getf(i); r.setOrigX(r.getOrigX() + x); r.setOrigY(r.getOrigY() + y); r.setXPosition(r.getXPosition() + xx); r.setYPosition(r.getYPosition() + yy); } } ///////////////////////////////////////////////////////////////// // END OF PROCEDURE METHODS ///////////////////////////////////////////////////////////////// /** * Gets the distance unit. * * @return the distance unit */ public DistanceUnit getDistanceUnit() { if (hasCalibration() && getCalibrationReader().hasDistanceUnit()) { return getCalibrationReader().getDistanceUnit(); } return null; } /** * Gets the intensity unit. * * @return the intensity unit */ public IntensityUnit getIntensityUnit() { if (hasCalibration() && getCalibrationReader().hasIntensityUnit()) { return getCalibrationReader().getIntensityUnit(); } return null; } /** * Gets the angle unit. * * @return the angle unit */ public AngleUnit getAngleUnit() { if (hasCalibration() && getCalibrationReader().hasAngleUnit()) { return getCalibrationReader().getAngleUnit(); } return null; } /** * Gets the distance converter. * * @param distanceUnit the distance unit * @return the distance converter * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public TypeConverter getDistanceConverter(DistanceUnit distanceUnit) { checkCalibration(); return getCalibrationReader().getDistanceConverter(distanceUnit); } /** * Gets the intensity converter. * * @param intensityUnit the intensity unit * @return the intensity converter * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public TypeConverter getIntensityConverter(IntensityUnit intensityUnit) { checkCalibration(); return getCalibrationReader().getIntensityConverter(intensityUnit); } /** * Gets the time converter. * * @param timeUnit the time unit * @return the time converter * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public TypeConverter getTimeConverter(TimeUnit timeUnit) { checkCalibration(); return getCalibrationReader().getTimeConverter(timeUnit); } /** * Check calibration exits. * * @throws ConfigurationException if the configuration is invalid */ private void checkCalibration() { if (!hasCalibration()) { throw new ConfigurationException("No calibration"); } } /** * Fix zero background to the given background. * *

This will fail if the calibration is missing information to convert the units. * * @param intensityUnit the intensity unit * @param newBackground the new background * @throws ConversionException if the conversion is not possible * @throws ConfigurationException if the configuration is invalid */ public void setZeroBackground(IntensityUnit intensityUnit, float newBackground) { final TypeConverter ic = getIntensityConverter(intensityUnit); newBackground = ic.convertBack(newBackground); for (int i = 0, size = size(); i < size; i++) { final PeakResult r = getfX(i); if (r.getBackground() == 0) { r.setBackground(newBackground); } } } /** * Creates the frame counter. It will be initialised with the value of {@link #getFirstFrame()}. * This ensures that the next frame after the first frame will be recognised as a new frame. * * @return the frame counter */ public FrameCounter newFrameCounter() { return new FrameCounter((isEmpty()) ? 0 : getFirstFrame()); } /** * Gets a view of the results. * * @return the view */ public PeakResultView getPeakResultView() { return new DynamicPeakResultView(results); } /** * Gets a snapshot view of the results. The view can cache the results so changes to the results * may not be reflected in the view. Use in a read-only context. * * @return the view */ public PeakResultView getSnapshotPeakResultView() { return new CachedPeakResultView(results); } /** * Get a subset of the results that match the filter. * * @param filter the filter * @return the results */ public PeakResult[] getSubset(Predicate filter) { return results.subset(filter); } /** * Find the index of the given result. More formally, returns the lowest index {@code i} such that * {@code (result==null ? get(i)==null : result.equals(get(i)))}, or -1 if there is no such index. * * @param result the result * @return the index (or -1) */ public int indexOf(PeakResult result) { return results.indexOf(result); } /** * Create a deep copy of the results and assign Ids that are currently zero a negative Id. * *

This method is to be used on clustering results where an Id of zero indicates no cluster and * an Id above zero is for an assigned cluster. * * @return the new results */ public MemoryPeakResults copyAndAssignZeroIds() { final int size = size(); final MemoryPeakResults copy = new MemoryPeakResults(size); copy.copyState(this); // Copy the result. Assign any zero Id result a negative Id. int nextId = 0; final PeakResult[] results = new PeakResult[size]; for (int i = 0; i < size; i++) { final PeakResult result = getfX(i); final int id = result.getId() == 0 ? --nextId : result.getId(); final ExtendedPeakResult newResult = new ExtendedPeakResult(result.getFrame(), result.getOrigX(), result.getOrigY(), result.getOrigValue(), result.getError(), result.getNoise(), result.getMeanIntensity(), result.getParameters().clone(), ArrayUtils.clone(result.getParameterDeviations()), result.getEndFrame(), id); results[i] = newResult; } copy.addAll(results); return copy; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy