package ij.plugin.filter;
import ij.*;
import ij.gui.*;
import ij.process.*;
import ij.measure.*;
import ij.util.*;
import ij.io.*;
import ij.plugin.TextReader;
import ij.plugin.frame.Fitter;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
import java.io.*;
/** Implements the Analyze/Calibrate command. */
public class Calibrator implements PlugInFilter, Measurements, ActionListener {
private static final String NONE = "None";
private static final String INVERTER = "Pixel Inverter";
private static final String UNCALIBRATED_OD = "Uncalibrated OD";
private static final String CUSTOM = "Custom";
private static boolean showSettings;
private boolean global1, global2;
private ImagePlus imp;
private int choiceIndex;
private String[] functions;
private int nFits = Calibration.EXP_RECOVERY+1; //don't set to CurveFitter.fitList.length; Calibration can't cope with it
private String curveFitError;
private int spacerIndex = nFits+1;
private int inverterIndex = nFits+2;
private int odIndex = nFits+3;
private int customIndex = nFits+4;
private static String xText = "";
private static String yText = "";
private static boolean importedValues;
private String unit;
private double lx=0.02, ly=0.1;
private int oldFunction;
private String sumResiduals, fitGoodness;
private Button open, save;
private GenericDialog gd;
private static boolean showPlotFlagSaved = true;
private boolean showPlotFlag;
private static String unitSaved = Calibration.DEFAULT_VALUE_UNIT;
private CurveFitter curveFitter;
public int setup(String arg, ImagePlus imp) {
this.imp = imp;
//IJ.register(Calibrator.class);
return DOES_ALL-DOES_RGB+NO_CHANGES;
}
public void run(ImageProcessor ip) {
global1 = imp.getGlobalCalibration()!=null;
if (!showDialog(imp))
return;
if (choiceIndex==customIndex) {
showPlot(null, null, imp.getCalibration(), null);
return;
} else if (imp.getType()==ImagePlus.GRAY32) {
if (choiceIndex==0)
imp.getCalibration().setValueUnit(unit);
else
IJ.error("Calibrate", "Function must be \"None\" for 32-bit images,\nbut you can change the Unit.");
} else
calibrate(imp);
}
public boolean showDialog(ImagePlus imp) {
String defaultChoice;
Calibration cal = imp.getCalibration();
functions = getFunctionList(cal.getFunction()==Calibration.CUSTOM);
int function = cal.getFunction();
oldFunction = function;
double[] p = cal.getCoefficients();
unit = cal.getValueUnit();
if (unit == Calibration.DEFAULT_VALUE_UNIT)
unit = unitSaved;
if (function==Calibration.NONE)
defaultChoice=NONE;
else if (functionmax) {
String title = (bitDepth==8?"8-bit":"16-bit") + " Calibration";
String msg = "Measured (uncalibrated) values in the left\ncolumn must be in the range 0-";
IJ.error(title, msg+max+".");
return false;
}
}
return true;
}
double[] doCurveFitting(double[] x, double[] y, int fitType) {
if (x.length!=y.length || y.length==0) {
IJ.error("Calibrate",
"To create a calibration curve, the left column must\n"
+"contain a list of measured mean pixel values and the\n"
+"right column must contain the same number of calibration\n"
+"standard values. Use the Measure command to add mean\n"
+"pixel value measurements to the left column.\n"
+" \n"
+" Left column: "+x.length+" values\n"
+" Right column: "+y.length+" values\n"
);
return null;
}
int n = x.length;
double xmin=0.0,xmax;
if (imp.getType()==ImagePlus.GRAY16)
xmax=65535.0;
else
xmax=255.0;
double[] a = Tools.getMinMax(y);
double ymin=a[0], ymax=a[1];
CurveFitter cf = new CurveFitter(x, y);
cf.doFit(fitType, showSettings);
if (cf.getStatus() == Minimizer.INITIALIZATION_FAILURE) {
curveFitError = cf.getStatusString();
return null;
}
if (IJ.debugMode) IJ.log(cf.getResultString());
int np = cf.getNumParams();
double[] p = cf.getParams();
fitGoodness = IJ.d2s(cf.getRSquared(),6);
curveFitter = cf;
double[] parameters = new double[np];
for (int i=0; i0&&y.length>0)
plot.addPoints(x, y, PlotWindow.CIRCLE);
double[] p = cal.getCoefficients();
if (fit<=Calibration.LOG2) {
drawLabel(plot, CurveFitter.fList[fit]);
ly += 0.04;
}
if (p!=null) {
int np = p.length;
drawLabel(plot, "a="+IJ.d2s(p[0],6,10));
drawLabel(plot, "b="+IJ.d2s(p[1],6,10));
if (np>=3)
drawLabel(plot, "c="+IJ.d2s(p[2],6,10));
if (np>=4)
drawLabel(plot, "d="+IJ.d2s(p[3],6,10));
if (np>=5)
drawLabel(plot, "e="+IJ.d2s(p[4],6,10));
ly += 0.04;
}
if (rSquared!=null)
{drawLabel(plot, "R^2="+rSquared); rSquared=null;}
plot.show();
}
void drawLabel(Plot plot, String label) {
plot.addLabel(lx, ly, label);
ly += 0.08;
}
double sqr(double x) {return x*x;}
String[] getFunctionList(boolean custom) {
int n = nFits+4;
if (custom) n++;
String[] list = new String[n];
list[0] = NONE;
for (int i=0; iMAX_STANDARDS)
count = MAX_STANDARDS;
String s = "";
for (int i=0; i='0'&&c<='9') || c=='-' || c=='.' || c==',' || c=='\n' || c=='\r' || c==' ')
sb.append(c);
}
xData = sb.toString();
StringTokenizer st = new StringTokenizer(xData);
int nTokens = st.countTokens();
if (nTokens<1)
return new double[0];
int n = nTokens;
double data[] = new double[n];
for (int i=0; i1)) {
IJ.error("Calibrate", "This appears to not be a one or two column text file");
return;
}
StringBuffer sb = new StringBuffer();
for (int i=0; i
Ads help maintain this website.