package cz.cuni.lf1.lge.ThunderSTORM;
import cz.cuni.lf1.lge.ThunderSTORM.UI.GUI;
import cz.cuni.lf1.lge.ThunderSTORM.UI.Help;
import cz.cuni.lf1.lge.ThunderSTORM.util.GridBagHelper;
import cz.cuni.lf1.lge.ThunderSTORM.util.MacroUI.DialogStub;
import cz.cuni.lf1.lge.ThunderSTORM.util.MacroUI.ParameterKey;
import cz.cuni.lf1.lge.ThunderSTORM.util.MacroUI.ParameterTracker;
import cz.cuni.lf1.lge.ThunderSTORM.util.MacroUI.validators.DoubleValidatorFactory;
import ij.IJ;
import ij.Macro;
import ij.plugin.PlugIn;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashMap;
public class CameraSetupPlugIn implements PlugIn {
public static final String PIXEL_SIZE = "pixelSize";
public static final String PHOTONS_TO_ADU = "photons2ADU";
public static final String QUANTUM_EFFICIENCY = "quantumEfficiency";
public static final String EM_GAIN = "gain";
public static final String READOUT_NOISE = "readoutNoise";
public static final String BASELINE_OFFSET = "offset";
public static final String EM_GAIN_ENABLED = "isEmGain";
public static final ParameterTracker params = new ParameterTracker("thunderstorm.camera");
private static ParameterKey.Double pixelSize = params.createDoubleField("pixelSize", null, 80.0);
private static ParameterKey.Double photons2ADU = params.createDoubleField("photons2ADU", null, 3.6);
private static ParameterKey.Double quantumEfficiency = params.createDoubleField("quantumEfficiency", DoubleValidatorFactory.rangeInclusive(0.0, 1.0), 1.0);
private static ParameterKey.Double gain = params.createDoubleField("gainEM", null, 100, new ParameterTracker.Condition() {
@Override
public boolean isSatisfied() {
return isEmGain.getValue();
}
@Override
public ParameterKey[] dependsOn() {
return new ParameterKey[]{isEmGain};
}
});
private static ParameterKey.Double readoutNoise = params.createDoubleField("readoutNoise", null, 0, new ParameterTracker.Condition() {
@Override
public boolean isSatisfied() {
return !isEmGain.getValue();
}
@Override
public ParameterKey[] dependsOn() {
return new ParameterKey[]{isEmGain};
}
});
private static ParameterKey.Double offset = params.createDoubleField("offset", null, 414);
private static ParameterKey.Boolean isEmGain = params.createBooleanField("isEmGain", null, false);
static{
loadPreferences();
}
public static double getPixelSize() {
return params.getDouble(pixelSize);
}
public static double getPhotons2ADU() {
return params.getDouble(photons2ADU);
}
public static double getQuantumEfficiency() {
return params.getDouble(quantumEfficiency);
}
public static double getGain() {
return params.getDouble(gain);
}
public static double getReadoutNoise() {
return params.getDouble(readoutNoise);
}
public static double getOffset() {
return params.getDouble(offset);
}
public static boolean getIsEmGain() {
return params.getBoolean(isEmGain);
}
public static void setPixelSize(double px) {
params.setDouble(pixelSize, px);
}
public static void setPhotons2ADU(double adc) {
params.setDouble(photons2ADU, adc);
}
public static void setQuantumEfficiency(double qe) {
params.setDouble(quantumEfficiency, qe);
}
public static void setGain(double g) {
params.setDouble(gain, g);
}
public static void setReadoutNoise(double readout) {
params.setDouble(readoutNoise, readout);
}
public static void setOffset(double off) {
params.setDouble(offset, off);
}
public static void setIsEmGain(boolean em) {
params.setBoolean(isEmGain, em);
}
public static HashMap<String, Object> exportSettings() {
HashMap<String, Object> settings = new HashMap<String, Object>();
settings.put(PIXEL_SIZE, getPixelSize());
settings.put(PHOTONS_TO_ADU, getPhotons2ADU());
settings.put(QUANTUM_EFFICIENCY, getQuantumEfficiency());
settings.put(EM_GAIN_ENABLED, getIsEmGain());
settings.put(EM_GAIN, getGain());
settings.put(READOUT_NOISE, getReadoutNoise());
settings.put(BASELINE_OFFSET, getOffset());
return settings;
}
@Override
public void run(String arg) {
String macroOptions = Macro.getOptions();
if(macroOptions != null) {
params.readMacroOptions();
} else {
GUI.setLookAndFeel();
DialogStub dialog2 = new DialogStub(params, IJ.getInstance(), "Camera setup") {
@Override
protected void layoutComponents() {
setLayout(new GridBagLayout());
add(new JLabel("Pixel size [nm]:"), GridBagHelper.leftCol());
JTextField pixelSizeTextField = new JTextField(20);
add(pixelSizeTextField, GridBagHelper.rightCol());
params.registerComponent(pixelSize, pixelSizeTextField);
add(new JLabel("Photoelectrons per A/D count:"), GridBagHelper.leftCol());
JTextField photons2ADUTextField = new JTextField(20);
add(photons2ADUTextField, GridBagHelper.rightCol());
params.registerComponent(photons2ADU, photons2ADUTextField);
add(new JLabel("Quantum efficiency:"), GridBagHelper.leftCol());
JTextField quantumEfficiencyTextField = new JTextField(20);
add(quantumEfficiencyTextField, GridBagHelper.rightCol());
params.registerComponent(quantumEfficiency, quantumEfficiencyTextField);
add(new JLabel("Base level [A/D counts]:"), GridBagHelper.leftCol());
JTextField offsetTextField = new JTextField(20);
add(offsetTextField, GridBagHelper.rightCol());
params.registerComponent(offset, offsetTextField);
final JCheckBox emGainCheckBox = new JCheckBox("EM gain:", !getIsEmGain()); // force the call of the ItemListener to init the dialog properly (enable/disable gain/readout text fields)
emGainCheckBox.setBorder(BorderFactory.createEmptyBorder());
final JTextField emGainTextField = new JTextField(20);
final JTextField readoutNoiseTextField = new JTextField(20);
emGainCheckBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
emGainTextField.setEnabled(emGainCheckBox.isSelected());
readoutNoiseTextField.setEnabled(!emGainCheckBox.isSelected());
}
});
add(emGainCheckBox, GridBagHelper.leftCol());
add(emGainTextField, GridBagHelper.rightCol());
add(new JLabel("Readout noise [e-/pixel]:"), GridBagHelper.leftCol());
add(readoutNoiseTextField, GridBagHelper.rightCol());
params.registerComponent(isEmGain, emGainCheckBox);
params.registerComponent(gain, emGainTextField);
params.registerComponent(readoutNoise, readoutNoiseTextField);
JPanel buttons = new JPanel(new GridBagLayout());
buttons.add(createDefaultsButton());
buttons.add(Box.createHorizontalGlue(), new GridBagHelper.Builder()
.fill(GridBagConstraints.HORIZONTAL).weightx(1).build());
buttons.add(Help.createHelpButton(CameraSetupPlugIn.class));
buttons.add(createOKButton());
buttons.add(createCancelButton());
add(Box.createVerticalStrut(10), GridBagHelper.twoCols());
add(buttons, GridBagHelper.twoCols());
params.updateComponents();
getRootPane().setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
pack();
setLocationRelativeTo(null);
setModal(true);
}
};
dialog2.showAndGetResult();
}
}
public static double pixelsToNanometers(double pixels) {
return pixels * getPixelSize();
}
public static double nanometersToPixels(double nanometers) {
return nanometers / getPixelSize();
}
public static double pixels2ToNanometers2(double pixels2) {
return pixels2 * getPixelSize() * getPixelSize();
}
public static double nanometers2ToPixels2(double nanometers2) {
return nanometers2 / getPixelSize() / getPixelSize();
}
public static double adCountsToPhotons(double counts) {
return (counts - getOffset()) * getPhotons2ADU() / getGain();
}
public static double photonsToAdCounts(double photons) {
return photons / getPhotons2ADU() * getGain() + getOffset();
}
public static double digitalCountsToPhotons(double intensity) {
if(getIsEmGain()) {
return intensity * getPhotons2ADU() / getQuantumEfficiency() / getGain();
} else {
return intensity * getPhotons2ADU() / getQuantumEfficiency();
}
}
public static double photonsToDigitalCounts(double photons) {
if(getIsEmGain()) {
return photons * getGain() / getPhotons2ADU() * getQuantumEfficiency();
} else {
return photons / getPhotons2ADU() * getQuantumEfficiency();
}
}
public static void loadPreferences() {
params.loadPrefs();
}
}