import ij.*; import ij.plugin.PlugIn; import ij.gui.*; import java.awt.*; /*Sebastian Rhode, Plugin to display SNR characteristics of a CCD Version 1.3 2008-03-31 */ public class Calc_CCD_SNR implements PlugIn { public void run(String arg) { if (IJ.versionLessThan("1.39t")) return; /* default values for common CCDs ----- DEFAULT CCD ---------------------------- qe = 0.65; gain = 1; nf = 1; nd = 0.1; sc = 0.05; sr = 20; pix = 8; ----- DEFAULT EM-CCD ------------------------- qe = 0.93; gain = 1000; nf = 1.41; nd = 0.001; sc = 0.05; sr = 60; pix = 16 ----- DEFAULT I-CCD -------------------------- qe = 0.50; gain = 1000; nf = 1.6; nd = 0.001; sc = 0; sr = 20; pix = 10 ----- DEFAULT IDEAL -------------------------- qe = 1; gain = 1; nf = 1; nd = 0; sc = 0; sr = 0; pix = 6.45 ----------------------------------------------*/ /* Quantum Efficiency --> Quantum yield of CCD chip. EM-Gain --> Multiplication factor for On-Chip Electron Multiplication. Noise Factor --> Noise component (also called Multiplicative Noise) related to the amplification process. The factor represents the statistical variation in the overall number of electrons generated by the initial detected charge. For a stochastic gain process in a EM-CCD the noise factor = 1.41 and for normal CCDs = 1.0 and for modern ICCDs = 1.6. Dark Current --> Charge generated by thermal generated electrons --> Dark Noise is the statistical variation of the Dark Current --> equals sqrt(Dark Current). Dark Current can be subtracted from an image while the dark noise remains. Spurious Noise --> Clock Induced Charge (CIC) which is independent of the exposure time. During the transfer of electrons there is a small probability of producing extra electrons through impact ionization. Is normally hidden in the ReadOut Noise for normal CCDs and ICCDs. For EM-CCDs those charges will be amplified and become detectable. ReadOut Noise --> Noise related to the actual ReadOut process. Faster readout speeds will lead to a higher ReadOut Noise. That noise can be effectively reduced to 1 by using an EM_CCD -------------------------------------------------------------------------------------------------------------------- Other terms to know: Shot noise --> represents the uncertainity in the number of incoming photons. It is an inherent noise (can not be overcome) and is defined by POISSON statistics. Correction Factor --> Assume the photon flux is 100 photons per pixel for an 16µm CCD chip per frame. To compare that to a 8µm CCD chip one must keep the following in mind: 16µm^2 / 8µm^2 = 4 --> to compare the SNR values you have to use the x=100 photons for the 16µm CCD chip and the x =100 photons / 4 (!!!) = 25. In other words, 100 photons/frame/pixel for a 16µm chip corresponds to 25 photons/frame/pixel for an 8µm chip! SNR-Equation: SNR= SIGNAL / sqrt( NF^2 * (SIGNAL + DARK + CIC^2) + (SR^2/GAIN^2)); */ double qe1 = 0.93; // quantum efficiency double gain1= 50; // electron multiplier gain for EM-CCD or I-CCD double nf1 = 1.41; // noise factor --> nf^2 = sigma_out^2/(gain^2*sigma_input^2) double nd1 = 0.03; // dark current double sc1 = 0.05; // clock induced charge (CIC) or spurious noise double sr1 = 30; // readout noise double px1 = 16; // pixel size //--------------------------------------------------------------------- double qe2 = 0.55; // quantum efficiency double gain2= 1; // electron multiplier gain for EM-CCD or I-CCD double nf2 = 1; // noise factor --> nf^2 = sigma_out^2/(gain^2*sigma_input^2) double nd2 = 0.1; // dark current double sc2 = 0.05; // clock induced charge (CIC) or spurious noise double sr2 = 10; // readout noise double px2 = 6.45; // pixel size GenericDialog gd = new GenericDialog("Specify Parameters for CCDs", IJ.getInstance()); gd.addMessage("Parameters CCD 1"); gd.addNumericField("Quantum efficiency [0-1]", qe1, 2); gd.addNumericField("EM-Gain (no EM-CCD --> 1)", gain1, 0); gd.addNumericField("Noise Factor (CCD=1 or EM-CCD=1.41)", nf1, 2); gd.addNumericField("Dark Current [e-/pix/sec]", nd1, 3); gd.addNumericField("Spurious Noise CIC [events/pix]", sc1, 3); gd.addNumericField("Readout Noise [e-]", sr1, 0 ); gd.addNumericField("Pixel Size [µm]", px1, 2 ); gd.addMessage("-------------------------------------------"); gd.addMessage("Parameters CCD 2"); gd.addNumericField("Quantum efficiency [0-1]", qe2, 2); gd.addNumericField("EM-Gain (no EM-CCD --> 1)", gain2, 0); gd.addNumericField("Noise Factor (CCD=1 or EM-CCD=1.41)", nf2, 2); gd.addNumericField("Dark Current [e-/pix/sec]", nd2, 3); gd.addNumericField("Spurious Noise CIC [events/pix]", sc2, 3); gd.addNumericField("Readout Noise [e-]", sr2, 0 ); gd.addNumericField("Pixel Size [µm]", px2, 2 ); gd.showDialog(); if (gd.wasCanceled()) return; //----------CCD 1 -------------------- qe1 = gd.getNextNumber(); gain1 = gd.getNextNumber(); nf1 = gd.getNextNumber(); nd1 = gd.getNextNumber(); sc1 = gd.getNextNumber(); sr1 = gd.getNextNumber(); px1 = gd.getNextNumber(); //----------CCD 2 -------------------- qe2 = gd.getNextNumber(); gain2 = gd.getNextNumber(); nf2 = gd.getNextNumber(); nd2 = gd.getNextNumber(); sc2 = gd.getNextNumber(); sr2 = gd.getNextNumber(); px2 = gd.getNextNumber(); double pmax = 250; double corrf = 0; double[] pp = new double [(int)pmax]; for (int i = 0; i= px1) corrf = px2*px2/px1/px1; if (px2 < px1) corrf = px1*px1/px2/px2; double cf = Math.round(corrf*100); cf = cf / 100; PlotWindow plot = new PlotWindow("Theoretical SNR Calculation","Number of Photons","SNR",pp,snr1); plot.setLimits(0, pmax, 0, 10); plot.setColor(Color.black); plot.addLabel(0.6,0.95,"Correction Factor: "+IJ.d2s(cf,2)); plot.setColor(Color.red); plot.addLabel(0.1,0.2,"CCD2"); plot.addPoints(pp,snr2,PlotWindow.LINE); plot.setColor(Color.blue); plot.addLabel(0.1,0.1,"CCD1"); plot.draw(); } }