use of uk.ac.sussex.gdsc.smlm.ij.IJImageSource in project GDSC-SMLM by aherbert.
the class CameraModelManager method runFilterImage.
private void runFilterImage() {
// Select an image
GenericDialog gd = new GenericDialog(TITLE);
final String[] list = ImageJUtils.getImageList(ImageJUtils.GREY_SCALE);
gd.addChoice("Image", list, pluginSettings.getImage());
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
final String image = gd.getNextChoice();
pluginSettings.setImage(image);
final ImagePlus imp = WindowManager.getImage(image);
if (imp == null) {
IJ.error(TITLE, "Failed to find image: " + image);
return;
}
// Select the model
gd = new GenericDialog(TITLE);
final String[] models = listCameraModels(false);
gd.addChoice("Model", models, pluginSettings.getSelected());
gd.addHelp(HelpUrls.getUrl("camera-model-manager-filter"));
gd.showDialog();
if (gd.wasCanceled()) {
return;
}
final String name = gd.getNextChoice();
pluginSettings.setSelected(name);
CameraModel cameraModel = load(name);
if (cameraModel == null) {
IJ.error(TITLE, "Failed to find camera data for model: " + name);
return;
}
// Crop the model if appropriate
try {
Rectangle bounds;
try {
bounds = IJImageSource.getBounds(imp);
} catch (final IllegalArgumentException ex) {
bounds = new Rectangle(pluginSettings.getOriginX(), pluginSettings.getOriginY(), imp.getWidth(), imp.getHeight());
}
cameraModel = PeakFit.cropCameraModel(cameraModel, bounds, null, false);
} catch (final IllegalArgumentException ex) {
IJ.error(TITLE, ex.getMessage());
return;
}
final Rectangle bounds = cameraModel.getBounds();
pluginSettings.setOriginX(bounds.x);
pluginSettings.setOriginY(bounds.y);
// Reset origin for fast filtering
cameraModel = cameraModel.copy();
cameraModel.setOrigin(0, 0);
// Filter all the frames
final ImageSource source = new IJImageSource(imp);
if (!source.open()) {
IJ.error(TITLE, "Cannot open image: " + image);
}
final ImageStack stack = new ImageStack(imp.getWidth(), imp.getHeight());
for (float[] data = source.next(); data != null; data = source.next()) {
cameraModel.removeBiasAndGain(data);
stack.addSlice(null, data);
}
final ImagePlus imp2 = new ImagePlus(imp.getTitle() + " Filtered", stack);
imp2.copyScale(imp);
imp2.show();
}
use of uk.ac.sussex.gdsc.smlm.ij.IJImageSource in project GDSC-SMLM by aherbert.
the class AstigmatismModelManager method fitRegion.
private boolean fitRegion() {
final int radius = config.getFittingWidth();
if (pluginSettings.getLogFitProgress()) {
fitConfig.setLog(ImageJPluginLoggerHelper.getLogger(getClass()));
}
// Create a fit engine
results = new MemoryPeakResults();
results.setCalibration(fitConfig.getCalibration());
results.setPsf(fitConfig.getPsf());
results.setSortAfterEnd(true);
results.begin();
final int threadCount = Prefs.getThreads();
final FitEngine engine = FitEngine.create(config, SynchronizedPeakResults.create(results, threadCount), threadCount, FitQueue.BLOCKING);
final IJImageSource source = new IJImageSource(imp);
source.open();
final Rectangle r1 = new Rectangle(cx - radius, cy - radius, 2 * radius + 1, 2 * radius + 1);
final Rectangle regionBounds = r1.intersection(new Rectangle(source.getWidth(), source.getHeight()));
// Fit only a spot in the centre
final int x = cx - regionBounds.x;
final int y = cy - regionBounds.y;
final int[] maxIndices = new int[] { y * regionBounds.width + x };
final Ticker ticker = ImageJUtils.createTicker(source.getFrames(), threadCount);
IJ.showStatus("Fitting ...");
boolean shutdown = false;
while (!shutdown) {
// Extract the region from each frame
final float[] region = source.next(regionBounds);
if (region == null) {
break;
}
final FitParameters params = new FitParameters();
params.maxIndices = maxIndices.clone();
final int slice = (int) ticker.getCurrent();
final ParameterisedFitJob job = new ParameterisedFitJob(slice, params, slice, region, regionBounds);
engine.run(job);
ticker.tick();
shutdown = IJ.escapePressed();
}
if (shutdown) {
IJ.showStatus("Cancelled");
}
engine.end(shutdown);
results.end();
IJ.showProgress(1);
if (!shutdown) {
ImageJUtils.log("Fit %d/%s", results.size(), TextUtils.pleural(source.getFrames(), "spot"));
}
return !shutdown;
}
use of uk.ac.sussex.gdsc.smlm.ij.IJImageSource in project GDSC-SMLM by aherbert.
the class CreateData method drawImage.
// StoredDataStatistics rawPhotons = new StoredDataStatistics();
// StoredDataStatistics drawPhotons = new StoredDataStatistics();
// private synchronized void addRaw(double d)
// {
// //rawPhotons.add(d);
// }
//
// private synchronized void addDraw(double d)
// {
// //drawPhotons.add(d);
// }
/**
* Create an image from the localisations using the configured PSF width. Draws a new stack image.
*
* <p>Note that the localisations are filtered using the signal. The input list of localisations
* will be updated.
*
* @param localisationSets the localisation sets
* @return The localisations
*/
private List<LocalisationModel> drawImage(final List<LocalisationModelSet> localisationSets) {
if (localisationSets.isEmpty()) {
return null;
}
// Create a new list for all localisation that are drawn (i.e. pass the signal filters)
List<LocalisationModelSet> newLocalisations = Collections.synchronizedList(new ArrayList<LocalisationModelSet>(localisationSets.size()));
photonsRemoved = new AtomicInteger();
removedT1 = new AtomicInteger();
removedTn = new AtomicInteger();
photonStats = new SummaryStatistics();
// Add drawn spots to memory
results = new MemoryPeakResults();
final CalibrationWriter c = new CalibrationWriter();
c.setDistanceUnit(DistanceUnit.PIXEL);
c.setIntensityUnit(IntensityUnit.PHOTON);
c.setNmPerPixel(settings.getPixelPitch());
c.setExposureTime(settings.getExposureTime());
c.setCameraType(settings.getCameraType());
if (settings.getCameraType() == CameraType.SCMOS) {
c.setCameraModelName(settings.getCameraModelName());
} else {
final CreateDataSettingsHelper helper = new CreateDataSettingsHelper(settings);
c.setCountPerPhoton(helper.getTotalGainSafe());
c.setBias(settings.getBias());
c.setReadNoise(helper.getReadNoiseInCounts());
c.setQuantumEfficiency(helper.getQuantumEfficiency());
}
results.setCalibration(c.getCalibration());
results.setSortAfterEnd(true);
results.begin();
maxT = localisationSets.get(localisationSets.size() - 1).getTime();
// Display image
final ImageStack stack = new ImageStack(settings.getSize(), settings.getSize(), maxT);
final double psfSd = getPsfSd();
if (psfSd <= 0) {
return null;
}
final PsfModel psfModel = createPsfModel(localisationSets);
if (psfModel == null) {
return null;
}
// Create the camera noise model
createPerPixelCameraModelData(cameraModel);
createBackgroundPixels();
final int threadCount = Prefs.getThreads();
IJ.showStatus("Drawing image ...");
// Multi-thread for speed
final PeakResults syncResults = SynchronizedPeakResults.create(results, threadCount);
final ExecutorService threadPool = Executors.newFixedThreadPool(threadCount);
final List<Future<?>> futures = new LinkedList<>();
// Count all the frames to process
final Ticker ticker = ImageJUtils.createTicker(maxT, threadCount);
// Collect statistics on the number of photons actually simulated
// Process all frames
int index = 0;
int lastT = -1;
for (final LocalisationModelSet l : localisationSets) {
if (ImageJUtils.isInterrupted()) {
break;
}
if (l.getTime() != lastT) {
lastT = l.getTime();
futures.add(threadPool.submit(new ImageGenerator(localisationSets, newLocalisations, index, lastT, psfModel.copy(), syncResults, stack, poissonNoise, createRandomGenerator(), ticker)));
}
index++;
}
// Finish processing data
ConcurrencyUtils.waitForCompletionUnchecked(futures);
futures.clear();
if (ImageJUtils.isInterrupted()) {
IJ.showProgress(1);
return null;
}
// Do all the frames that had no localisations
float[] limits = null;
for (int t = 1; t <= maxT; t++) {
if (ImageJUtils.isInterrupted()) {
break;
}
final Object pixels = stack.getPixels(t);
if (pixels == null) {
futures.add(threadPool.submit(new ImageGenerator(localisationSets, newLocalisations, maxT, t, null, syncResults, stack, poissonNoise, createRandomGenerator(), ticker)));
} else if (limits == null) {
limits = MathUtils.limits((float[]) pixels);
}
}
// Finish
ConcurrencyUtils.waitForCompletionUnchecked(futures);
futures.clear();
threadPool.shutdown();
IJ.showProgress(1);
if (ImageJUtils.isInterrupted() || limits == null) {
return null;
}
results.end();
if (photonsRemoved.get() > 0) {
ImageJUtils.log("Removed %d localisations with less than %.1f rendered photons", photonsRemoved.get(), settings.getMinPhotons());
}
if (removedT1.get() > 0) {
ImageJUtils.log("Removed %d localisations with no neighbours @ SNR %.2f", removedT1.get(), settings.getMinSnrT1());
}
if (removedTn.get() > 0) {
ImageJUtils.log("Removed %d localisations with valid neighbours @ SNR %.2f", removedTn.get(), settings.getMinSnrTN());
}
if (photonStats.getN() > 0) {
ImageJUtils.log("Average photons rendered = %s +/- %s", MathUtils.rounded(photonStats.getMean()), MathUtils.rounded(photonStats.getStandardDeviation()));
}
// System.out.printf("rawPhotons = %f\n", rawPhotons.getMean());
// System.out.printf("drawPhotons = %f\n", drawPhotons.getMean());
// new HistogramPlotBuilder("draw photons", drawPhotons, "photons", true, 0, 1000);
// Update with all those localisation that have been drawn
localisationSets.clear();
localisationSets.addAll(newLocalisations);
newLocalisations = null;
IJ.showStatus("Displaying image ...");
ImageStack newStack = stack;
if (!settings.getRawImage()) {
// Get the global limits and ensure all values can be represented
final Object[] imageArray = stack.getImageArray();
limits = MathUtils.limits((float[]) imageArray[0]);
for (int j = 1; j < imageArray.length; j++) {
limits = MathUtils.limits(limits, (float[]) imageArray[j]);
}
// float limits0 = limits[0];
// Leave bias in place
final float limits0 = 0;
// Check if the image will fit in a 16-bit range
if ((limits[1] - limits0) < 65535) {
// Convert to 16-bit
newStack = new ImageStack(stack.getWidth(), stack.getHeight(), stack.getSize());
// Account for rounding
final float min = (float) (limits0 - 0.5);
for (int j = 0; j < imageArray.length; j++) {
final float[] image = (float[]) imageArray[j];
final short[] pixels = new short[image.length];
for (int k = 0; k < pixels.length; k++) {
pixels[k] = (short) (image[k] - min);
}
newStack.setPixels(pixels, j + 1);
// Free memory
imageArray[j] = null;
// Attempt to stay within memory (check vs 32MB)
if (MemoryUtils.getFreeMemory() < 33554432L) {
MemoryUtils.runGarbageCollectorOnce();
}
}
for (int k = 2; k-- > 0; ) {
limits[k] = (float) Math.floor(limits[k] - min);
}
} else {
// Keep as 32-bit but round to whole numbers
for (int j = 0; j < imageArray.length; j++) {
final float[] pixels = (float[]) imageArray[j];
for (int k = 0; k < pixels.length; k++) {
pixels[k] = Math.round(pixels[k]);
}
}
for (int k = 2; k-- > 0; ) {
limits[k] = Math.round(limits[k]);
}
}
}
// Show image
final ImagePlus imp = ImageJUtils.display(CREATE_DATA_IMAGE_TITLE, newStack);
final ij.measure.Calibration cal = new ij.measure.Calibration();
String unit = "nm";
double unitPerPixel = settings.getPixelPitch();
if (unitPerPixel > 100) {
unit = "um";
unitPerPixel /= 1000.0;
}
cal.setUnit(unit);
cal.pixelHeight = cal.pixelWidth = unitPerPixel;
final Rectangle bounds = cameraModel.getBounds();
if (bounds != null) {
cal.xOrigin = -bounds.x;
cal.yOrigin = -bounds.y;
}
imp.setCalibration(cal);
imp.setDimensions(1, 1, newStack.getSize());
imp.setDisplayRange(limits[0], limits[1]);
imp.updateAndDraw();
saveImage(imp);
final IJImageSource imageSource = new IJImageSource(imp);
// Shift simulation image source to correct location
results.setSource(imageSource);
results.setName(CREATE_DATA_IMAGE_TITLE + " (" + TITLE + ")");
// Bounds are relative to the image source
results.setBounds(new Rectangle(settings.getSize(), settings.getSize()));
results.setPsf(createPsf(psfSd));
MemoryPeakResults.addResults(results);
setBenchmarkResults(imp, results);
if (benchmarkMode && benchmarkParameters != null) {
benchmarkParameters.setPhotons(results);
}
final List<LocalisationModel> localisations = toLocalisations(localisationSets);
savePulses(localisations, results);
// Saved the fixed and moving localisations into different datasets
saveFixedAndMoving(results);
saveCompoundMolecules(results);
return localisations;
}
use of uk.ac.sussex.gdsc.smlm.ij.IJImageSource in project GDSC-SMLM by aherbert.
the class ResultsManager method loadInputResults.
/**
* Load the results from the named input option. If the results are not empty then a check can be
* made for calibration, and data using the specified units. If the calibration cannot be obtained
* or the units are incorrect then the null will be returned.
*
* @param inputOption the input option
* @param checkCalibration Set to true to ensure the results have a valid calibration
* @param distanceUnit the required distance unit for the results
* @param intensityUnit the required intensity unit for the results
* @param extraOptions the extra options
* @return the results
*/
public static MemoryPeakResults loadInputResults(String inputOption, boolean checkCalibration, DistanceUnit distanceUnit, IntensityUnit intensityUnit, LoadOption... extraOptions) {
MemoryPeakResults results = null;
PeakResultsReader reader = null;
if (inputOption.equals(INPUT_NONE)) {
// Do nothing
} else if (inputOption.equals(INPUT_FILE)) {
IJ.showStatus("Reading results file ...");
reader = new PeakResultsReader(findFileName(extraOptions));
IJ.showStatus("Reading " + reader.getFormat() + " results file ...");
final ResultOption[] options = reader.getOptions();
if (options.length != 0) {
collectOptions(reader, options);
}
reader.setTracker(SimpleImageJTrackProgress.getInstance());
results = reader.getResults();
reader.getTracker().progress(1.0);
// If the name contains a .tif suffix then create an image source
if (results != null && results.size() > 0 && results.getName() != null && results.getName().contains(".tif") && results.getSource() == null) {
final int index = results.getName().indexOf(".tif");
results.setSource(new IJImageSource(results.getName().substring(0, index)));
}
} else {
results = loadMemoryResults(inputOption);
}
try {
if (results == null) {
return null;
}
if (results.isEmpty()) {
return results;
}
if (checkCalibration && !checkCalibration(results, reader)) {
return null;
}
if (distanceUnit != null && results.getDistanceUnit() != distanceUnit) {
ImageJUtils.log("Incorrect distance unit: " + results.getDistanceUnit());
return null;
}
if (intensityUnit != null && results.getIntensityUnit() != intensityUnit) {
ImageJUtils.log("Incorrect intensity unit: " + results.getDistanceUnit());
return null;
}
} finally {
IJ.showStatus("");
}
return results;
}
use of uk.ac.sussex.gdsc.smlm.ij.IJImageSource in project GDSC-SMLM by aherbert.
the class PsfEstimator method calculateStatistics.
private boolean calculateStatistics(PeakFit fitter, double[] params, double[] paramsDev) {
debug(" Fitting PSF");
swapStatistics();
// Create the fit engine using the PeakFit plugin
final FitConfiguration fitConfig = config.getFitConfiguration();
fitConfig.setInitialPeakStdDev0((float) params[1]);
try {
fitConfig.setInitialPeakStdDev1((float) params[2]);
fitConfig.setInitialAngle((float) Math.toRadians(params[0]));
} catch (IllegalStateException ex) {
// Ignore this as the current PSF is not a 2 axis and theta Gaussian PSF
}
final ImageStack stack = imp.getImageStack();
final Rectangle roi = stack.getProcessor(1).getRoi();
ImageSource source = new IJImageSource(imp);
// Allow interlaced data by wrapping the image source
if (interlacedData) {
source = new InterlacedImageSource(source, dataStart, dataBlock, dataSkip);
}
// Allow frame aggregation by wrapping the image source
if (integrateFrames > 1) {
source = new AggregatedImageSource(source, integrateFrames);
}
fitter.initialiseImage(source, roi, true);
fitter.addPeakResults(this);
fitter.initialiseFitting();
final FitEngine engine = fitter.createFitEngine();
// Use random slices
final int[] slices = new int[stack.getSize()];
for (int i = 0; i < slices.length; i++) {
slices[i] = i + 1;
}
RandomUtils.shuffle(slices, UniformRandomProviders.create());
IJ.showStatus("Fitting ...");
// Use multi-threaded code for speed
int sliceIndex;
for (sliceIndex = 0; sliceIndex < slices.length; sliceIndex++) {
final int slice = slices[sliceIndex];
IJ.showProgress(size(), settings.getNumberOfPeaks());
final ImageProcessor ip = stack.getProcessor(slice);
// stack processor does not set the bounds required by ImageConverter
ip.setRoi(roi);
final FitJob job = new FitJob(slice, ImageJImageConverter.getData(ip), roi);
engine.run(job);
if (sampleSizeReached() || ImageJUtils.isInterrupted()) {
break;
}
}
if (ImageJUtils.isInterrupted()) {
IJ.showProgress(1);
engine.end(true);
return false;
}
// Wait until we have enough results
while (!sampleSizeReached() && !engine.isQueueEmpty()) {
IJ.showProgress(size(), settings.getNumberOfPeaks());
try {
Thread.sleep(50);
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
throw new ConcurrentRuntimeException("Unexpected interruption", ex);
}
}
// End now if we have enough samples
engine.end(sampleSizeReached());
ImageJUtils.finished();
// This count will be an over-estimate given that the provider is ahead of the consumer
// in this multi-threaded system
debug(" Processed %d/%d slices (%d peaks)", sliceIndex, slices.length, size());
setParams(ANGLE, params, paramsDev, sampleNew[ANGLE]);
setParams(X, params, paramsDev, sampleNew[X]);
setParams(Y, params, paramsDev, sampleNew[Y]);
if (settings.getShowHistograms()) {
final HistogramPlotBuilder builder = new HistogramPlotBuilder(TITLE).setNumberOfBins(settings.getHistogramBins());
final WindowOrganiser wo = new WindowOrganiser();
for (int ii = 0; ii < 3; ii++) {
if (sampleNew[ii].getN() == 0) {
continue;
}
final StoredDataStatistics stats = StoredDataStatistics.create(sampleNew[ii].getValues());
builder.setData(stats).setName(NAMES[ii]).setPlotLabel("Mean = " + MathUtils.rounded(stats.getMean()) + ". Median = " + MathUtils.rounded(sampleNew[ii].getPercentile(50))).show(wo);
}
wo.tile();
}
if (size() < 2) {
log("ERROR: Insufficient number of fitted peaks, terminating ...");
return false;
}
return true;
}
Aggregations