Commit 87f4c7ce authored by Andrey Filippov's avatar Andrey Filippov

Debugging derivatives for mechanical variables

parent 1ac965a0
...@@ -27,12 +27,14 @@ import ij.IJ; ...@@ -27,12 +27,14 @@ import ij.IJ;
import ij.gui.GenericDialog; import ij.gui.GenericDialog;
import ij.text.TextWindow; import ij.text.TextWindow;
import java.awt.Point;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
...@@ -40,12 +42,6 @@ import org.apache.commons.configuration.ConfigurationException; ...@@ -40,12 +42,6 @@ import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration; import org.apache.commons.configuration.XMLConfiguration;
//import Distortions.LMAArrays; // may still reuse? //import Distortions.LMAArrays; // may still reuse?
import Jama.LUDecomposition; import Jama.LUDecomposition;
import Jama.Matrix; import Jama.Matrix;
...@@ -60,6 +56,7 @@ public class FocusingField { ...@@ -60,6 +56,7 @@ public class FocusingField {
public double currentPX0; public double currentPX0;
public double currentPY0; public double currentPY0;
boolean sagittalMaster=false; // center data is the same, when true sagittal fitting only may change r=0 coefficients, boolean sagittalMaster=false; // center data is the same, when true sagittal fitting only may change r=0 coefficients,
boolean parallelOnly = true; // only process measurements for parallel moves
// when false - tangential is master // when false - tangential is master
double [] minMeas= {1.0,1.0,1.0,1.0,1.0,1.0}; // pixels double [] minMeas= {1.0,1.0,1.0,1.0,1.0,1.0}; // pixels
double [] maxMeas= {4.5,4.5,4.5,4.5,4.5,4.5}; // pixels double [] maxMeas= {4.5,4.5,4.5,4.5,4.5,4.5}; // pixels
...@@ -78,6 +75,8 @@ public class FocusingField { ...@@ -78,6 +75,8 @@ public class FocusingField {
private boolean qb_use_corrected=true; private boolean qb_use_corrected=true;
private boolean qb_invert=true; private boolean qb_invert=true;
private boolean z_relative=true; // focal distance relative to center greeen
private boolean rslt_show_z_axial=true; private boolean rslt_show_z_axial=true;
private boolean rslt_show_z_individual=true; private boolean rslt_show_z_individual=true;
...@@ -157,12 +156,11 @@ public class FocusingField { ...@@ -157,12 +156,11 @@ public class FocusingField {
public boolean debugDerivativesFxDxDy=false; public boolean debugDerivativesFxDxDy=false;
private Properties savedProperties=null; // to-be applied private Properties savedProperties=null; // to-be applied
private String propertiesPrefix=null; private String propertiesPrefix=null;
// public double fwhm_to_mtf50=500.0; // put actual number
public double fwhm_to_mtf50=2*Math.log(2.0)/Math.PI*1000; //pi/0.004 public double fwhm_to_mtf50=2*Math.log(2.0)/Math.PI*1000; //pi/0.004
public boolean updateStatus=true;
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
System.out.println("FocusingField: setProperties()"); if (debugLevel>1) System.out.println("FocusingField: setProperties()");
if (fieldFitting == null) { if (fieldFitting == null) {
System.out.println("fieldFitting is not initioalized, nothing to save"); System.out.println("fieldFitting is not initioalized, nothing to save");
return; return;
...@@ -174,6 +172,7 @@ public class FocusingField { ...@@ -174,6 +172,7 @@ public class FocusingField {
properties.setProperty(prefix+"currentPX0",currentPX0+""); properties.setProperty(prefix+"currentPX0",currentPX0+"");
properties.setProperty(prefix+"currentPY0",currentPY0+""); properties.setProperty(prefix+"currentPY0",currentPY0+"");
properties.setProperty(prefix+"sagittalMaster",sagittalMaster+""); properties.setProperty(prefix+"sagittalMaster",sagittalMaster+"");
properties.setProperty(prefix+"parallelOnly",parallelOnly+"");
for (int chn=0; chn<minMeas.length; chn++) properties.setProperty(prefix+"minMeas_"+chn,minMeas[chn]+""); for (int chn=0; chn<minMeas.length; chn++) properties.setProperty(prefix+"minMeas_"+chn,minMeas[chn]+"");
for (int chn=0; chn<maxMeas.length; chn++) properties.setProperty(prefix+"maxMeas_"+chn,maxMeas[chn]+""); for (int chn=0; chn<maxMeas.length; chn++) properties.setProperty(prefix+"maxMeas_"+chn,maxMeas[chn]+"");
for (int chn=0; chn<thresholdMax.length; chn++) properties.setProperty(prefix+"thresholdMax_"+chn,thresholdMax[chn]+""); for (int chn=0; chn<thresholdMax.length; chn++) properties.setProperty(prefix+"thresholdMax_"+chn,thresholdMax[chn]+"");
...@@ -190,6 +189,7 @@ public class FocusingField { ...@@ -190,6 +189,7 @@ public class FocusingField {
properties.setProperty(prefix+"qb_scan_step",qb_scan_step+""); properties.setProperty(prefix+"qb_scan_step",qb_scan_step+"");
properties.setProperty(prefix+"qb_use_corrected",qb_use_corrected+""); properties.setProperty(prefix+"qb_use_corrected",qb_use_corrected+"");
properties.setProperty(prefix+"qb_invert",qb_invert+""); properties.setProperty(prefix+"qb_invert",qb_invert+"");
properties.setProperty(prefix+"z_relative",z_relative+"");
properties.setProperty(prefix+"rslt_show_z_axial",rslt_show_z_axial+""); properties.setProperty(prefix+"rslt_show_z_axial",rslt_show_z_axial+"");
properties.setProperty(prefix+"rslt_show_z_individual",rslt_show_z_individual+""); properties.setProperty(prefix+"rslt_show_z_individual",rslt_show_z_individual+"");
properties.setProperty(prefix+"rslt_show_f_axial",rslt_show_f_axial+""); properties.setProperty(prefix+"rslt_show_f_axial",rslt_show_f_axial+"");
...@@ -204,7 +204,7 @@ public class FocusingField { ...@@ -204,7 +204,7 @@ public class FocusingField {
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
savedProperties=properties; savedProperties=properties;
propertiesPrefix=prefix; propertiesPrefix=prefix;
System.out.println("FocusingField: getProperties()"); if (debugLevel>1) System.out.println("FocusingField: getProperties()");
if (fieldFitting == null) { if (fieldFitting == null) {
System.out.println("fieldFitting is not initialized, will apply properties later"); System.out.println("fieldFitting is not initialized, will apply properties later");
return; //fieldFitting=new FieldFitting(); return; //fieldFitting=new FieldFitting();
...@@ -219,7 +219,10 @@ public class FocusingField { ...@@ -219,7 +219,10 @@ public class FocusingField {
currentPX0=Double.parseDouble(properties.getProperty(prefix+"currentPX0")); currentPX0=Double.parseDouble(properties.getProperty(prefix+"currentPX0"));
if (properties.getProperty(prefix+"currentPY0")!=null) if (properties.getProperty(prefix+"currentPY0")!=null)
currentPY0=Double.parseDouble(properties.getProperty(prefix+"currentPY0")); currentPY0=Double.parseDouble(properties.getProperty(prefix+"currentPY0"));
if (properties.getProperty(prefix+"sagittalMaster")!=null)
sagittalMaster=Boolean.parseBoolean(properties.getProperty(prefix+"sagittalMaster"));
if (properties.getProperty(prefix+"parallelOnly")!=null)
parallelOnly=Boolean.parseBoolean(properties.getProperty(prefix+"parallelOnly"));
for (int chn=0; chn<minMeas.length; chn++) if (properties.getProperty(prefix+"minMeas_"+chn)!=null) for (int chn=0; chn<minMeas.length; chn++) if (properties.getProperty(prefix+"minMeas_"+chn)!=null)
minMeas[chn]=Double.parseDouble(properties.getProperty(prefix+"minMeas_"+chn)); minMeas[chn]=Double.parseDouble(properties.getProperty(prefix+"minMeas_"+chn));
for (int chn=0; chn<maxMeas.length; chn++) if (properties.getProperty(prefix+"maxMeas_"+chn)!=null) for (int chn=0; chn<maxMeas.length; chn++) if (properties.getProperty(prefix+"maxMeas_"+chn)!=null)
...@@ -250,6 +253,8 @@ public class FocusingField { ...@@ -250,6 +253,8 @@ public class FocusingField {
qb_use_corrected=Boolean.parseBoolean(properties.getProperty(prefix+"qb_use_corrected")); qb_use_corrected=Boolean.parseBoolean(properties.getProperty(prefix+"qb_use_corrected"));
if (properties.getProperty(prefix+"qb_invert")!=null) if (properties.getProperty(prefix+"qb_invert")!=null)
qb_invert=Boolean.parseBoolean(properties.getProperty(prefix+"qb_invert")); qb_invert=Boolean.parseBoolean(properties.getProperty(prefix+"qb_invert"));
if (properties.getProperty(prefix+"z_relative")!=null)
z_relative=Boolean.parseBoolean(properties.getProperty(prefix+"z_relative"));
if (properties.getProperty(prefix+"rslt_show_z_axial")!=null) if (properties.getProperty(prefix+"rslt_show_z_axial")!=null)
rslt_show_z_axial=Boolean.parseBoolean(properties.getProperty(prefix+"rslt_show_z_axial")); rslt_show_z_axial=Boolean.parseBoolean(properties.getProperty(prefix+"rslt_show_z_axial"));
if (properties.getProperty(prefix+"rslt_show_z_individual")!=null) if (properties.getProperty(prefix+"rslt_show_z_individual")!=null)
...@@ -357,10 +362,12 @@ public boolean configureDataVector(String title, boolean forcenew){ ...@@ -357,10 +362,12 @@ public boolean configureDataVector(String title, boolean forcenew){
if (tmpFieldFitting==null) tmpFieldFitting= new FieldFitting(); // just to get field description if (tmpFieldFitting==null) tmpFieldFitting= new FieldFitting(); // just to get field description
int [] numCurvPars=tmpFieldFitting.getNumCurvars(); int [] numCurvPars=tmpFieldFitting.getNumCurvars();
GenericDialog gd = new GenericDialog(title+(forcenew?" RESETTING DATA":"")); GenericDialog gd = new GenericDialog(title+(forcenew?" RESETTING DATA":""));
gd.addMessage("=== Setting minimal measured PSF radius for different colors/directions ==="); gd.addCheckbox("Only use measurements acquired during parallel moves (false - use all)",parallelOnly);
gd.addCheckbox("Sagittal channels are master channels (false - tangential are masters)",sagittalMaster); gd.addCheckbox("Sagittal channels are master channels (false - tangential are masters)",sagittalMaster);
gd.addMessage("=== Setting minimal measured PSF radius for different colors/directions ===");
for (int i=0;i<minMeas.length;i++){ for (int i=0;i<minMeas.length;i++){
gd.addNumericField(tmpFieldFitting.getDescription(i),this.minMeas[i],3,5,"pix"); gd.addNumericField(tmpFieldFitting.getDescription(i),this.minMeas[i],3,5,"pix");
} }
...@@ -392,6 +399,7 @@ public boolean configureDataVector(String title, boolean forcenew){ ...@@ -392,6 +399,7 @@ public boolean configureDataVector(String title, boolean forcenew){
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
parallelOnly=gd.getNextBoolean();
sagittalMaster= gd.getNextBoolean(); sagittalMaster= gd.getNextBoolean();
for (int i=0;i<minMeas.length;i++)this.minMeas[i]= gd.getNextNumber(); for (int i=0;i<minMeas.length;i++)this.minMeas[i]= gd.getNextNumber();
useMinMeas= gd.getNextBoolean(); useMinMeas= gd.getNextBoolean();
...@@ -418,7 +426,7 @@ public boolean configureDataVector(String title, boolean forcenew){ ...@@ -418,7 +426,7 @@ public boolean configureDataVector(String title, boolean forcenew){
numCurvPars[0], numCurvPars[0],
numCurvPars[1]); numCurvPars[1]);
if (savedProperties!=null){ if (savedProperties!=null){
System.out.println("configureDataVector(): Applying properties"); if (debugLevel>1) System.out.println("configureDataVector(): Applying properties");
getProperties(propertiesPrefix,savedProperties); getProperties(propertiesPrefix,savedProperties);
} }
} }
...@@ -437,17 +445,49 @@ public boolean configureDataVector(String title, boolean forcenew){ ...@@ -437,17 +445,49 @@ public boolean configureDataVector(String title, boolean forcenew){
} }
private int [] getParallelDiff(MeasuredSample [] vector){
HashMap<Point,AtomicInteger> map=new HashMap<Point,AtomicInteger>();
for (MeasuredSample ms:vector) {
Point diff=new Point (ms.motors[1]-ms.motors[0],ms.motors[2]-ms.motors[0]);
if (map.containsKey(diff)) map.get(diff).incrementAndGet();
else map.put(diff, new AtomicInteger(1));
}
Point parallelDiff=new Point(0,0);
int maxRun=0;
for (Point diff:map.keySet()){
if (map.get(diff).get()>maxRun){
maxRun=map.get(diff).get();
parallelDiff=diff;
}
}
if (debugLevel>1) System.out.println("getParallelDiff(): maximal number of parallel measurements is "+
maxRun+", for M2-M1="+parallelDiff.x+", M3-M2="+parallelDiff.y);
int [] result= {parallelDiff.x,parallelDiff.y};
return result;
}
// includes deselected channels // includes deselected channels
public void setDataVector(MeasuredSample [] vector){ // remove unused channels if any public void setDataVector(MeasuredSample [] vector){ // remove unused channels if any
if (debugLevel>1) System.out.println("+++++ (Re)calculating sample weights +++++"); if (debugLevel>1) System.out.println("+++++ (Re)calculating sample weights +++++");
int [] diffs=null;
if (parallelOnly) diffs=getParallelDiff(vector);
boolean [] chanSel=fieldFitting.getSelectedChannels(); boolean [] chanSel=fieldFitting.getSelectedChannels();
int numSamples=0; int numSamples=0;
for (int i=0;i<vector.length;i++) if (chanSel[vector[i].channel]) numSamples++; for (int i=0;i<vector.length;i++) if (chanSel[vector[i].channel]){
if ((diffs!=null) && (
((vector[i].motors[1]-vector[i].motors[0]) != diffs[0]) ||
((vector[i].motors[2]-vector[i].motors[0]) != diffs[1]))) continue;
numSamples++;
}
dataVector=new MeasuredSample [numSamples]; dataVector=new MeasuredSample [numSamples];
int n=0; int n=0;
for (int i=0;i<vector.length;i++) if (chanSel[vector[i].channel]) dataVector[n++]=vector[i]; for (int i=0;i<vector.length;i++) if (chanSel[vector[i].channel]) {
if ((diffs!=null) && (
((vector[i].motors[1]-vector[i].motors[0]) != diffs[0]) ||
((vector[i].motors[2]-vector[i].motors[0]) != diffs[1]))) continue;
dataVector[n++]=vector[i];
}
int corrLength=fieldFitting.getNumberOfCorrParameters(); int corrLength=fieldFitting.getNumberOfCorrParameters();
dataValues = new double [dataVector.length+corrLength]; dataValues = new double [dataVector.length+corrLength];
dataWeights = new double [dataVector.length+corrLength]; dataWeights = new double [dataVector.length+corrLength];
...@@ -811,7 +851,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2 ...@@ -811,7 +851,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
} }
// convert to microns from pixels // convert to microns from pixels
weightReference[c]*=getPixelUM(); weightReference[c]*=getPixelUM();
System.out.println("==== weightReference["+c+"]="+weightReference[c]); if (debugLevel>1) System.out.println("==== weightReference["+c+"]="+weightReference[c]);
} }
} else { } else {
thresholdMax=null; thresholdMax=null;
...@@ -994,7 +1034,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2 ...@@ -994,7 +1034,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
nMeas++; nMeas++;
} }
if (debugLevel>3) System.out.println(); if (debugLevel>3) System.out.println();
if (debugLevel>0) System.out.println("createDataVector -> "+sampleList.size()+" elements"); if (debugLevel>1) System.out.println("createDataVector -> "+sampleList.size()+" elements");
return sampleList.toArray(new MeasuredSample[0]); return sampleList.toArray(new MeasuredSample[0]);
} }
/** /**
...@@ -1149,17 +1189,17 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2 ...@@ -1149,17 +1189,17 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
} }
// if ((this.currentfX==null)|| ((this.jacobian==null) && !this.threadedLMA )) { // if ((this.currentfX==null)|| ((this.jacobian==null) && !this.threadedLMA )) {
if ((this.currentfX==null)|| (this.lMAArrays==null)) { if ((this.currentfX==null)|| (this.lMAArrays==null)) {
if (debugLevel>1) { String msg="initial Jacobian matrix calculation. Points:"+this.dataValues.length+" Parameters:"+this.currentVector.length;
System.out.println(": initial Jacobian matrix calculation. Points:"+this.dataValues.length+" Parameters:"+this.currentVector.length); if (debugLevel>1) System.out.println(msg);
} if (this.updateStatus) IJ.showStatus(msg);
this.currentfX=createFXandJacobian(this.currentVector, true); // is it always true here (this.jacobian==null) this.currentfX=createFXandJacobian(this.currentVector, true); // is it always true here (this.jacobian==null)
this.lMAArrays=calculateJacobianArrays(this.currentfX); this.lMAArrays=calculateJacobianArrays(this.currentfX);
this.currentRMS= calcErrorDiffY(this.currentfX,false); this.currentRMS= calcErrorDiffY(this.currentfX,false);
this.currentRMSPure=calcErrorDiffY(this.currentfX, true); this.currentRMSPure=calcErrorDiffY(this.currentfX, true);
if (debugLevel>1) { msg=": initial RMS="+IJ.d2s(this.currentRMS,8)+" (pure RMS"+IJ.d2s(this.currentRMSPure,8)+")"+
System.out.println(": initial RMS="+IJ.d2s(this.currentRMS,8)+" (pure RMS="+IJ.d2s(this.currentRMSPure,8)+")"+ ". Calculating next Jacobian. Points:"+this.dataValues.length+" Parameters:"+this.currentVector.length;
". Calculating next Jacobian. Points:"+this.dataValues.length+" Parameters:"+this.currentVector.length); if (debugLevel>1) System.out.println(msg);
} if (this.updateStatus) IJ.showStatus(msg);
} else { } else {
// continuing, but need to re-build Y vector to match this.currentVector // continuing, but need to re-build Y vector to match this.currentVector
commitParameterVector(this.currentVector); // may be extra job? commitParameterVector(this.currentVector); // may be extra job?
...@@ -1191,6 +1231,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2 ...@@ -1191,6 +1231,7 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
for (int i=0;i<this.nextVector.length;i++) this.nextVector[i]+=deltas[i]; for (int i=0;i<this.nextVector.length;i++) this.nextVector[i]+=deltas[i];
// another option - do not calculate J now, just fX. and late - calculate both if it was improvement // another option - do not calculate J now, just fX. and late - calculate both if it was improvement
// save current Jacobian // save current Jacobian
if (debugLevel>2) { if (debugLevel>2) {
System.out.println("this.nextVector"); System.out.println("this.nextVector");
for (int i=0;i<this.nextVector.length;i++){ for (int i=0;i<this.nextVector.length;i++){
...@@ -1207,13 +1248,13 @@ this.nextRMS= calcErrorDiffY(this.nextfX,false); ...@@ -1207,13 +1248,13 @@ this.nextRMS= calcErrorDiffY(this.nextfX,false);
this.nextRMSPure= calcErrorDiffY(this.nextfX,true); this.nextRMSPure= calcErrorDiffY(this.nextfX,true);
this.lastImprovements[1]=this.lastImprovements[0]; this.lastImprovements[1]=this.lastImprovements[0];
this.lastImprovements[0]=this.currentRMS-this.nextRMS; this.lastImprovements[0]=this.currentRMS-this.nextRMS;
if (debugLevel>2) { String msg="currentRMS="+this.currentRMS+
System.out.println("stepLMA this.currentRMS="+this.currentRMS+ ", currentRMSPure="+this.currentRMSPure+
", this.currentRMSPure="+this.currentRMSPure+ ", nextRMS="+this.nextRMS+
", this.nextRMS="+this.nextRMS+ ", nextRMSPure="+this.nextRMSPure+
", this.nextRMSPure="+this.nextRMSPure+ ", delta="+(this.currentRMS-this.nextRMS);
", delta="+(this.currentRMS-this.nextRMS)); if (debugLevel>2) System.out.println("stepLMA "+msg);
} if (this.updateStatus) IJ.showStatus(msg);
boolean [] status={matrixNonSingular && (this.nextRMS<=this.currentRMS),!matrixNonSingular}; boolean [] status={matrixNonSingular && (this.nextRMS<=this.currentRMS),!matrixNonSingular};
// additional test if "worse" but the difference is too small, it was be caused by computation error, like here: // additional test if "worse" but the difference is too small, it was be caused by computation error, like here:
//stepLevenbergMarquardtAction() step=27, this.currentRMS=0.17068403807026408, this.nextRMS=0.1706840380702647 //stepLevenbergMarquardtAction() step=27, this.currentRMS=0.17068403807026408, this.nextRMS=0.1706840380702647
...@@ -1258,26 +1299,25 @@ this.nextRMSPure= calcErrorDiffY(this.nextfX,true); ...@@ -1258,26 +1299,25 @@ this.nextRMSPure= calcErrorDiffY(this.nextfX,true);
} }
public void stepLevenbergMarquardtAction(int debugLevel){// public void stepLevenbergMarquardtAction(int debugLevel){//
this.iterationStepNumber++; this.iterationStepNumber++;
// apply/revert,modify lambda // apply/revert,modify lambda
if (debugLevel>1) { String msg="currentRMS="+this.currentRMS+
System.out.println( ", currentRMSPure="+this.currentRMSPure+
"stepLevenbergMarquardtAction() step="+this.iterationStepNumber+ ", nextRMS="+this.nextRMS+
", this.currentRMS="+this.currentRMS+ ", nextRMSPure="+this.nextRMSPure+
", this.currentRMSPure="+this.currentRMSPure+ ", delta="+(this.currentRMS-this.nextRMS)+
", this.nextRMS="+this.nextRMS+ ", lambda="+this.lambda;
", this.nextRMSPure="+this.nextRMSPure+ if (debugLevel>1) System.out.println("stepLevenbergMarquardtAction() "+msg);
" lambda="+this.lambda); //+" at "+IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)+" sec"); // if (this.updateStatus) IJ.showStatus(msg);
} if (this.nextRMS<this.currentRMS) { //improved
if (this.nextRMS<this.currentRMS) { //improved this.lambda*=this.lambdaStepDown;
this.lambda*=this.lambdaStepDown; this.currentRMS=this.nextRMS;
this.currentRMS=this.nextRMS; this.currentfX=this.nextfX;
this.currentfX=this.nextfX; this.currentVector=this.nextVector;
this.currentVector=this.nextVector; } else {
} else { this.lambda*=this.lambdaStepUp;
this.lambda*=this.lambdaStepUp; this.lMAArrays=this.savedLMAArrays; // restore Jt*J and Jt*diff
this.lMAArrays=this.savedLMAArrays; // restore Jt*J and Jt*diff }
}
} }
/** /**
...@@ -1670,6 +1710,8 @@ public void listCombinedResults(){ ...@@ -1670,6 +1710,8 @@ public void listCombinedResults(){
gd.addCheckbox("Show constant-z sections (axial model)", this.rslt_show_f_axial); gd.addCheckbox("Show constant-z sections (axial model)", this.rslt_show_f_axial);
gd.addCheckbox("Show constant-z sections (per-sample adjusted)", this.rslt_show_f_individual); gd.addCheckbox("Show constant-z sections (per-sample adjusted)", this.rslt_show_f_individual);
gd.addCheckbox("Show mtf50 (false - PSF FWHM)", this.rslt_mtf50_mode); gd.addCheckbox("Show mtf50 (false - PSF FWHM)", this.rslt_mtf50_mode);
gd.addCheckbox("Show focal distance relative to center green (false - motor absolute)", this.z_relative);
gd.addMessage("Multiple section setup:"); gd.addMessage("Multiple section setup:");
gd.addNumericField("Scan from (relative to green center)", this.rslt_scan_below, 3,7,"um"); gd.addNumericField("Scan from (relative to green center)", this.rslt_scan_below, 3,7,"um");
gd.addNumericField("Scan to (relative to green center)", this.rslt_scan_above, 3,7,"um"); gd.addNumericField("Scan to (relative to green center)", this.rslt_scan_above, 3,7,"um");
...@@ -1687,114 +1729,118 @@ public void listCombinedResults(){ ...@@ -1687,114 +1729,118 @@ public void listCombinedResults(){
this.rslt_show_f_axial= gd.getNextBoolean(); this.rslt_show_f_axial= gd.getNextBoolean();
this.rslt_show_f_individual= gd.getNextBoolean(); this.rslt_show_f_individual= gd.getNextBoolean();
this.rslt_mtf50_mode= gd.getNextBoolean(); this.rslt_mtf50_mode= gd.getNextBoolean();
this.rslt_scan_below= gd.getNextNumber(); this.z_relative= gd.getNextBoolean();
this.rslt_scan_above= gd.getNextNumber(); this.rslt_scan_below= gd.getNextNumber();
this.rslt_scan_step= gd.getNextNumber(); this.rslt_scan_above= gd.getNextNumber();
listCombinedResults( this.rslt_scan_step= gd.getNextNumber();
"Field curvature measuremnts results", //String title,
null, //String path, listCombinedResults(
rslt_show_chn, //boolean [] show_chn, "Field curvature measuremnts results", //String title,
rslt_show_z_axial, //boolean show_z_axial, null, //String path,
rslt_show_z_individual, //boolean show_z_individual, z_relative?center_z[1]:0.0,
rslt_show_f_axial, //boolean show_f_axial, rslt_show_chn, //boolean [] show_chn,
rslt_show_f_individual, //boolean show_f_individual, rslt_show_z_axial, //boolean show_z_axial,
center_z[1]+rslt_scan_below, // double scan_below, rslt_show_z_individual, //boolean show_z_individual,
center_z[1]+rslt_scan_above, //double scan_above, rslt_show_f_axial, //boolean show_f_axial,
rslt_scan_step, //double scan_step, rslt_show_f_individual, //boolean show_f_individual,
rslt_mtf50_mode); //boolean freq_mode) center_z[1]+rslt_scan_below, // double scan_below,
center_z[1]+rslt_scan_above, //double scan_above,
rslt_scan_step, //double scan_step,
rslt_mtf50_mode); //boolean freq_mode)
} }
public void listCombinedResults( public void listCombinedResults(
String title, String title,
String path, String path,
boolean [] show_chn, double z0, // subtract from z
boolean show_z_axial, boolean [] show_chn,
boolean show_z_individual, boolean show_z_axial,
boolean show_f_axial, boolean show_z_individual,
boolean show_f_individual, boolean show_f_axial,
double scan_below, boolean show_f_individual,
double scan_above, double scan_below,
double scan_step, double scan_above,
boolean freq_mode){ double scan_step,
String [] chnNames={"RS","RT","GS","GT","BS","BT"}; boolean freq_mode){
String [] chnNames={"RS","RT","GS","GT","BS","BT"};
double k=this.fwhm_to_mtf50; //TODO: correct psf fwhm to mtf50 conversion
// double k=2*Math.log(2.0)/Math.PI*1000; double k=this.fwhm_to_mtf50; //TODO: correct psf fwhm to mtf50 conversion
// String header="Z(um)\tComposite\tRed\tGreen\tBlue"; // double k=2*Math.log(2.0)/Math.PI*1000;
String header="radius(mm)"; // String header="Z(um)\tComposite\tRed\tGreen\tBlue";
if (show_z_axial){ String header="radius(mm)";
for (int i=0;i<show_chn.length;i++){ if (show_z_axial){
if (show_chn[i])header+="\tZ"+chnNames[i]; for (int i=0;i<show_chn.length;i++){
} if (show_chn[i])header+="\tZ"+chnNames[i];
} }
if (show_z_individual){ }
for (int i=0;i<show_chn.length;i++){ if (show_z_individual){
if (show_chn[i])header+="\tZ"+chnNames[i]+"*"; for (int i=0;i<show_chn.length;i++){
} if (show_chn[i])header+="\tZ"+chnNames[i]+"*";
} }
int numSect=0; }
if (show_f_axial || show_f_individual) for (double z=scan_below;z<=scan_above;z+=scan_step){ int numSect=0;
if (show_f_axial) { if (show_f_axial || show_f_individual) for (double z=scan_below;z<=scan_above;z+=scan_step){
for (int i=0;i<show_chn.length;i++){ if (show_f_axial) {
if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z,1); for (int i=0;i<show_chn.length;i++){
} if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z,1);
} }
if (show_f_individual) { }
for (int i=0;i<show_chn.length;i++){ if (show_f_individual) {
if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z,1)+"*"; for (int i=0;i<show_chn.length;i++){
} if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z,1)+"*";
} }
numSect++; }
} numSect++;
double [] radiuses=fieldFitting.getSampleRadiuses(); }
double [][][][] f_values=new double [numSect][2][][]; double [] radiuses=fieldFitting.getSampleRadiuses();
double [][][] z_values={ double [][][][] f_values=new double [numSect][2][][];
(show_z_axial?fieldFitting.getCalcZ(false,true):null), double [][][] z_values={
(show_z_individual?fieldFitting.getCalcZ(true,true):null)}; (show_z_axial?fieldFitting.getCalcZ(false,true):null),
int sect=0; (show_z_individual?fieldFitting.getCalcZ(true,true):null)};
for (double z=scan_below;z<=scan_above;z+=scan_step){ int sect=0;
f_values[sect][0]=show_f_axial?fieldFitting.getCalcValuesForZ(z, false,true):null; for (double z=scan_below;z<=scan_above;z+=scan_step){
f_values[sect][1]=show_f_individual?fieldFitting.getCalcValuesForZ(z, true,true):null; f_values[sect][0]=show_f_axial?fieldFitting.getCalcValuesForZ(z, false,true):null;
sect++; f_values[sect][1]=show_f_individual?fieldFitting.getCalcValuesForZ(z, true,true):null;
} sect++;
StringBuffer sb = new StringBuffer(); }
for (int n=0;n<radiuses.length;n++){ StringBuffer sb = new StringBuffer();
sb.append(IJ.d2s(radiuses[n],3)); for (int n=0;n<radiuses.length;n++){
if (show_z_axial){ sb.append(IJ.d2s(radiuses[n],3));
for (int i=0;i<show_chn.length;i++){ if (show_z_axial){
if (show_chn[i]) sb.append("\t"+IJ.d2s(z_values[0][i][n],3)); for (int i=0;i<show_chn.length;i++){
} if (show_chn[i]) sb.append("\t"+IJ.d2s(z_values[0][i][n]-z0,3));
} }
if (show_z_individual){ }
for (int i=0;i<show_chn.length;i++){ if (show_z_individual){
if (show_chn[i]) sb.append("\t"+IJ.d2s(z_values[1][i][n],3)); for (int i=0;i<show_chn.length;i++){
} if (show_chn[i]) sb.append("\t"+IJ.d2s(z_values[1][i][n]-z0,3));
} }
if (show_f_axial || show_f_individual) for (int s=0;s<numSect;s++){ }
if (show_f_axial) for (int i=0;i<show_chn.length;i++) if (show_chn[i]) { if (show_f_axial || show_f_individual) for (int s=0;s<numSect;s++){
if (freq_mode){ if (show_f_axial) for (int i=0;i<show_chn.length;i++) if (show_chn[i]) {
sb.append("\t"+IJ.d2s(k/f_values[s][0][i][n],3)); if (freq_mode){
} else { sb.append("\t"+IJ.d2s(k/f_values[s][0][i][n],3));
sb.append("\t"+IJ.d2s(f_values[s][0][i][n],3)); } else {
} sb.append("\t"+IJ.d2s(f_values[s][0][i][n],3));
} }
if (show_f_individual) for (int i=0;i<show_chn.length;i++) if (show_chn[i]) { }
if (freq_mode){ if (show_f_individual) for (int i=0;i<show_chn.length;i++) if (show_chn[i]) {
sb.append("\t"+IJ.d2s(k/f_values[s][1][i][n],3)); if (freq_mode){
} else { sb.append("\t"+IJ.d2s(k/f_values[s][1][i][n],3));
sb.append("\t"+IJ.d2s(f_values[s][1][i][n],3)); } else {
} sb.append("\t"+IJ.d2s(f_values[s][1][i][n],3));
} }
} }
sb.append("\n"); }
} sb.append("\n");
if (path!=null) { }
CalibrationFileManagement.saveStringToFile ( if (path!=null) {
path, CalibrationFileManagement.saveStringToFile (
header+"\n"+sb.toString()); path,
} else { header+"\n"+sb.toString());
new TextWindow(title, header, sb.toString(), 800,1000); } else {
} new TextWindow(title, header, sb.toString(), 800,1000);
}
} }
...@@ -1821,7 +1867,9 @@ public void listScanQB(){ ...@@ -1821,7 +1867,9 @@ public void listScanQB(){
gd.addNumericField("Relative (to green) weight of red channel",100* this.k_red, 3,7,"%"); gd.addNumericField("Relative (to green) weight of red channel",100* this.k_red, 3,7,"%");
gd.addNumericField("Relative (to green) weight of blue channel",100* this.k_blue, 3,7,"%"); gd.addNumericField("Relative (to green) weight of blue channel",100* this.k_blue, 3,7,"%");
gd.addCheckbox("Use per-sample location corrected data", this.qb_use_corrected); gd.addCheckbox("Use per-sample location corrected data", this.qb_use_corrected);
gd.addCheckbox("Use per-sample location corrected data", this.qb_invert); gd.addCheckbox("Show mtf50 (false - PSF FWHM)", this.qb_invert);
gd.addCheckbox("Show focal distance relative to center green (false - motor absolute)", this.z_relative);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) { if (gd.wasCanceled()) {
return; return;
...@@ -1833,10 +1881,13 @@ public void listScanQB(){ ...@@ -1833,10 +1881,13 @@ public void listScanQB(){
this.k_blue= 0.01*gd.getNextNumber(); this.k_blue= 0.01*gd.getNextNumber();
this.qb_use_corrected= gd.getNextBoolean(); this.qb_use_corrected= gd.getNextBoolean();
this.qb_invert= gd.getNextBoolean(); this.qb_invert= gd.getNextBoolean();
this.z_relative= gd.getNextBoolean();
listScanQB( listScanQB(
"Focus quality vs. distance", // String title, "Focus quality vs. distance", // String title,
null, //String path, null, //String path,
z_relative?center_z[1]:0.0,
center_z[1]+this.qb_scan_below, //double min_z, // absolute center_z[1]+this.qb_scan_below, //double min_z, // absolute
center_z[1]+this.qb_scan_above, //double max_z, center_z[1]+this.qb_scan_above, //double max_z,
this.qb_scan_step , //double step_z, this.qb_scan_step , //double step_z,
...@@ -1849,6 +1900,7 @@ public void listScanQB(){ ...@@ -1849,6 +1900,7 @@ public void listScanQB(){
public void listScanQB( public void listScanQB(
String title, String title,
String path, String path,
double z0,
double min_z, // absolute double min_z, // absolute
double max_z, double max_z,
double step_z, double step_z,
...@@ -1869,9 +1921,9 @@ public void listScanQB( ...@@ -1869,9 +1921,9 @@ public void listScanQB(
z, z,
corrected); corrected);
if (freq_mode){ if (freq_mode){
sb.append(z+"\t"+IJ.d2s(k/qb_w,3)+"\t"+IJ.d2s(k/qb_rgb[0],3)+"\t"+IJ.d2s(k/qb_rgb[1],3)+"\t"+IJ.d2s(k/qb_rgb[2],3) +"\n"); sb.append(IJ.d2s(z-z0,3)+"\t"+IJ.d2s(k/qb_w,3)+"\t"+IJ.d2s(k/qb_rgb[0],3)+"\t"+IJ.d2s(k/qb_rgb[1],3)+"\t"+IJ.d2s(k/qb_rgb[2],3) +"\n");
} else { } else {
sb.append(z+"\t"+IJ.d2s(qb_w,3)+"\t"+IJ.d2s(qb_rgb[0],3)+"\t"+IJ.d2s(qb_rgb[1],3)+"\t"+IJ.d2s(qb_rgb[2],3) +"\n"); sb.append(IJ.d2s(z-z0,3)+"\t"+IJ.d2s(qb_w,3)+"\t"+IJ.d2s(qb_rgb[0],3)+"\t"+IJ.d2s(qb_rgb[1],3)+"\t"+IJ.d2s(qb_rgb[2],3) +"\n");
} }
} }
...@@ -2015,17 +2067,14 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2015,17 +2067,14 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
// if (this.showNextImages) showDiff (this.nextfX, "fit-"+(this.iterationStepNumber+1)); // if (this.showNextImages) showDiff (this.nextfX, "fit-"+(this.iterationStepNumber+1));
} }
stepLevenbergMarquardtAction(debugLevel); // apply step - in any case? stepLevenbergMarquardtAction(debugLevel); // apply step - in any case?
/*
if (this.updateStatus){ if (this.updateStatus){
IJ.showStatus(this.seriesNumber+": "+"Step #"+this.iterationStepNumber+ IJ.showStatus("Step #"+this.iterationStepNumber+
" RMS="+IJ.d2s(this.currentRMS,8)+ " RMS="+IJ.d2s(this.currentRMS,8)+
" ("+IJ.d2s(this.firstRMS,8)+")"+ " ("+IJ.d2s(this.firstRMS,8)+")"+
" RMSPure="+IJ.d2s(this.currentRMSPure,8)+ " RMSPure="+IJ.d2s(this.currentRMSPure,8)+
" ("+IJ.d2s(this.firstRMSPure,8)+")"+ " ("+IJ.d2s(this.firstRMSPure,8)+")"+
" "); " ");
// showStatus(this.seriesNumber+": "+"Step #"+this.iterationStepNumber+" RMS="+IJ.d2s(this.currentRMS,8)+ " ("+IJ.d2s(this.firstRMS,8)+")",0);
} }
*/
if (!cont){ if (!cont){
if (this.saveSeries) { if (this.saveSeries) {
savedLambda=this.lambda; savedLambda=this.lambda;
...@@ -2058,23 +2107,23 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2058,23 +2107,23 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
// if (wasLastSeries) break; // if (wasLastSeries) break;
// } // while (this.fittingStrategy.isSeriesValid(this.seriesNumber)){ // TODO: Add "stop" tag to series // } // while (this.fittingStrategy.isSeriesValid(this.seriesNumber)){ // TODO: Add "stop" tag to series
if (debugLevel>0) System.out.println("LevenbergMarquardt(): all done"+ String msg="RMS="+this.currentRMS+" ("+this.firstRMS+") "+
", step="+ this.iterationStepNumber+ ", pure RMS="+this.currentRMSPure+" ("+this.firstRMSPure+") "+
", RMS="+this.currentRMS+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3);
" ("+this.firstRMS+") "+ if (debugLevel>0) System.out.println("stepLevenbergMarquardtAction() "+msg);
" at "+ IJ.d2s(0.000000001*(System.nanoTime()-this.startTime),3)); // if (this.updateStatus) IJ.showStatus(msg);
this.savedVector=this.currentVector.clone(); if (this.updateStatus){
commitParameterVector(this.savedVector); IJ.showStatus("Done: Step #"+this.iterationStepNumber+
return true; // all series done " RMS="+IJ.d2s(this.currentRMS,8)+
" ("+IJ.d2s(this.firstRMS,8)+")"+
} " RMSPure="+IJ.d2s(this.currentRMSPure,8)+
" ("+IJ.d2s(this.firstRMSPure,8)+")"+
" ");
}
this.savedVector=this.currentVector.clone();
commitParameterVector(this.savedVector);
return true; // all series done
}
public class FocusingFieldMeasurement{ public class FocusingFieldMeasurement{
public String timestamp; public String timestamp;
...@@ -2348,7 +2397,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2348,7 +2397,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
if (mechanicalFocusingModel==null){ if (mechanicalFocusingModel==null){
System.out.println ("Mechanical properties not yet initialized, will save properties later"); if (debugLevel>1) System.out.println ("Mechanical properties not yet initialized, will save properties later");
return; return;
} }
properties.setProperty(prefix+"numberOfLocations",numberOfLocations+""); properties.setProperty(prefix+"numberOfLocations",numberOfLocations+"");
...@@ -2400,7 +2449,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2400,7 +2449,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
if (properties.getProperty(prefix+"centerSelect_Y")!=null) if (properties.getProperty(prefix+"centerSelect_Y")!=null)
centerSelect[1]=Boolean.parseBoolean(properties.getProperty(prefix+"centerSelect_Y")); centerSelect[1]=Boolean.parseBoolean(properties.getProperty(prefix+"centerSelect_Y"));
if (mechanicalFocusingModel==null){ if (mechanicalFocusingModel==null){
System.out.println ("Mechanical properties not yet initialized, will apply properties later"); if (debugLevel>1) System.out.println ("Mechanical properties not yet initialized, will apply properties later");
return; return;
} }
mechanicalFocusingModel.getProperties(prefix+"mechanicalFocusingModel.",properties); mechanicalFocusingModel.getProperties(prefix+"mechanicalFocusingModel.",properties);
...@@ -2500,13 +2549,19 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2500,13 +2549,19 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
for (int np=0;np<numPars;np++) for (int i=0;i<numberOfLocations;i++) for (int np=0;np<numPars;np++) for (int i=0;i<numberOfLocations;i++)
correctionParameters[chn][np][i]=0.0; correctionParameters[chn][np][i]=0.0;
} }
for (int np=0;np<numPars;np++) for (int i=0;i<numberOfLocations;i++) for (int np=0;np<numPars;np++) {
if (properties.getProperty(prefix+"correctionParameters_"+chn+"_"+np+"_"+i)!=null) { if ((correctionParameters[chn][np]==null) || (correctionParameters[chn][np].length!=numberOfLocations)){
correctionParameters[chn][np][i]=Double.parseDouble(properties.getProperty(prefix+"correctionParameters_"+chn+"_"+np+"_"+i)); correctionParameters[chn][np]=new double [numberOfLocations];
for (int i=0;i<numberOfLocations;i++) correctionParameters[chn][np][i]=0.0;
} }
for (int i=0;i<numberOfLocations;i++)
if (properties.getProperty(prefix+"correctionParameters_"+chn+"_"+np+"_"+i)!=null) {
correctionParameters[chn][np][i]=Double.parseDouble(properties.getProperty(prefix+"correctionParameters_"+chn+"_"+np+"_"+i));
}
}
} }
} else { } else {
System.out.println("numberOfLocations==0, can not restore"); if (debugLevel>1) System.out.println("numberOfLocations==0, can not restore");
} }
...@@ -2533,7 +2588,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2533,7 +2588,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
if (numCorrPar==0){ if (numCorrPar==0){
String msg="No correction parameters are enabled"; String msg="No correction parameters are enabled";
IJ.showMessage(msg); IJ.showMessage(msg);
System.out.println(msg); if (debugLevel>1) System.out.println(msg);
return; return;
} }
double [][] pixels=new double [numCorrPar][numSamples]; double [][] pixels=new double [numCorrPar][numSamples];
...@@ -2861,7 +2916,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2861,7 +2916,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
} }
} }
System.out.println("getCorrVector 1"); if (debugLevel>1) System.out.println("getCorrVector 1");
sampleCorrVector=new double [numPars]; sampleCorrVector=new double [numPars];
for (int nChn=0; nChn< sampleCorrChnParIndex.length;nChn++) { for (int nChn=0; nChn< sampleCorrChnParIndex.length;nChn++) {
if (sampleCorrChnParIndex[nChn]!=null){ if (sampleCorrChnParIndex[nChn]!=null){
...@@ -2873,7 +2928,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2873,7 +2928,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
else { else {
sampleCorrVector[sampleCorrChnParIndex[nChn][nPar]+i]=0.0; sampleCorrVector[sampleCorrChnParIndex[nChn][nPar]+i]=0.0;
if ((correctionParameters[nChn]!=null) && (correctionParameters[nChn][nPar]!=null) && (correctionParameters[nChn][nPar].length<i)){ if ((correctionParameters[nChn]!=null) && (correctionParameters[nChn][nPar]!=null) && (correctionParameters[nChn][nPar].length<i)){
System.out.println("correctionParameters["+nChn+"]["+nPar+"].length < "+i); if (debugLevel>1) System.out.println("correctionParameters["+nChn+"]["+nPar+"].length < "+i);
} }
} }
} }
...@@ -2885,7 +2940,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2885,7 +2940,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
public void commitCorrVector(){ public void commitCorrVector(){
System.out.println("commitCorrVector()"); if (debugLevel>1) System.out.println("commitCorrVector()");
commitCorrVector(sampleCorrVector); commitCorrVector(sampleCorrVector);
} }
...@@ -2897,7 +2952,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2897,7 +2952,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
if(correctionParameters[nChn]==null) if(correctionParameters[nChn]==null)
correctionParameters[nChn]=new double [sampleCorrChnParIndex[nChn].length][]; correctionParameters[nChn]=new double [sampleCorrChnParIndex[nChn].length][];
if ((correctionParameters[nChn][nPar]==null) || (correctionParameters[nChn][nPar].length!=numberOfLocations)){ if ((correctionParameters[nChn][nPar]==null) || (correctionParameters[nChn][nPar].length!=numberOfLocations)){
System.out.println("commitCorrVector(): correctionParameters["+nChn+"]["+nPar+"].length < "+numberOfLocations); if (debugLevel>1) System.out.println("commitCorrVector(): correctionParameters["+nChn+"]["+nPar+"].length < "+numberOfLocations);
correctionParameters[nChn][nPar]=new double [numberOfLocations]; correctionParameters[nChn][nPar]=new double [numberOfLocations];
} }
...@@ -2975,7 +3030,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2975,7 +3030,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
// currently all correction parameters are initialized as zeros. // currently all correction parameters are initialized as zeros.
getCorrVector(); getCorrVector();
System.out.println("was resetting sampleCorrVector here"); if (debugLevel>1) System.out.println("was resetting sampleCorrVector here");
// sampleCorrVector=new double [numPars]; // sampleCorrVector=new double [numPars];
// for (int i=0;i<numPars;i++)sampleCorrVector[i]=0.0; // for (int i=0;i<numPars;i++)sampleCorrVector[i]=0.0;
...@@ -3002,7 +3057,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3002,7 +3057,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double [] corr =new double [correctionParameters[chn].length]; double [] corr =new double [correctionParameters[chn].length];
for (int i=0;i<corr.length;i++){ for (int i=0;i<corr.length;i++){
if ((correctionParameters[chn][i] !=null) && (correctionParameters[chn][i].length<=i)){ if ((correctionParameters[chn][i] !=null) && (correctionParameters[chn][i].length<=i)){
System.out.println("getCorrPar(): correctionParameters["+chn+"]["+i+"].length="+correctionParameters[chn][i].length); if (debugLevel>1) System.out.println("getCorrPar(): correctionParameters["+chn+"]["+i+"].length="+correctionParameters[chn][i].length);
} }
if ((correctionParameters[chn][i] !=null) && (correctionParameters[chn][i].length>i)) corr[i]=correctionParameters[chn][i][sampleIndex]; if ((correctionParameters[chn][i] !=null) && (correctionParameters[chn][i].length>i)) corr[i]=correctionParameters[chn][i][sampleIndex];
else corr[i]=0.0; else corr[i]=0.0;
...@@ -3213,7 +3268,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3213,7 +3268,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
} else { } else {
if ((correctionParameters[n][np]!=null) && (correctionParameters[n][np].length!=numberOfLocations)){ if ((correctionParameters[n][np]!=null) && (correctionParameters[n][np].length!=numberOfLocations)){
System.out.println("getParameterValueStrings(): correctionParameters["+n+"]["+np+"].length="+correctionParameters[n][np].length); if (debugLevel>1) System.out.println("getParameterValueStrings(): correctionParameters["+n+"]["+np+"].length="+correctionParameters[n][np].length);
} }
} }
} }
...@@ -3357,7 +3412,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3357,7 +3412,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
index++; index++;
} }
} }
System.out.println("createParameterVector(): using sampleCorrVector - do we need to create it first?"); if (debugLevel>1) System.out.println("createParameterVector(): using sampleCorrVector - do we need to create it first?");
getCorrVector(); // do we need that? getCorrVector(); // do we need that?
int nCorrPars=getNumberOfCorrParameters(); int nCorrPars=getNumberOfCorrParameters();
for (int i=0;i<nCorrPars;i++) pars[np++]=sampleCorrVector[i]; for (int i=0;i<nCorrPars;i++) pars[np++]=sampleCorrVector[i];
...@@ -3387,7 +3442,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3387,7 +3442,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
} }
// copy correction parameters // copy correction parameters
System.out.println("commitParameterVector(): Creating and committing sampleCorrVector"); if (debugLevel>1) System.out.println("commitParameterVector(): Creating and committing sampleCorrVector");
int nCorrPars=getNumberOfCorrParameters(); int nCorrPars=getNumberOfCorrParameters();
for (int i=0;i<nCorrPars;i++) sampleCorrVector[i]=pars[np++]; for (int i=0;i<nCorrPars;i++) sampleCorrVector[i]=pars[np++];
commitCorrVector(); commitCorrVector();
...@@ -3663,7 +3718,44 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3663,7 +3718,44 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
public Double getValue(MECH_PAR mech_par){ public Double getValue(MECH_PAR mech_par){
return paramValues[mech_par.ordinal()]; return paramValues[mech_par.ordinal()];
} }
public double [] debugDeriv_ZdZ(
double scale,
int [] motors,
double px,
double py){
double [] derivSteps ={
0.001, // [0] K0 843.6001052876973
0.001, // [1] KD1 1600.0723700390713
0.001, // [2] KD3 -2428.8998947123027
0.1, // [3] sM1 -1.1720600074585734
0.1, // [4] cM1 0.6081060292866338
0.1, // [5] sM2 -2.3717384278673035
0.1, // [6] cM2 1.2305414643438266
0.1, // [7] sM3 2.7345656468251707
0.1, // [8] cM3 1.4187890097199358
1.0, // [9] Lx -0.535718420298317
1.0, // [10] Ly 0.0
10.0, // [11] mpX0 -2.816702366108815E-5
10.0, // [12] mpY0 -8.351458550253758E-5
1.0, // [13] z0 1.0
0.1, // [14] tx -2.5168000000000004
0.1 // [15] ty -1.76
};
double [] initialVector=paramValues.clone();
double [] derivs=new double [paramValues.length];
for (int i=0;i<derivs.length;i++){
paramValues[i]=initialVector[i]-scale*derivSteps[i];
double zm=calc_ZdZ(motors,px,py,null);
paramValues[i]=initialVector[i]+scale*derivSteps[i];
double zp=calc_ZdZ(motors,px,py,null);
paramValues[i]=initialVector[i];
derivs[i]=(zp-zm)/(2.0*scale*derivSteps[i]);
}
return derivs;
}
/** /**
* Calculate distance from the selected sensor pixel to the common "focal" plane * Calculate distance from the selected sensor pixel to the common "focal" plane
...@@ -3679,6 +3771,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3679,6 +3771,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double px, double px,
double py, double py,
double[] deriv){ double[] deriv){
double debugMot=6545;
int debugThreshold=1;
boolean dbg = (debugLevel>debugThreshold);
/* /*
kM3=K0+KD3 kM3=K0+KD3
kM1=K0+KD1-KD3 kM1=K0+KD1-KD3
...@@ -3713,13 +3808,24 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3713,13 +3808,24 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double zM2=kM2 * aM2; double zM2=kM2 * aM2;
double zM3=kM3 * aM3; double zM3=kM3 * aM3;
double zc= 0.25* zM1+ 0.25* zM2+ 0.5 * zM3; double zc= 0.25* zM1+ 0.25* zM2+ 0.5 * zM3+getValue(MECH_PAR.z0);
double dx=PIXEL_SIZE*(px-getValue(MECH_PAR.mpX0)); double dx=PIXEL_SIZE*(px-getValue(MECH_PAR.mpX0));
double dy=PIXEL_SIZE*(py-getValue(MECH_PAR.mpY0)); double dy=PIXEL_SIZE*(py-getValue(MECH_PAR.mpY0));
double zx=dx*(getValue(MECH_PAR.tx)+(2*zM3-zM1-zM2)/(4*getValue(MECH_PAR.Lx))) ; double zx=dx*(getValue(MECH_PAR.tx)+(2*zM3-zM1-zM2)/(4*getValue(MECH_PAR.Lx))) ;
double zy=dy*(getValue(MECH_PAR.ty)+(zM1-zM2)/(2*getValue(MECH_PAR.Ly))); // double zy=dy*(getValue(MECH_PAR.ty)+(zM1-zM2)/(2*getValue(MECH_PAR.Ly)));
double zy=dy*(getValue(MECH_PAR.ty)+(zM2-zM1)/(2*getValue(MECH_PAR.Ly)));
double z=zc+zx+zy; double z=zc+zx+zy;
if (deriv==null) return z; if (dbg) if ((Math.abs(m1)==debugMot)&& (Math.abs(m2)==debugMot)){
System.out.print ("M: "+((int)m1)+":"+((int)m2)+":"+((int)m3)+
" dxy="+IJ.d2s(dx,3)+":"+IJ.d2s(dy,3)+" zcxy="+IJ.d2s(zc,3)+":"+IJ.d2s(zx,3)+":"+IJ.d2s(zy,3)+
" zxy(t)="+IJ.d2s(dx*getValue(MECH_PAR.tx),3)+":"+IJ.d2s(dy*getValue(MECH_PAR.ty),3));
}
if (deriv==null) {
if (dbg) if ((Math.abs(m1)==debugMot)&& (Math.abs(m2)==debugMot)){
System.out.println();
}
return z;
}
for (int i=0;i<deriv.length;i++) deriv[i]=0.0; for (int i=0;i<deriv.length;i++) deriv[i]=0.0;
// Above same as calc_Z // Above same as calc_Z
double dx_mpX0=-PIXEL_SIZE; double dx_mpX0=-PIXEL_SIZE;
...@@ -3731,8 +3837,10 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3731,8 +3837,10 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double zM2_KD1=-aM2; double zM2_KD1=-aM2;
double zM2_KD3=-aM2; double zM2_KD3=-aM2;
double zM3_K0= aM3; double zM3_K0= aM3;
double zM3_KD1=-aM3; // double zM3_KD1=-aM3;
double zM3_KD3= 0.0; // double zM3_KD3= 0.0;
double zM3_KD1= 0.0;
double zM3_KD3= aM3;
double zM1_sM1= kM1*p2pi*Math.sin(m1/p2pi); double zM1_sM1= kM1*p2pi*Math.sin(m1/p2pi);
double zM1_cM1= kM1*p2pi*Math.cos(m1/p2pi); double zM1_cM1= kM1*p2pi*Math.cos(m1/p2pi);
double zM2_sM2= kM2*p2pi*Math.sin(m2/p2pi); double zM2_sM2= kM2*p2pi*Math.sin(m2/p2pi);
...@@ -3754,7 +3862,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3754,7 +3862,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double zx_a=dx/(4*getValue(MECH_PAR.Lx)); double zx_a=dx/(4*getValue(MECH_PAR.Lx));
double zx_K0= (2*zM3_K0-zM1_K0-zM2_K0)*zx_a; double zx_K0= (2*zM3_K0-zM1_K0-zM2_K0)*zx_a;
double zx_KD1=(2*zM3_KD1-zM1_KD1-zM2_KD1)*zx_a; double zx_KD1=(2*zM3_KD1-zM1_KD1-zM2_KD1)*zx_a;
double zx_KD3=(2*zM3_K0-zM1_K0-zM2_K0)*zx_a; double zx_KD3=(2*zM3_KD3-zM1_KD3-zM2_KD3)*zx_a;
double zx_sM1= (-zM1_sM1)*zx_a; double zx_sM1= (-zM1_sM1)*zx_a;
double zx_cM1= (-zM1_cM1)*zx_a; double zx_cM1= (-zM1_cM1)*zx_a;
double zx_sM2= (-zM2_sM2)*zx_a; double zx_sM2= (-zM2_sM2)*zx_a;
...@@ -3764,20 +3872,21 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3764,20 +3872,21 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double zx_mpX0=dx_mpX0/(4*getValue(MECH_PAR.Lx)); double zx_mpX0=dx_mpX0/(4*getValue(MECH_PAR.Lx));
double zx_tx= dx; double zx_tx= dx;
double zx_Lx= -dx*(2*zM3-zM1-zM2)/(4*getValue(MECH_PAR.Lx)*getValue(MECH_PAR.Lx)); double zx_Lx= -dx*(2*zM3-zM1-zM2)/(4*getValue(MECH_PAR.Lx)*getValue(MECH_PAR.Lx));
// double zy=dy*(getValue(MECH_PAR.ty)+(zM2-zM1)/(2*getValue(MECH_PAR.Ly)));
double zy_a=dx/(2*getValue(MECH_PAR.Ly)); double zy_a=dy/(2*getValue(MECH_PAR.Ly));
double zy_K0= (zM1_K0- zM2_K0) *zy_a; double zy_K0= (zM2_K0- zM1_K0) *zy_a; // double zy_K0= (zM1_K0- zM2_K0) *zy_a;
double zy_KD1= (zM1_KD1-zM2_KD1)*zy_a; double zy_KD1= (zM2_KD1-zM1_KD1)*zy_a; // double zy_KD1= (zM2_KD1-zM1_KD1)*zy_a;
double zy_KD3= (zM1_KD3-zM2_KD3)*zy_a; double zy_KD3= (zM2_KD3-zM1_KD3)*zy_a; // double zy_KD3= (zM1_KD3-zM2_KD3)*zy_a;
double zy_sM1= (zM1_sM1)*zy_a; double zy_sM1= (-zM1_sM1)*zy_a; // double zy_sM1= (zM1_sM1)*zy_a;
double zy_cM1= (zM1_cM1)*zy_a; double zy_cM1= (-zM1_cM1)*zy_a; // double zy_cM1= (zM1_cM1)*zy_a;
double zy_sM2= (-zM2_sM2)*zy_a; double zy_sM2= (zM2_sM2)*zy_a; // double zy_sM2= (-zM2_sM2)*zy_a;
double zy_cM2= (-zM2_cM2)*zy_a; double zy_cM2= (zM2_cM2)*zy_a; // double zy_cM2= (-zM2_cM2)*zy_a;
double zy_sM3= 0.0; double zy_sM3= 0.0;
double zy_cM3= 0.0; double zy_cM3= 0.0;
double zy_mpY0=dy_mpY0/(2*getValue(MECH_PAR.Ly)); double zy_mpY0=dy_mpY0/(2*getValue(MECH_PAR.Ly));
double zy_ty= dy; double zy_ty= dy;
double zy_Ly= -dy*(zM1-zM2)/(2*getValue(MECH_PAR.Ly)*getValue(MECH_PAR.Ly)); // double zy_Ly= -dy*(zM1-zM2)/(2*getValue(MECH_PAR.Ly)*getValue(MECH_PAR.Ly));
double zy_Ly= -dy*(zM2-zM1)/(2*getValue(MECH_PAR.Ly)*getValue(MECH_PAR.Ly));
deriv[getIndex(MECH_PAR.K0)]= zc_K0+zx_K0+zy_K0; deriv[getIndex(MECH_PAR.K0)]= zc_K0+zx_K0+zy_K0;
deriv[getIndex(MECH_PAR.KD1)]=zc_KD1+zx_KD1+zy_KD1; deriv[getIndex(MECH_PAR.KD1)]=zc_KD1+zx_KD1+zy_KD1;
...@@ -3792,8 +3901,25 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3792,8 +3901,25 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
deriv[getIndex(MECH_PAR.Ly)] = zy_Ly; deriv[getIndex(MECH_PAR.Ly)] = zy_Ly;
deriv[getIndex(MECH_PAR.mpX0)] = zx_mpX0; deriv[getIndex(MECH_PAR.mpX0)] = zx_mpX0;
deriv[getIndex(MECH_PAR.mpY0)] = zy_mpY0; deriv[getIndex(MECH_PAR.mpY0)] = zy_mpY0;
deriv[getIndex(MECH_PAR.z0)] = 1.0;
deriv[getIndex(MECH_PAR.tx)] = zx_tx; deriv[getIndex(MECH_PAR.tx)] = zx_tx;
deriv[getIndex(MECH_PAR.ty)] = zy_ty; deriv[getIndex(MECH_PAR.ty)] = zy_ty;
if (dbg) if ((Math.abs(m1)==debugMot)&& (Math.abs(m2)==debugMot)){
if (m1*m2>0){
System.out.println("same sign");
} else {
System.out.println("opposite sign");
}
System.out.println (" zxy_txy="+IJ.d2s(zx_tx,3)+":"+IJ.d2s(zy_ty,3)+" zxy_Lxy="+IJ.d2s(zx_Lx,5)+":"+IJ.d2s(zy_Ly,5));
double [] dbg_derivs= debugDeriv_ZdZ(
0.1, //scale,
motors,
px,
py);
for (int i=0;i<deriv.length;i++){
System.out.println(i+": "+descriptions[i][0]+" deriv="+deriv[i]+", dbg_derivs="+dbg_derivs[i]);
}
}
return z; return z;
} }
public boolean[] getDefaultMask(){ public boolean[] getDefaultMask(){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment