package cz.cuni.lf1.lge.ThunderSTORM; import cz.cuni.lf1.lge.ThunderSTORM.UI.BiplaneCalibrationDialog; import cz.cuni.lf1.lge.ThunderSTORM.UI.GUI; import cz.cuni.lf1.lge.ThunderSTORM.calibration.*; import cz.cuni.lf1.lge.ThunderSTORM.detectors.ui.IDetectorUI; import cz.cuni.lf1.lge.ThunderSTORM.estimators.ui.AstigmaticBiplaneCalibrationEstimatorUI; import cz.cuni.lf1.lge.ThunderSTORM.estimators.ui.BiplaneCalibrationEstimatorUI; import cz.cuni.lf1.lge.ThunderSTORM.estimators.ui.ICalibrationEstimatorUI; import cz.cuni.lf1.lge.ThunderSTORM.estimators.ui.IEstimatorUI; import cz.cuni.lf1.lge.ThunderSTORM.filters.ui.IFilterUI; import cz.cuni.lf1.lge.ThunderSTORM.thresholding.Thresholder; import cz.cuni.lf1.lge.ThunderSTORM.util.MacroUI.Utils; import cz.cuni.lf1.lge.ThunderSTORM.util.UI; import ij.IJ; import ij.ImagePlus; import ij.gui.Roi; import ij.plugin.PlugIn; import javax.swing.*; import java.io.IOException; import java.util.Arrays; import java.util.List; public class BiPlaneCalibrationPlugin implements PlugIn { DefocusFunction defocusModel; CalibrationConfig calibrationConfig; IFilterUI selectedFilterUI; IDetectorUI selectedDetectorUI; ICalibrationEstimatorUI calibrationEstimatorUI; String savePath; double stageStep; double zRangeLimit;//in nm ImagePlus imp1, imp2; Roi roi1, roi2; private boolean isStack(ImagePlus imp) { if(imp == null) { IJ.error("No image open."); return false; } if(imp.getImageStackSize() < 2) { IJ.error("Requires a stack."); return false; } return true; } @Override public void run(String arg) { GUI.setLookAndFeel(); // if (Utils.getOpenImageTitles(true).length < 3) { // 3 = 2 images + 1 empty string IJ.error("Two images must be opened for biplane calibration to work!"); return; } // try { //load modules List<IFilterUI> filters = ModuleLoader.getUIModules(IFilterUI.class); List<IDetectorUI> detectors = ModuleLoader.getUIModules(IDetectorUI.class); List<IEstimatorUI> estimators = Arrays.asList(new IEstimatorUI[]{new BiplaneCalibrationEstimatorUI(), new AstigmaticBiplaneCalibrationEstimatorUI()}); // only certain estimators can be used List<DefocusFunction> defocusFunctions = ModuleLoader.getUIModules(DefocusFunction.class); Thresholder.loadFilters(filters); // get user options try { GUI.setLookAndFeel(); } catch(Exception e) { IJ.handleException(e); } BiplaneCalibrationDialog dialog = new BiplaneCalibrationDialog(filters, detectors, estimators, defocusFunctions); if(dialog.showAndGetResult() != JOptionPane.OK_OPTION) { return; } calibrationConfig = dialog.getCalibrationConfig(); selectedFilterUI = dialog.getActiveFilterUI(); selectedDetectorUI = dialog.getActiveDetectorUI(); calibrationEstimatorUI = (ICalibrationEstimatorUI) dialog.getActiveEstimatorUI(); savePath = dialog.getSavePath(); stageStep = dialog.getStageStep(); zRangeLimit = dialog.getZRangeLimit(); defocusModel = dialog.getActiveDefocusFunction(); if (!isStack(imp1 = dialog.getFirstPlaneStack())) return; if (!isStack(imp2 = dialog.getSecondPlaneStack())) return; roi1 = imp1.getRoi() != null ? imp1.getRoi() : new Roi(0, 0, imp1.getWidth(), imp1.getHeight()); roi2 = imp2.getRoi() != null ? imp2.getRoi() : new Roi(0, 0, imp2.getWidth(), imp2.getHeight()); if (roi1.getFloatWidth() != roi2.getFloatWidth() || roi1.getFloatHeight() != roi2.getFloatHeight()) { IJ.error("Both used images (or ROIs) must be of the same size!"); return; } // perform the calibration final ICalibrationProcess process = CalibrationProcessFactory.create( calibrationConfig, selectedFilterUI, selectedDetectorUI, calibrationEstimatorUI, defocusModel, stageStep, zRangeLimit, imp1, imp2, roi1, roi2); try { process.runCalibration(); } catch(TransformEstimationFailedException ex) { IJ.showMessage("Error", ex.getMessage()); IJ.showStatus("Calibration failed."); IJ.showProgress(1.0); return; } catch(NoMoleculesFittedException ex) { // if no beads were successfully fitted, draw localizations anyway process.drawOverlay(); IJ.showMessage("Error", ex.getMessage()); IJ.showStatus("Calibration failed."); IJ.showProgress(1.0); return; } process.drawOverlay(); process.drawSigmaPlots(); try { process.getCalibration(defocusModel).saveToFile(savePath); } catch(IOException ex) { UI.showAnotherLocationDialog(ex, process.getCalibration(defocusModel)); } } catch(Exception ex) { IJ.handleException(ex); } } }