Commit d2c9aab5 authored by Andrey Filippov's avatar Andrey Filippov

Debugging, cleaning up

parent 87f4c7ce
...@@ -4385,7 +4385,7 @@ if (MORE_BUTTONS) { ...@@ -4385,7 +4385,7 @@ if (MORE_BUTTONS) {
FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL); FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL);
if (PROPERTIES!=null) FOCUSING_FIELD.getProperties("FOCUSING_FIELD.", PROPERTIES); if (PROPERTIES!=null) FOCUSING_FIELD.getProperties("FOCUSING_FIELD.", PROPERTIES);
System.out.println("Loaded FocusingField"); System.out.println("Loaded FocusingField");
if (!FOCUSING_FIELD.configureDataVector("Configure curvature",true)) return; if (!FOCUSING_FIELD.configureDataVector("Configure curvature",true,true)) return;
FOCUSING_FIELD.setDataVector(FOCUSING_FIELD.createDataVector()); FOCUSING_FIELD.setDataVector(FOCUSING_FIELD.createDataVector());
double []focusing_fx=FOCUSING_FIELD.createFXandJacobian(true); double []focusing_fx=FOCUSING_FIELD.createFXandJacobian(true);
double rms= FOCUSING_FIELD.getRMS(focusing_fx,false); double rms= FOCUSING_FIELD.getRMS(focusing_fx,false);
...@@ -4397,7 +4397,7 @@ if (MORE_BUTTONS) { ...@@ -4397,7 +4397,7 @@ if (MORE_BUTTONS) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if (FOCUSING_FIELD==null) return; if (FOCUSING_FIELD==null) return;
FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL); FOCUSING_FIELD.setDebugLevel(DEBUG_LEVEL);
if (!FOCUSING_FIELD.configureDataVector("Re-configure curvature parameters",false)) return; if (!FOCUSING_FIELD.configureDataVector("Re-configure curvature parameters",false,true)) return;
FOCUSING_FIELD.setDataVector(FOCUSING_FIELD.createDataVector()); FOCUSING_FIELD.setDataVector(FOCUSING_FIELD.createDataVector());
return; return;
} }
......
...@@ -55,40 +55,82 @@ public class FocusingField { ...@@ -55,40 +55,82 @@ public class FocusingField {
public double pY0_distortions; public double pY0_distortions;
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; // center data is the same, when true sagittal fitting only may change r=0 coefficients,
boolean parallelOnly = true; // only process measurements for parallel moves boolean parallelOnly; // only process measurements for parallel moves
boolean filterInput;
double filterInputMotorDiff;
double filterInputDiff; // um
boolean filterInputFirstLast;
boolean filterInputTooFar; // filter samples that are too far from the "center of mass" of other samples
double filterInpuFarRatio; // remove samples that are farther than this ration of average distance
// 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; // pixels
double [] maxMeas= {4.5,4.5,4.5,4.5,4.5,4.5}; // pixels double [] maxMeas; // pixels
double [] thresholdMax= {2.4,3.0,2.6,3.0,3.1,3.0}; // pixels double [] thresholdMax; // pixels
boolean useMinMeas= true; boolean useMinMeas;
boolean useMaxMeas= true; boolean useMaxMeas;
boolean useThresholdMax=true; boolean useThresholdMax;
int weightMode=1; // 0; // 0 - same weight, 1 - linear threshold difference, 2 - quadratic thershold difference int weightMode; // 0; // 0 - same weight, 1 - linear threshold difference, 2 - quadratic thershold difference
double weightRadius=0.0; //2.0; // Gaussian sigma in mm double weightRadius; //2.0; // Gaussian sigma in mm
private double k_red=0.7; private double k_red;
private double k_blue=0.4; private double k_blue;
private double qb_scan_below; // um
private double qb_scan_below=-20.0; // um private double qb_scan_above; // um
private double qb_scan_above= 60.0; // um private double qb_scan_step; // um
private double qb_scan_step= 0.5; // um private boolean qb_use_corrected;
private boolean qb_invert;
private boolean qb_use_corrected=true; private boolean z_relative; // focal distance relative to center greeen
private boolean qb_invert=true; private boolean rslt_show_z_axial;
private boolean rslt_show_z_individual;
private boolean z_relative=true; // focal distance relative to center greeen private boolean rslt_show_f_axial;
private boolean rslt_show_f_individual;
private boolean rslt_show_z_axial=true; private double rslt_scan_below;
private boolean rslt_show_z_individual=true; private double rslt_scan_above;
private boolean rslt_show_f_axial=true; private double rslt_scan_step;
private boolean rslt_show_f_individual=true; private boolean rslt_mtf50_mode;
private double rslt_scan_below=-10.0; private boolean [] rslt_show_chn;
private double rslt_scan_above= 10.0;
private double rslt_scan_step= 5.0;
private boolean rslt_mtf50_mode= true;
private boolean [] rslt_show_chn={true,true,true,true,true,true};
// not saved/restored // not saved/restored
private double lambdaStepUp; // multiply lambda by this if result is worse
private double lambdaStepDown; // multiply lambda by this if result is better
private double thresholdFinish; // (copied from series) stop iterations if 2 last steps had less improvement (but not worsening )
private int numIterations; // maximal number of iterations
private double maxLambda; // max lambda to fail
private double lambda; // copied from series
private boolean stopEachStep; // open dialog after each fitting step
private boolean stopOnFailure; // open dialog when fitting series failed
private boolean showParams; // show modified parameters
private boolean showDisabledParams;
private boolean showCorrectionParams;
private boolean keepCorrectionParameters;
private boolean saveSeries; // just for the dialog
private boolean showMotors;
private boolean [] showMeasCalc;
private boolean [] showColors;
private boolean [] showDirs;
private boolean [] showSamples;
private boolean showAllSamples;
private boolean showIgnoredData;
private boolean showRad;
private boolean correct_measurement_ST;
private boolean updateWeightWhileFitting;
private int debugPoint;
private int debugParameter;
// not reset to defaults
private boolean [][][][][] sampleMask=null;
public int debugLevel;
public boolean debugDerivatives;
public boolean debugDerivativesFxDxDy;
private Properties savedProperties=null; // to-be applied
private String propertiesPrefix=null;
public double fwhm_to_mtf50=2*Math.log(2.0)/Math.PI*1000; //pi/0.004
public boolean updateStatus=true;
public String [] debugParameterNames=null;
private double [] lastImprovements= {-1.0,-1.0}; // {last improvement, previous improvement}. If both >0 and < thresholdFinish - done
private int iterationStepNumber=0;
private long startTime=0;
private AtomicInteger stopRequested=null; // 1 - stop now, 2 - when convenient
public static final double PIXEL_SIZE=0.0022; // mm public static final double PIXEL_SIZE=0.0022; // mm
public static final String sep = " "; public static final String sep = " ";
public static final String regSep = "\\s"; public static final String regSep = "\\s";
...@@ -98,10 +140,11 @@ public class FocusingField { ...@@ -98,10 +140,11 @@ public class FocusingField {
public double [][][] sampleCoord; public double [][][] sampleCoord;
public ArrayList<FocusingFieldMeasurement> measurements; public ArrayList<FocusingFieldMeasurement> measurements;
double [] weightReference=null; double [] weightReference=null; // calculated per-channel (6) array of maximal PSF FWHM after applying min/max correction
MeasuredSample [] dataVector; MeasuredSample [] dataVector;
double [] dataValues; double [] dataValues;
double [] dataWeights; double [] dataWeights;
// int [][][] dataIndex=null; // [measurement][channel][sample] - index in dataValues (and dataWeights) or -1
// double sumWeights=0.0; // double sumWeights=0.0;
double [][] jacobian=null; // rows - parameters, columns - samples double [][] jacobian=null; // rows - parameters, columns - samples
double [] currentVector=null; double [] currentVector=null;
...@@ -119,45 +162,86 @@ public class FocusingField { ...@@ -119,45 +162,86 @@ public class FocusingField {
private double firstRMS=-1.0; // RMS before current series of LMA started private double firstRMS=-1.0; // RMS before current series of LMA started
private double firstRMSPure=-1.0; // RMS before current series of LMA started private double firstRMSPure=-1.0; // RMS before current series of LMA started
private double lambdaStepUp= 8.0; // multiply lambda by this if result is worse
private double lambdaStepDown= 0.5; // multiply lambda by this if result is better
private double thresholdFinish=0.001; // (copied from series) stop iterations if 2 last steps had less improvement (but not worsening )
private int numIterations= 100; // maximal number of iterations
private double maxLambda= 100.0; // max lambda to fail
private double lambda=0.001; // copied from series
private double [] lastImprovements= {-1.0,-1.0}; // {last improvement, previous improvement}. If both >0 and < thresholdFinish - done
private int iterationStepNumber=0;
private boolean stopEachStep= true; // open dialog after each fitting step
private boolean stopOnFailure= true; // open dialog when fitting series failed
private boolean showParams= false; // show modified parameters
private boolean showDisabledParams = false;
private boolean showCorrectionParams = false;
private boolean keepCorrectionParameters = true;
private long startTime=0;
private AtomicInteger stopRequested=null; // 1 - stop now, 2 - when convenient
private boolean saveSeries=false; // just for the dialog
private boolean showMotors = true;
private boolean [] showMeasCalc = {true,true,true};
private boolean [] showColors = {true,true,true};
private boolean [] showDirs = {true,true};
private boolean [] showSamples = null;
private boolean showAllSamples = true;
private boolean showIgnoredData= false;
private boolean showRad = true;
private boolean [][][][][] sampleMask=null;
private boolean correct_measurement_ST=true; public void setDefaults(){
private boolean updateWeightWhileFitting=false; sagittalMaster=false; // center data is the same, when true sagittal fitting only may change r=0 coefficients,
parallelOnly = true; // only process measurements for parallel moves
filterInput = true;
filterInputMotorDiff = 500.0;
filterInputDiff = 2.0; // um
filterInputFirstLast = true;
filterInputTooFar = true; // filter samples that are too far from the "center of mass" of other samples
filterInpuFarRatio = 3.0; // remove samples that are farther than this ration of average distance
// when false - tangential is master
double [] minMeasDflt= {0.5,0.5,0.5,0.5,0.5,0.5}; // pixels
minMeas= minMeasDflt; // pixels
double [] maxMeasDflt= {4.5,4.5,4.5,4.5,4.5,4.5}; // pixels
maxMeas= maxMeasDflt; // pixels
double [] thresholdMaxDflt= {2.4,3.0,2.6,3.0,3.1,3.0}; // pixels
thresholdMax= thresholdMaxDflt; // pixels
useMinMeas= true;
useMaxMeas= true;
useThresholdMax=true;
weightMode=1; // 0; // 0 - same weight, 1 - linear threshold difference, 2 - quadratic thershold difference
weightRadius=0.0; //2.0; // Gaussian sigma in mm
k_red=0.7;
k_blue=0.4;
qb_scan_below=-40.0; // um
qb_scan_above= 80.0; // um
qb_scan_step= 0.5; // um
qb_use_corrected=true;
qb_invert=true;
z_relative=true; // focal distance relative to center greeen
rslt_show_z_axial=true;
rslt_show_z_individual=true;
rslt_show_f_axial=true;
rslt_show_f_individual=true;
rslt_scan_below=-10.0;
rslt_scan_above= 10.0;
rslt_scan_step= 5.0;
rslt_mtf50_mode= true;
boolean [] rslt_show_chnDflt={true,true,true,true,true,true};
rslt_show_chn=rslt_show_chnDflt.clone();
// not saved/restored
lambdaStepUp= 8.0; // multiply lambda by this if result is worse
lambdaStepDown= 0.5; // multiply lambda by this if result is better
thresholdFinish=0.001; // (copied from series) stop iterations if 2 last steps had less improvement (but not worsening )
numIterations= 100; // maximal number of iterations
maxLambda= 100.0; // max lambda to fail
lambda=0.001; // copied from series
stopEachStep= true; // open dialog after each fitting step
stopOnFailure= true; // open dialog when fitting series failed
showParams= false; // show modified parameters
showDisabledParams = false;
showCorrectionParams = false;
keepCorrectionParameters = true;
saveSeries=false; // just for the dialog
showMotors = true;
boolean [] showMeasCalcDflt={true,true,true};
showMeasCalc=showMeasCalcDflt.clone();
boolean [] showColorsDflt = {true,true,true};
showColors = showColorsDflt.clone();
boolean [] showDirsDflt = {true,true};
showDirs = showDirsDflt.clone();
showSamples = null;
showAllSamples = true;
showIgnoredData= false;
showRad = true;
sampleMask=null;
correct_measurement_ST=true;
updateWeightWhileFitting=false;
debugPoint=-1;
debugParameter=-1;
}
public int debugLevel;
public boolean debugDerivatives;
public boolean debugDerivativesFxDxDy=false;
private Properties savedProperties=null; // to-be applied
private String propertiesPrefix=null;
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){
if (debugLevel>1) System.out.println("FocusingField: setProperties()"); if (debugLevel>1) System.out.println("FocusingField: setProperties()");
...@@ -173,6 +257,12 @@ public class FocusingField { ...@@ -173,6 +257,12 @@ public class FocusingField {
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+""); properties.setProperty(prefix+"parallelOnly",parallelOnly+"");
properties.setProperty(prefix+"filterInput",filterInput+"");
properties.setProperty(prefix+"filterInputMotorDiff",filterInputMotorDiff+"");
properties.setProperty(prefix+"filterInputDiff",filterInputDiff+"");
properties.setProperty(prefix+"filterInputFirstLast",filterInputFirstLast+"");
properties.setProperty(prefix+"filterInputTooFar",filterInputTooFar+"");
properties.setProperty(prefix+"filterInpuFarRatio",filterInpuFarRatio+"");
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]+"");
...@@ -223,6 +313,18 @@ public class FocusingField { ...@@ -223,6 +313,18 @@ public class FocusingField {
sagittalMaster=Boolean.parseBoolean(properties.getProperty(prefix+"sagittalMaster")); sagittalMaster=Boolean.parseBoolean(properties.getProperty(prefix+"sagittalMaster"));
if (properties.getProperty(prefix+"parallelOnly")!=null) if (properties.getProperty(prefix+"parallelOnly")!=null)
parallelOnly=Boolean.parseBoolean(properties.getProperty(prefix+"parallelOnly")); parallelOnly=Boolean.parseBoolean(properties.getProperty(prefix+"parallelOnly"));
if (properties.getProperty(prefix+"filterInput")!=null)
filterInput=Boolean.parseBoolean(properties.getProperty(prefix+"filterInput"));
if (properties.getProperty(prefix+"filterInputMotorDiff")!=null)
filterInputMotorDiff=Double.parseDouble(properties.getProperty(prefix+"filterInputMotorDiff"));
if (properties.getProperty(prefix+"filterInputDiff")!=null)
filterInputDiff=Double.parseDouble(properties.getProperty(prefix+"filterInputDiff"));
if (properties.getProperty(prefix+"filterInputFirstLast")!=null)
filterInputFirstLast=Boolean.parseBoolean(properties.getProperty(prefix+"filterInputFirstLast"));
if (properties.getProperty(prefix+"filterInputTooFar")!=null)
filterInputTooFar=Boolean.parseBoolean(properties.getProperty(prefix+"filterInputTooFar"));
if (properties.getProperty(prefix+"filterInpuFarRatio")!=null)
filterInpuFarRatio=Double.parseDouble(properties.getProperty(prefix+"filterInpuFarRatio"));
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)
...@@ -311,6 +413,8 @@ public static double getPixelMM(){return PIXEL_SIZE;} ...@@ -311,6 +413,8 @@ public static double getPixelMM(){return PIXEL_SIZE;}
public static double getPixelUM(){return PIXEL_SIZE*1000;} public static double getPixelUM(){return PIXEL_SIZE*1000;}
public int flattenIndex(int i, int j){return j+i*sampleCoord[0].length;} public int flattenIndex(int i, int j){return j+i*sampleCoord[0].length;}
public int getNumSamples(){return sampleCoord.length*sampleCoord[0].length;} public int getNumSamples(){return sampleCoord.length*sampleCoord[0].length;}
public int getNumChannels(){return 6;}
public int getSampleWidth(){return sampleCoord[0].length;} public int getSampleWidth(){return sampleCoord[0].length;}
public double [][] flattenSampleCoord(){ public double [][] flattenSampleCoord(){
///sampleCoord ///sampleCoord
...@@ -353,7 +457,7 @@ public class MeasuredSample{ ...@@ -353,7 +457,7 @@ public class MeasuredSample{
this.sampleIndex=sampleIndex; this.sampleIndex=sampleIndex;
} }
} }
public boolean configureDataVector(String title, boolean forcenew){ public boolean configureDataVector(String title, boolean forcenew, boolean enableReset){
if ((fieldFitting == null) && !forcenew){ if ((fieldFitting == null) && !forcenew){
forcenew=true; forcenew=true;
} }
...@@ -363,6 +467,13 @@ public boolean configureDataVector(String title, boolean forcenew){ ...@@ -363,6 +467,13 @@ public boolean configureDataVector(String title, boolean forcenew){
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.addCheckbox("Only use measurements acquired during parallel moves (false - use all)",parallelOnly); gd.addCheckbox("Only use measurements acquired during parallel moves (false - use all)",parallelOnly);
gd.addCheckbox("Remove \"crazy\" input data (samll motor move causing large variations of FWHM)",filterInput);
gd.addNumericField("Maximal motor move to be considered small",filterInputMotorDiff,0,5,"steps (~90um/step)");
gd.addNumericField("Maximal allowed PSF FWHM variations fro the move above",filterInputDiff,3,5,"um");
gd.addCheckbox("Remove first/last in a series of measuremnts separated by small (see above) steps",filterInputFirstLast);
gd.addCheckbox("Remove measurements taken too far from the rest for the same channel/sample",filterInputTooFar);
gd.addNumericField("\"Too far\" ratio to the average distance to the center of measurements",filterInpuFarRatio,3,5,"um");
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 ==="); gd.addMessage("=== Setting minimal measured PSF radius for different colors/directions ===");
...@@ -395,11 +506,28 @@ public boolean configureDataVector(String title, boolean forcenew){ ...@@ -395,11 +506,28 @@ public boolean configureDataVector(String title, boolean forcenew){
gd.addCheckbox("Show/modify disabled for auto-adjustment parameters?",showDisabled); gd.addCheckbox("Show/modify disabled for auto-adjustment parameters?",showDisabled);
gd.addCheckbox("Debug feature: update measurements and /dxc, /dyc if center is being fitted",correct_measurement_ST); gd.addCheckbox("Debug feature: update measurements and /dxc, /dyc if center is being fitted",correct_measurement_ST);
gd.addCheckbox("Debug feature: update sample weights during fitting",updateWeightWhileFitting); gd.addCheckbox("Debug feature: update sample weights during fitting",updateWeightWhileFitting);
if (enableReset) gd.enableYesNoCancel("OK","Reset to defaults, re-open"); // default OK (on enter) - "Apply"
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
parallelOnly=gd.getNextBoolean(); if (!gd.wasOKed()) {
savedProperties=null;
setDefaults();
if (!configureDataVector(title, true,false)) return false;
return true;
}
// boolean configureDataVector(String title, boolean forcenew, boolean moreset)
parallelOnly= gd.getNextBoolean();
filterInput= gd.getNextBoolean();
filterInputMotorDiff= gd.getNextNumber();
filterInputDiff= gd.getNextNumber();
filterInputFirstLast= gd.getNextBoolean();
filterInputTooFar= gd.getNextBoolean();
filterInpuFarRatio= gd.getNextNumber();
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();
...@@ -444,6 +572,144 @@ public boolean configureDataVector(String title, boolean forcenew){ ...@@ -444,6 +572,144 @@ public boolean configureDataVector(String title, boolean forcenew){
return true; return true;
} }
private boolean [] dataWeightsToBoolean(){
boolean [] enable = new boolean [dataVector.length];
for (int i=0;i<enable.length;i++){
enable[i]=dataWeights[i]>0.0;
}
return enable;
}
private void maskDataWeights(boolean [] enable){
for (int i=0;i<enable.length;i++){
if (!enable[i]) dataWeights[i]=0.0;
}
}
private boolean [] filterTooFar(double ratio,boolean [] enable_in){
if (enable_in==null) {
enable_in=new boolean [dataVector.length];
for (int i=0;i<enable_in.length;i++)enable_in[i]=true;
}
boolean [] enable_out=enable_in.clone();
int numFiltered = 0;
double [][][] data=new double [getNumChannels()][getNumSamples()][3];
double [] z_sample=new double [dataVector.length];
for (int chn=0;chn<data.length;chn++)
for (int sample=0;sample<data[chn].length;sample++)
for (int i=0;i<data[chn][sample].length;i++)data[chn][sample][i]=0;
for (int index=0;index<dataVector.length;index++) if ((index>=enable_in.length) ||enable_in[index]){
int chn=dataVector[index].channel;
int sample=dataVector[index].sampleIndex;
double z= fieldFitting.getMotorsZ(
dataVector[index].motors, //int [] motors, // 3 motor coordinates
dataVector[index].px, // double px, // pixel x
dataVector[index].px); // double py)
double w=weightReference[chn]-dataVector[index].value; // maybe use square of w?
data[chn][sample][0]+=w;
data[chn][sample][1]+=w*z;
data[chn][sample][2]+=w*z*z;
z_sample[index]=z;
}
for (int chn=0;chn<data.length;chn++) for (int sample=0;sample<data[chn].length;sample++) {
if (data[chn][sample][0]>0.0) {
double z_av=data[chn][sample][1]/data[chn][sample][0];
double z2 =(data[chn][sample][2]*data[chn][sample][0]-data[chn][sample][1]*data[chn][sample][1])/
(data[chn][sample][0]*data[chn][sample][0]);
data[chn][sample][2]=z2*ratio*ratio; // squared radius
data[chn][sample][1]=z_av; // center z
if (debugLevel>1) System.out.println("filterTooFar(): chn="+chn+", sample="+
sample+", r_av="+IJ.d2s(Math.sqrt(z2),3)+" z_av="+IJ.d2s(z_av,3));
}
}
for (int index=0;index<dataVector.length;index++) if ((index>=enable_in.length) ||enable_in[index]){
int chn=dataVector[index].channel;
int sample=dataVector[index].sampleIndex;
if (data[chn][sample][0]>0.0) {
double diff_z=z_sample[index]-data[chn][sample][1];
if ((diff_z*diff_z > data[chn][sample][2]) && enable_out[index]){
enable_out[index]=false;
numFiltered++;
}
}
}
if (debugLevel>0) System.out.println("filterTooFar(): removed "+numFiltered+" samples");
return enable_out;
}
private boolean [] filterCrazyInput(
boolean [] enable_in, // [meas][cjn][sample] (or null) // can be shorter or longer than dataVector
double maxMotDiff,
double diff,
boolean removeFirstLast // very first, very last in all samples (or after big move) - OK
){
if (enable_in==null) {
enable_in=new boolean [dataVector.length];
for (int i=0;i<enable_in.length;i++)enable_in[i]=true;
}
boolean [] enable_out=enable_in.clone();
// int lastIndex=-1;
int numFiltered=0;
int [][] lastIndex=new int [getNumChannels()][getNumSamples()];
int [][] lastTimestampIndex=new int [getNumChannels()][getNumSamples()];
for (int i=0;i<lastIndex.length;i++) for (int j=0;j<lastIndex[i].length;j++) {
lastIndex[i][j]=-1;
lastTimestampIndex[i][j]=-1;
}
String lastTimestamp=null;
int thisTimestampIndex=0;
int lastIndexAny=-1;
boolean smallMove=false;
// for (int index=0;index<dataVector.length;index++) if ((index>=enable_in.length) ||enable_in[index]){
for (int index=0;index<dataVector.length;index++) { // crazy neighbor still kills even if is ignored itself - needed
int chn=dataVector[index].channel;
int sample=dataVector[index].sampleIndex;
if (lastTimestamp==null) lastTimestamp=dataVector[index].timestamp;
if (!dataVector[index].timestamp.equals(lastTimestamp)){
if (smallMove){ // see if any of the samples/channel did not move last time
for (int i=0;i<lastIndex.length;i++) for (int j=0;j<lastIndex[i].length;j++) {
if ((lastIndex[i][j]>=0) && (lastTimestampIndex[i][j]<thisTimestampIndex)){
if(removeFirstLast){
if (enable_out[lastIndex[i][j]]) numFiltered++;
enable_out[lastIndex[i][j]]=false;
}
lastIndex[i][j]=-1;
}
}
}
smallMove=((Math.abs(dataVector[index].motors[0]-dataVector[lastIndexAny].motors[0]))<=maxMotDiff) &&
((Math.abs(dataVector[index].motors[1]-dataVector[lastIndexAny].motors[1]))<=maxMotDiff) &&
((Math.abs(dataVector[index].motors[2]-dataVector[lastIndexAny].motors[2]))<=maxMotDiff);
thisTimestampIndex++;
}
// is it a first enabled sample after small move?
if (smallMove){
if ((lastIndex[chn][sample]<0) || (lastTimestampIndex[chn][sample]<(thisTimestampIndex-1))){
if (removeFirstLast) {
if (enable_out[index]) numFiltered++;
enable_out[index]=false;
}
} else { // large difference?
if ((Math.abs(dataVector[index].value-dataVector[lastIndex[chn][sample]].value))>=diff){
// yes, remove both this and previous
if (enable_out[lastIndex[chn][sample]]) numFiltered++;
enable_out[lastIndex[chn][sample]]=false;
if (enable_out[index]) numFiltered++;
enable_out[index]=false;
}
}
}
lastIndex[chn][sample]=index;
lastTimestampIndex[chn][sample]=thisTimestampIndex;
lastTimestamp=dataVector[index].timestamp;
lastIndexAny=index;
}
if (debugLevel>0) System.out.println("filterCrazyInput(): removed "+numFiltered+" samples");
return enable_out;
}
private int [] getParallelDiff(MeasuredSample [] vector){ private int [] getParallelDiff(MeasuredSample [] vector){
HashMap<Point,AtomicInteger> map=new HashMap<Point,AtomicInteger>(); HashMap<Point,AtomicInteger> map=new HashMap<Point,AtomicInteger>();
...@@ -468,7 +734,7 @@ private int [] getParallelDiff(MeasuredSample [] vector){ ...@@ -468,7 +734,7 @@ private int [] getParallelDiff(MeasuredSample [] vector){
// 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. vector is already corrected from input data, FWHM psf
if (debugLevel>1) System.out.println("+++++ (Re)calculating sample weights +++++"); if (debugLevel>1) System.out.println("+++++ (Re)calculating sample weights +++++");
int [] diffs=null; int [] diffs=null;
if (parallelOnly) diffs=getParallelDiff(vector); if (parallelOnly) diffs=getParallelDiff(vector);
...@@ -517,6 +783,24 @@ public void setDataVector(MeasuredSample [] vector){ // remove unused channels i ...@@ -517,6 +783,24 @@ public void setDataVector(MeasuredSample [] vector){ // remove unused channels i
dataValues[i+dataVector.length]=0.0; // correction target is always 0 dataValues[i+dataVector.length]=0.0; // correction target is always 0
dataWeights[i+dataVector.length]=1.0; // improve? dataWeights[i+dataVector.length]=1.0; // improve?
} }
if (filterInput){
boolean [] en=dataWeightsToBoolean();
en= filterCrazyInput(
en, // [meas][cjn][sample] (or null) // can be shorter or longer than dataVector
filterInputMotorDiff,
filterInputDiff,
filterInputFirstLast
);
maskDataWeights(en);
}
if (filterInputTooFar){
boolean [] en=dataWeightsToBoolean();
en= filterTooFar(
filterInpuFarRatio,
en);
maskDataWeights(en);
}
} }
// for compatibility with Distortions class\ // for compatibility with Distortions class\
...@@ -570,6 +854,11 @@ public double [] createFXandJacobian(boolean createJacobian){ ...@@ -570,6 +854,11 @@ public double [] createFXandJacobian(boolean createJacobian){
double prevPx=-1,prevPy=-1; double prevPx=-1,prevPy=-1;
for (int n=0;n<dataVector.length;n++){ for (int n=0;n<dataVector.length;n++){
MeasuredSample ms=dataVector[n]; MeasuredSample ms=dataVector[n];
// int saveDebugLevel=debugLevel;
// if (n==9) {
// System.out.println("createFXandJacobian(): n="+n);
// debugLevel=10;
// }
if (!ms.timestamp.equals(prevTimeStamp) || (ms.px!=prevPx) || (ms.py!=prevPy)){ if (!ms.timestamp.equals(prevTimeStamp) || (ms.px!=prevPx) || (ms.py!=prevPy)){
subData=fieldFitting.getValsDerivatives( subData=fieldFitting.getValsDerivatives(
ms.sampleIndex, ms.sampleIndex,
...@@ -582,10 +871,18 @@ public double [] createFXandJacobian(boolean createJacobian){ ...@@ -582,10 +871,18 @@ public double [] createFXandJacobian(boolean createJacobian){
prevPx=ms.px; prevPx=ms.px;
prevPy=ms.py; prevPy=ms.py;
} }
// debugLevel=saveDebugLevel; // restore debugLevel
fx[n]=subData[selChanIndices[ms.channel]]; fx[n]=subData[selChanIndices[ms.channel]];
if (createJacobian) { if (createJacobian) {
double [] thisDerivs=derivs[selChanIndices[ms.channel]]; double [] thisDerivs=derivs[selChanIndices[ms.channel]];
// for (int i=0;i<numRegPars;i++){ // for (int i=0;i<numRegPars;i++){
if ((debugLevel>1) && (debugParameter>=0)){
if ((debugParameter<thisDerivs.length) && (thisDerivs[debugParameter]!=0.0)){
System.out.println("createFXandJacobian(): n="+n+" channel="+ms.channel+" chn. index="+selChanIndices[ms.channel]+
", sample="+ms.sampleIndex+" timestamp="+ms.timestamp+" derivative="+thisDerivs[debugParameter]);
}
}
// contains derivatives for normal and correction parameters // contains derivatives for normal and correction parameters
for (int i=0;i<numPars;i++){ for (int i=0;i<numPars;i++){
...@@ -629,9 +926,53 @@ public double [] createFXandJacobian(boolean createJacobian){ ...@@ -629,9 +926,53 @@ public double [] createFXandJacobian(boolean createJacobian){
} }
} }
} }
if (createJacobian && (debugLevel>1)){
if (debugPoint>=0) debugJacobianPoint(debugPoint);
if (debugParameter>=0) debugJacobianParameter(debugParameter);
}
return fx; return fx;
} }
public void debugJacobianPoint(int nPoint){
System.out.println("==== Non-zero parameters on which point #"+nPoint+" depends:");
if (nPoint>=jacobian[0].length){
System.out.println("Jacobian is defined for "+jacobian[0].length+" points only");
return;
}
for (int i=0;i<jacobian.length;i++){
if (jacobian[i][nPoint]!=0.0){
String name=(debugParameterNames==null)?"":debugParameterNames[i];
System.out.println(i+": "+name+" = "+ jacobian[i][nPoint]);
}
}
}
public void debugJacobianParameter(int nPar){
String name=(debugParameterNames==null)?"":debugParameterNames[nPar];
System.out.println("==== points that depend on parameter #"+nPar+": "+name+" :");
if (nPar>=jacobian.length){
System.out.println("Jacobian is defined for "+jacobian.length+" parameters only");
return;
}
String [] corrNames=fieldFitting.getCorrNames();
for (int i=0;i<jacobian[nPar].length;i++){
if (jacobian[nPar][i]!=0.0){
int nMeasPoints=dataVector.length;
String pointName="";
if (i<nMeasPoints){
pointName="chn"+dataVector[i].channel+":"+dataVector[i].sampleIndex+"__"+dataVector[i].timestamp;
} else {
int overData=i-nMeasPoints;
if ((corrNames!=null) && (overData< corrNames.length)){
pointName="correction_parameter-"+corrNames[overData];
} else {
pointName="unknown-point_+"+overData;
}
}
System.out.println(i+": "+ jacobian[nPar][i]+" "+pointName);
}
}
}
public double getRMS(double [] fx, boolean pure){ public double getRMS(double [] fx, boolean pure){
int len=pure?dataVector.length:fx.length; int len=pure?dataVector.length:fx.length;
double sum=0.0; double sum=0.0;
...@@ -1055,7 +1396,16 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2 ...@@ -1055,7 +1396,16 @@ d_s2/d_x0= 2*delta_x*delta_y^2/r2^2
for (int i=0;i<len;i++){ // for (int i=0;i<len;i++){ //
double diff=this.dataValues[i]-fX[i]; double diff=this.dataValues[i]-fX[i];
result+=diff*diff*this.dataWeights[i]; result+=diff*diff*this.dataWeights[i];
if (debugLevel>2) System.out.println(""+i+"fx="+fX[i]+" data="+this.dataValues[i]+" diff="+diff+" w="+this.dataWeights[i]); if (debugLevel>2) System.out.println(""+i+" fx="+fX[i]+" data="+this.dataValues[i]+" diff="+diff+" w="+this.dataWeights[i]);
if (debugLevel>1){
if (pure) {
int chn=dataVector[i].channel;
int sample=dataVector[i].sampleIndex;
if ((chn==2) && (sample==16)) {
System.out.println(""+i+" fx="+fX[i]+" data="+this.dataValues[i]+" diff="+diff+" w="+this.dataWeights[i]);
}
}
}
sumWeights+=this.dataWeights[i]; sumWeights+=this.dataWeights[i];
} }
if (sumWeights>0) result/=sumWeights; if (sumWeights>0) result/=sumWeights;
...@@ -1329,6 +1679,9 @@ public boolean selectLMAParameters(){ ...@@ -1329,6 +1679,9 @@ public boolean selectLMAParameters(){
// boolean resetCorrections=false; // boolean resetCorrections=false;
GenericDialog gd = new GenericDialog("Levenberg-Marquardt algorithm parameters for cameras distortions/locations"); GenericDialog gd = new GenericDialog("Levenberg-Marquardt algorithm parameters for cameras distortions/locations");
gd.addCheckbox("Debug df/dX0, df/dY0", false); gd.addCheckbox("Debug df/dX0, df/dY0", false);
gd.addNumericField("Debug Jacobian for point number", this.debugPoint, 0, 5,"(-1 - none)");
gd.addNumericField("Debug Jacobian for parameter number", this.debugParameter, 0, 5,"(-1 - none)");
gd.addCheckbox("Keep current correction parameters (do not reset)", this.keepCorrectionParameters); gd.addCheckbox("Keep current correction parameters (do not reset)", this.keepCorrectionParameters);
// gd.addNumericField("Iteration number to start (0.."+(numSeries-1)+")", this.seriesNumber, 0); // gd.addNumericField("Iteration number to start (0.."+(numSeries-1)+")", this.seriesNumber, 0);
gd.addNumericField("Initial LMA Lambda ", this.lambda, 5); gd.addNumericField("Initial LMA Lambda ", this.lambda, 5);
...@@ -1356,6 +1709,10 @@ public boolean selectLMAParameters(){ ...@@ -1356,6 +1709,10 @@ public boolean selectLMAParameters(){
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
this.debugDerivativesFxDxDy=gd.getNextBoolean(); this.debugDerivativesFxDxDy=gd.getNextBoolean();
debugPoint= (int) gd.getNextNumber();
debugParameter= (int) gd.getNextNumber();
this.keepCorrectionParameters = gd.getNextBoolean(); this.keepCorrectionParameters = gd.getNextBoolean();
// this.seriesNumber= (int) gd.getNextNumber(); // this.seriesNumber= (int) gd.getNextNumber();
this.lambda= gd.getNextNumber(); this.lambda= gd.getNextNumber();
...@@ -1511,7 +1868,7 @@ public void listData(String title, ...@@ -1511,7 +1868,7 @@ public void listData(String title,
} }
} }
for (FocusingFieldMeasurement ffm:measurements){ for (FocusingFieldMeasurement ffm:measurements){
double [][][][] samples=ffm.samples; // double [][][][] samples=ffm.samples;
double [][][][] samplesFull=new double [sampleCoord.length][sampleCoord[0].length][numColors][numDirs]; double [][][][] samplesFull=new double [sampleCoord.length][sampleCoord[0].length][numColors][numDirs];
double [][][][] calcSamples=new double [sampleCoord.length][sampleCoord[0].length][numColors][numDirs]; double [][][][] calcSamples=new double [sampleCoord.length][sampleCoord[0].length][numColors][numDirs];
double [][] calcZ= new double [sampleCoord.length][sampleCoord[0].length]; double [][] calcZ= new double [sampleCoord.length][sampleCoord[0].length];
...@@ -1525,7 +1882,19 @@ public void listData(String title, ...@@ -1525,7 +1882,19 @@ public void listData(String title,
calcSamples[i][j][c][d]=Double.NaN; calcSamples[i][j][c][d]=Double.NaN;
} }
} }
//showIgnoredData MeasuredSample [] dataVector
boolean [] enable=dataWeightsToBoolean();
for (int index=0;index<dataVector.length;index++) if (ffm.timestamp.equals(dataVector[index].timestamp) && (showIgnoredData || (index>=enable.length) || enable[index])){
int chn=dataVector[index].channel;
int sample=dataVector[index].sampleIndex;
int sampleRow=sample / sampleCoord[0].length;
int sampleCol=sample % sampleCoord[0].length;
int color = chn / 2;
int dir = chn % 2;
samplesFull[sampleRow][sampleCol][color][dir]=dataVector[index].value;
}
// still needed if showIgnoredData!
/*
if (showMeasCalc[0] && (samples!=null)) for (int i=0;i<sampleCoord.length;i++){ if (showMeasCalc[0] && (samples!=null)) for (int i=0;i<sampleCoord.length;i++){
if ((i<samples.length) && (samples[i]!=null)) for (int j=0;j<sampleCoord[i].length;j++){ if ((i<samples.length) && (samples[i]!=null)) for (int j=0;j<sampleCoord[i].length;j++){
if ((j<samples[i].length) && (samples[i][j]!=null)) for (int c=0;c<numColors;c++){ if ((j<samples[i].length) && (samples[i][j]!=null)) for (int c=0;c<numColors;c++){
...@@ -1583,10 +1952,17 @@ public void listData(String title, ...@@ -1583,10 +1952,17 @@ public void listData(String title,
} }
} }
} }
*/
// Now calculate values for the same samples // Now calculate values for the same samples
if (showMeasCalc[1]){ if (showMeasCalc[1]){
for (int i=0;i<sampleCoord.length;i++) for (int i=0;i<sampleCoord.length;i++)
for (int j=0;j<sampleCoord[0].length;j++) { for (int j=0;j<sampleCoord[0].length;j++) {
if ((i==0) && (j==3) && (ffm.motors[0]==2209)){
System.out.println("listData(), i="+i+", j="+j);
}
double [] subData=fieldFitting.getValsDerivatives( double [] subData=fieldFitting.getValsDerivatives(
flattenIndex(i,j), flattenIndex(i,j),
sagittalMaster, // dependent channel does not have center parameters, but that is only used for derivs. sagittalMaster, // dependent channel does not have center parameters, but that is only used for derivs.
...@@ -1782,27 +2158,87 @@ public void listCombinedResults( ...@@ -1782,27 +2158,87 @@ public void listCombinedResults(
if (show_f_axial || show_f_individual) for (double z=scan_below;z<=scan_above;z+=scan_step){ if (show_f_axial || show_f_individual) for (double z=scan_below;z<=scan_above;z+=scan_step){
if (show_f_axial) { if (show_f_axial) {
for (int i=0;i<show_chn.length;i++){ for (int i=0;i<show_chn.length;i++){
if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z,1); if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z-z0,1);
} }
} }
if (show_f_individual) { if (show_f_individual) {
for (int i=0;i<show_chn.length;i++){ for (int i=0;i<show_chn.length;i++){
if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z,1)+"*"; if (show_chn[i])header+="\t"+chnNames[i]+IJ.d2s(z-z0,1)+"*";
} }
} }
numSect++; numSect++;
} }
double [] radiuses=fieldFitting.getSampleRadiuses(); double [] radiuses0=fieldFitting.getSampleRadiuses();
int numSamples=radiuses0.length;
double [] radiuses=new double [numSamples+1];
radiuses[0]=0.0;
for (int i=0;i<numSamples;i++) radiuses[i+1]=radiuses0[i];
double [][][][] f_values=new double [numSect][2][][]; double [][][][] f_values=new double [numSect][2][][];
double [][][] z_values={
(show_z_axial?fieldFitting.getCalcZ(false,true):null),
(show_z_individual?fieldFitting.getCalcZ(true,true):null)};
int sect=0; int sect=0;
for (double z=scan_below;z<=scan_above;z+=scan_step){ for (double z=scan_below;z<=scan_above;z+=scan_step){
f_values[sect][0]=show_f_axial?fieldFitting.getCalcValuesForZ(z, false,true):null; if (show_f_axial){
f_values[sect][1]=show_f_individual?fieldFitting.getCalcValuesForZ(z, true,true):null; double [][] f=fieldFitting.getCalcValuesForZ(z, false,true);
double [] f0=fieldFitting.getCalcValuesForZ(z, 0.0);
f_values[sect][0]=new double [f.length][];
for (int chn=0;chn<f.length;chn++){
if (f[chn]!=null){
f_values[sect][0][chn]=new double[f[chn].length+1];
f_values[sect][0][chn][0]=f0[chn];
for (int i=0;i<f[chn].length;i++){
f_values[sect][0][chn][i+1]=f[chn][i];
}
} else f_values[sect][0][chn]=null;
}
} else {
f_values[sect][0]=null;
}
if (show_f_individual){
double [][] f=fieldFitting.getCalcValuesForZ(z, true,true);
f_values[sect][1]=new double [f.length][];
for (int chn=0;chn<f.length;chn++){
if (f[chn]!=null){
f_values[sect][1][chn]=new double[f[chn].length+1];
f_values[sect][1][chn][0]=Double.NaN;
for (int i=0;i<f[chn].length;i++){
f_values[sect][1][chn][i+1]=f[chn][i];
}
} else f_values[sect][1][chn]=null;
}
} else {
f_values[sect][1]=null;
}
sect++; sect++;
} }
double [][][] z_values=new double [2][][];
if (show_z_axial){
double [][] zai=fieldFitting.getCalcZ(false,true);
double [] zai0=fieldFitting.getCalcZ(0.0);
z_values[0]=new double [zai.length][];
for (int chn=0;chn<zai.length;chn++){
if (zai[chn]!=null){
z_values[0][chn]=new double[zai[chn].length+1];
z_values[0][chn][0]=zai0[chn];
for (int i=0;i<zai[chn].length;i++){
z_values[0][chn][i+1]=zai[chn][i];
}
} else z_values[0][chn]=null;
}
} else z_values[0] = null;
if (show_z_individual){
double [][] zai=fieldFitting.getCalcZ(true,true);
z_values[1]=new double [zai.length][];
for (int chn=0;chn<zai.length;chn++){
if (zai[chn]!=null){
z_values[1][chn]=new double[zai[chn].length+1];
z_values[1][chn][0]=Double.NaN;
for (int i=0;i<zai[chn].length;i++){
z_values[1][chn][i+1]=zai[chn][i];
}
} else z_values[1][chn]=null;
}
} else z_values[1] = null;
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
for (int n=0;n<radiuses.length;n++){ for (int n=0;n<radiuses.length;n++){
sb.append(IJ.d2s(radiuses[n],3)); sb.append(IJ.d2s(radiuses[n],3));
...@@ -2229,6 +2665,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2229,6 +2665,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double pY0, double pY0,
double [][][] sampleCoord, //){ // x,y,r double [][][] sampleCoord, //){ // x,y,r
AtomicInteger stopRequested){ AtomicInteger stopRequested){
setDefaults();
this.serialNumber=serialNumber; this.serialNumber=serialNumber;
this.lensSerial=lensSerial; this.lensSerial=lensSerial;
this.comment=comment; this.comment=comment;
...@@ -2246,6 +2683,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2246,6 +2683,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
boolean smart, // do not open dialog if default matches boolean smart, // do not open dialog if default matches
String defaultPath, //){ String defaultPath, //){
AtomicInteger stopRequested){ AtomicInteger stopRequested){
setDefaults();
this.stopRequested=stopRequested; this.stopRequested=stopRequested;
loadXML(smart,defaultPath); loadXML(smart,defaultPath);
} }
...@@ -2379,7 +2817,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2379,7 +2817,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
private double [][] sampleCorrCost= new double[6][]; // equivalent cost of one unit of parameter value (in result units, um) private double [][] sampleCorrCost= new double[6][]; // equivalent cost of one unit of parameter value (in result units, um)
private double [][] sampleCorrSigma= new double[6][]; // sigma (in mm) for neighbors influence private double [][] sampleCorrSigma= new double[6][]; // sigma (in mm) for neighbors influence
private double [][] sampleCorrPullZero=new double[6][]; // 1.0 - only difference from neighbors matters, 0.0 - only difference from 0 private double [][] sampleCorrPullZero=new double[6][]; // 1.0 - only difference from neighbors matters, 0.0 - only difference from 0
private double [] sampleCorrRadius=null; // private double [] sampleCorrRadius=null;
private double [][] sampleCoordinates=null;
private double [][][][] sampleCorrCrossWeights= new double[6][][][]; private double [][][][] sampleCorrCrossWeights= new double[6][][][];
private double [] sampleCorrVector=null; // currently adjusted per-sample parameters private double [] sampleCorrVector=null; // currently adjusted per-sample parameters
private double [][][] correctionParameters=new double[6][][]; // all private double [][][] correctionParameters=new double[6][][]; // all
...@@ -2387,9 +2826,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2387,9 +2826,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
private int [][] sampleCorrChnParIndex=null; private int [][] sampleCorrChnParIndex=null;
private boolean [] dflt_sampleCorrSelect= {false,false,false,false}; private boolean [] dflt_sampleCorrSelect= {false,false,false,false};
private double [] dflt_sampleCorrCost= {0.2,50.0,1.0,1.0}; private double [] dflt_sampleCorrCost= {1.0,50.0,1.0,1.0};
private double dflt_sampleCorrSigma= 1.0; // mm private double dflt_sampleCorrSigma= 2.0; // mm
private double dflt_sampleCorrPullZero= 0.25; // fraction private double dflt_sampleCorrPullZero= 0.75; // fraction
public final String [] channelDescriptions={ public final String [] channelDescriptions={
"Red, sagittal","Red, tangential", "Red, sagittal","Red, tangential",
"Green, sagittal","Green, tangential", "Green, sagittal","Green, tangential",
...@@ -2568,13 +3007,28 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2568,13 +3007,28 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
public double [] getSampleRadiuses(){ // distance from the current center to each each sample // public double [] getSampleRadiuses(){ // distance from the current center to each each sample
// return sampleCorrRadius;
// }
public double [] getSampleRadiuses(){
double [] sampleCorrRadius=new double [numberOfLocations];
//pXY
for (int i=0;i<numberOfLocations;i++){
double dx=sampleCoordinates[i][0]-pXY[0];
double dy=sampleCoordinates[i][1]-pXY[1];
sampleCorrRadius[i]=getPixelMM()*Math.sqrt(dx*dx+dy*dy);
}
return sampleCorrRadius; return sampleCorrRadius;
} }
public void showCurvCorr(String title){ public void showCurvCorr(String title){
int width=getSampleWidth(); int width=getSampleWidth();
int numSamples=getNumSamples(); int numSamples=getNumSamples();
String [] chnShortNames={"RS","RT","GS","GT","BRS","BT"}; String [] chnShortNames={"RS","RT","GS","GT","BS","BT"};
int numCorrPar=0; int numCorrPar=0;
int maxNumPars=0; int maxNumPars=0;
for (int chn=0;chn<correctionParameters.length;chn++) for (int chn=0;chn<correctionParameters.length;chn++)
...@@ -2612,6 +3066,23 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2612,6 +3066,23 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
titles); titles);
} }
public double [] getCalcValuesForZ(double z, double r){
double [] result=new double [6];
for (int chn=0;chn<result.length;chn++) {
if (curvatureModel[chn]!=null){
result[chn]=curvatureModel[chn].getFdF(
null,
r, // in mm,
Double.NaN, // py,
z, //mot_z,
null); //deriv_curv[c]);
} else {
result[chn]=Double.NaN;
}
}
return result;
}
/** /**
* Calculate values (sagital and tangential PSF FWHM in um for each of color channels) for specified z * Calculate values (sagital and tangential PSF FWHM in um for each of color channels) for specified z
* @param z distance from lens (from some zero point), image plane is perpendicular to the axis * @param z distance from lens (from some zero point), image plane is perpendicular to the axis
...@@ -2620,12 +3091,17 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2620,12 +3091,17 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
* @return outer dimension - number of channel, inner - number of sample (use getSampleRadiuses for radius of each) * @return outer dimension - number of channel, inner - number of sample (use getSampleRadiuses for radius of each)
*/ */
public double [][] getCalcValuesForZ(double z, boolean corrected, boolean allChannels){ public double [][] getCalcValuesForZ(double z, boolean corrected, boolean allChannels){
double [] sampleCorrRadius=getSampleRadiuses();
int numSamples=sampleCorrRadius.length; int numSamples=sampleCorrRadius.length;
double [][] result=new double [6][]; double [][] result=new double [6][];
for (int chn=0;chn<result.length;chn++) { for (int chn=0;chn<result.length;chn++) {
if ((curvatureModel[chn]!=null) && (allChannels || channelSelect[chn])){ if ((curvatureModel[chn]!=null) && (allChannels || channelSelect[chn])){
result[chn]=new double [numSamples]; result[chn]=new double [numSamples];
for (int sampleIndex=0;sampleIndex<numSamples;sampleIndex++) { for (int sampleIndex=0;sampleIndex<numSamples;sampleIndex++) {
if ((chn==4) && (sampleIndex==3)){
System.out.println("getCalcValuesForZ(), chn="+chn+", sampleIndex="+sampleIndex);
}
result[chn][sampleIndex]=curvatureModel[chn].getFdF( result[chn][sampleIndex]=curvatureModel[chn].getFdF(
corrected?getCorrPar(chn,sampleIndex):null, corrected?getCorrPar(chn,sampleIndex):null,
sampleCorrRadius[sampleIndex], //px, sampleCorrRadius[sampleIndex], //px,
...@@ -2639,6 +3115,19 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2639,6 +3115,19 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
return result; return result;
} }
public double [] getCalcZ(double r){
double [] result=new double [6];
for (int chn=0;chn<result.length;chn++) {
if (curvatureModel[chn]!=null){
result[chn]=curvatureModel[chn].getAr(r, null)[0];
} else {
result[chn]=Double.NaN;
}
}
return result;
}
/** /**
* calculate distance to "best focus" for each channel (color and S/T) for each sample * calculate distance to "best focus" for each channel (color and S/T) for each sample
* @param corrected when false - provide averaged (axial model) for radius, if true - with individual correction applied * @param corrected when false - provide averaged (axial model) for radius, if true - with individual correction applied
...@@ -2646,16 +3135,26 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2646,16 +3135,26 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
* @return outer dimension - number of channel, inner - number of sample (use getSampleRadiuses for radius of each) * @return outer dimension - number of channel, inner - number of sample (use getSampleRadiuses for radius of each)
*/ */
public double [][] getCalcZ(boolean corrected, boolean allChannels){ public double [][] getCalcZ(boolean corrected, boolean allChannels){
double [] sampleCorrRadius=getSampleRadiuses();
int numSamples=sampleCorrRadius.length; int numSamples=sampleCorrRadius.length;
boolean [][] goodSamples=new boolean[getNumChannels()][getNumSamples()];
for (int i=0;i<goodSamples.length;i++) for (int j=0;j<goodSamples[0].length;j++) goodSamples[i][j]=false;
for (int n=0;n<dataVector.length;n++) if (dataWeights[n]>0.0){
goodSamples[dataVector[n].channel][dataVector[n].sampleIndex]=true;
}
double [][] result=new double [6][]; double [][] result=new double [6][];
for (int chn=0;chn<result.length;chn++) { for (int chn=0;chn<result.length;chn++) {
if ((curvatureModel[chn]!=null) && (allChannels || channelSelect[chn])){ if ((curvatureModel[chn]!=null) && (allChannels || channelSelect[chn])){
result[chn]=new double [numSamples]; result[chn]=new double [numSamples];
for (int sampleIndex=0;sampleIndex<numSamples;sampleIndex++) { for (int sampleIndex=0;sampleIndex<numSamples;sampleIndex++) {
if (goodSamples[chn][sampleIndex]) {
result[chn][sampleIndex]=curvatureModel[chn].getAr( result[chn][sampleIndex]=curvatureModel[chn].getAr(
sampleCorrRadius[sampleIndex], sampleCorrRadius[sampleIndex],
corrected?getCorrPar(chn,sampleIndex):null corrected?getCorrPar(chn,sampleIndex):null
)[0]; )[0];
} else {
result[chn][sampleIndex]=Double.NaN;
}
} }
} else { } else {
result[chn]=null; result[chn]=null;
...@@ -2679,21 +3178,45 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2679,21 +3178,45 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
public double [] getQualB(double z, boolean corrected){ public double [] getQualB(double z, boolean corrected){
double [][] data=getCalcValuesForZ(z,corrected, true ); double [][] data=getCalcValuesForZ(z,corrected, true );
double [] qualB = {0.0,0.0,0.0}; double [] qualB = {0.0,0.0,0.0};
double [] sampleCorrRadius=getSampleRadiuses();
int numSamples=sampleCorrRadius.length; int numSamples=sampleCorrRadius.length;
boolean [][] goodSamples=new boolean[getNumChannels()][getNumSamples()];
for (int i=0;i<goodSamples.length;i++) for (int j=0;j<goodSamples[0].length;j++) goodSamples[i][j]=false;
for (int n=0;n<dataVector.length;n++) if (dataWeights[n]>0.0){
goodSamples[dataVector[n].channel][dataVector[n].sampleIndex]=true;
}
for (int c=0;c<3;c++) { for (int c=0;c<3;c++) {
if ((data[2*c]!=null) && (data[2*c+1]!=null)){ if ((data[2*c]!=null) && (data[2*c+1]!=null)){
int nSamp=0;
qualB[c]=0.0; qualB[c]=0.0;
for (int i=0;i<numSamples;i++){ for (int i=0;i<numSamples;i++){
qualB[c]+=data[2*c][i]*data[2*c][i]*data[2*c][i]*data[2*c][i]+ for (int dir=0;dir<2;dir++) {
data[2*c+1][i]*data[2*c+1][i]*data[2*c+1][i]*data[2*c+1][i]; if (goodSamples[2*c+dir][i]){
qualB[c]+=data[2*c+dir][i]*data[2*c+dir][i]*data[2*c+dir][i]*data[2*c+dir][i];
nSamp++;
}
}
}
if (nSamp>0){
qualB[c]/=nSamp;
} }
qualB[c]/=2.0*numSamples;
qualB[c]=Math.sqrt(Math.sqrt(qualB[c])); qualB[c]=Math.sqrt(Math.sqrt(qualB[c]));
} else { } else {
qualB[c]=Double.NaN; qualB[c]=Double.NaN;
} }
} }
//TODO: Move to a separate function
int [] numBad={0,0,0,0,0,0};
boolean hasBad=false;
for (int i=0;i<goodSamples.length;i++) for (int j=0;j<goodSamples[0].length;j++) if (!goodSamples[i][j]){
numBad[i]++;
hasBad=true;
}
if ((debugLevel>0) && hasBad){
for (int i=0;i<numBad.length;i++) if (numBad[i]>0){
System.out.println(numBad[i]+" sample locations are missing data for "+fieldFitting.getDescription(i));
}
}
return qualB; return qualB;
} }
...@@ -2939,6 +3462,35 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2939,6 +3462,35 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
return sampleCorrVector; return sampleCorrVector;
} }
public String [] getCorrNames(){
//numberOfLocations
int numPars=0;
for (int nChn=0; nChn< sampleCorrChnParIndex.length;nChn++) {
if (sampleCorrChnParIndex[nChn]!=null){
for (int nPar=0;nPar< sampleCorrChnParIndex[nChn].length;nPar++) {
if (sampleCorrChnParIndex[nChn][nPar]>=0){
numPars+=numberOfLocations;
}
}
}
}
if (debugLevel>1) System.out.println("getCorrVector 1");
String [] corrNames=new String [numPars];
for (int nChn=0; nChn< sampleCorrChnParIndex.length;nChn++) {
if (sampleCorrChnParIndex[nChn]!=null){
for (int nPar=0;nPar< sampleCorrChnParIndex[nChn].length;nPar++) {
if (sampleCorrChnParIndex[nChn][nPar]>=0){
for (int i=0;i<numberOfLocations;i++){
corrNames[sampleCorrChnParIndex[nChn][nPar]+i]="chn"+nChn+":"+nPar+"-"+i;
}
}
}
}
}
return corrNames;
}
public void commitCorrVector(){ public void commitCorrVector(){
if (debugLevel>1) System.out.println("commitCorrVector()"); if (debugLevel>1) System.out.println("commitCorrVector()");
commitCorrVector(sampleCorrVector); commitCorrVector(sampleCorrVector);
...@@ -2973,6 +3525,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -2973,6 +3525,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
// once per fitting series (or parameter change // once per fitting series (or parameter change
public void initSampleCorrVector(double [][] sampleCoordinates){ public void initSampleCorrVector(double [][] sampleCoordinates){
numberOfLocations=sampleCoordinates.length; numberOfLocations=sampleCoordinates.length;
this.sampleCoordinates=new double[sampleCoordinates.length][];
for (int i=0;i<sampleCoordinates.length;i++) this.sampleCoordinates[i]=sampleCoordinates[i].clone();
// int numSamples=sampleCoordinates.length; // int numSamples=sampleCoordinates.length;
for (int nChn=0; nChn< sampleCorrSelect.length;nChn++) { for (int nChn=0; nChn< sampleCorrSelect.length;nChn++) {
if (channelSelect[nChn]){ if (channelSelect[nChn]){
...@@ -3034,6 +3588,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3034,6 +3588,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
// 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;
/*
sampleCorrRadius=new double [numberOfLocations]; sampleCorrRadius=new double [numberOfLocations];
//pXY //pXY
for (int i=0;i<numberOfLocations;i++){ for (int i=0;i<numberOfLocations;i++){
...@@ -3041,6 +3596,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3041,6 +3596,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double dy=sampleCoordinates[i][1]-pXY[0]; double dy=sampleCoordinates[i][1]-pXY[0];
sampleCorrRadius[i]=getPixelMM()*Math.sqrt(dx*dx+dy*dy); sampleCorrRadius[i]=getPixelMM()*Math.sqrt(dx*dx+dy*dy);
} }
*/
} }
public double [] getCorrPar(int chn, int sampleIndex){ public double [] getCorrPar(int chn, int sampleIndex){
...@@ -3145,7 +3701,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3145,7 +3701,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
gd.addCheckbox("Setup correction parameters when the parameter itself is disabled", disabledCorrectionPars); gd.addCheckbox("Setup correction parameters when the parameter itself is disabled", disabledCorrectionPars);
// gd.enableYesNoCancel("Keep","Apply"); // default OK (on enter) - "Keep" // gd.enableYesNoCancel("Keep","Apply"); // default OK (on enter) - "Keep"
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
centerSelect[0]=gd.getNextBoolean(); centerSelect[0]=gd.getNextBoolean();
...@@ -3160,7 +3716,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3160,7 +3716,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
setupCorrectionPars=gd.getNextBoolean(); setupCorrectionPars=gd.getNextBoolean();
commonCorrectionPars=gd.getNextBoolean(); commonCorrectionPars=gd.getNextBoolean();
disabledCorrectionPars=gd.getNextBoolean(); disabledCorrectionPars=gd.getNextBoolean();
// boolean OK; // boolean OK;
if (editMechMask){ if (editMechMask){
boolean [] mask=mechanicalFocusingModel.maskSetDialog("Focusing mechanical parameters mask", mechanicalSelect); boolean [] mask=mechanicalFocusingModel.maskSetDialog("Focusing mechanical parameters mask", mechanicalSelect);
if (mask!=null) mechanicalSelect=mask; if (mask!=null) mechanicalSelect=mask;
...@@ -3176,7 +3732,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3176,7 +3732,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
} }
mask=curvatureModel[0].maskSetDialog( mask=curvatureModel[0].maskSetDialog(
"Parameter mask for all curvature model channels (colors,S/T)", "All channels mask for all curvature models (colors,S/T)",
detailedCurvMask, detailedCurvMask,
mask); mask);
if (mask==null) return false; // canceled if (mask==null) return false; // canceled
...@@ -3189,7 +3745,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3189,7 +3745,8 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
for (int i=0;i<channelSelect.length;i++) if (channelSelect[i]){ for (int i=0;i<channelSelect.length;i++) if (channelSelect[i]){
boolean [] mask=curvatureSelect[i]; boolean [] mask=curvatureSelect[i];
mask=curvatureModel[0].maskSetDialog( mask=curvatureModel[0].maskSetDialog(
"Parameter mask for curvature model, channel \""+getDescription(i)+"\"", // "Parameter mask for curvature model, channel \""+getDescription(i)+"\"",
"Channel \""+getDescription(i)+"\" parameter mask for curvature model",
detailedCurvMask, detailedCurvMask,
mask); mask);
if (mask==null) return false; // canceled if (mask==null) return false; // canceled
...@@ -3201,12 +3758,13 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3201,12 +3758,13 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
if (!setupSampleCorr("Setup per-sample correction parameters", if (!setupSampleCorr("Setup per-sample correction parameters",
!commonCorrectionPars, !commonCorrectionPars,
disabledCorrectionPars)) return false; disabledCorrectionPars)) return false;
// initSampleCorr(flattenSampleCoord()); // initSampleCorr(flattenSampleCoord());
} }
// will modify // will modify
initSampleCorrVector(flattenSampleCoord()); // run always regardless of configured or not (to create zero-length array of corr) initSampleCorrVector(flattenSampleCoord()); // run always regardless of configured or not (to create zero-length array of corr)
return true; return true;
} }
ArrayList<String> getParameterValueStrings(boolean showDisabled, boolean showCorrection){ ArrayList<String> getParameterValueStrings(boolean showDisabled, boolean showCorrection){
ArrayList<String> parList=new ArrayList<String>(); ArrayList<String> parList=new ArrayList<String>();
parList.add("\t ===== Aberrations center =====\t\t"); parList.add("\t ===== Aberrations center =====\t\t");
...@@ -3393,20 +3951,29 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3393,20 +3951,29 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
* @return vector of the current selected parameters values * @return vector of the current selected parameters values
*/ */
public double [] createParameterVector(boolean sagittalMaster){ public double [] createParameterVector(boolean sagittalMaster){
int debugThreshold=0;
double [] pars = new double [getNumberOfParameters(sagittalMaster)]; double [] pars = new double [getNumberOfParameters(sagittalMaster)];
int np=0; int np=0;
if (debugLevel>debugThreshold) debugParameterNames=new String [pars.length];
for (int i=0;i<2;i++){ for (int i=0;i<2;i++){
if ( centerSelect[i]) pars[np++]=pXY[i]; if ( centerSelect[i]) {
if (debugLevel>debugThreshold) debugParameterNames[np]="pXY"+i;
pars[np++]=pXY[i];
}
} }
for (int i=0;i<mechanicalFocusingModel.paramValues.length;i++){ for (int i=0;i<mechanicalFocusingModel.paramValues.length;i++){
if ((mechanicalSelect==null) || mechanicalSelect[i] ) pars[np++]=mechanicalFocusingModel.paramValues[i]; if ((mechanicalSelect==null) || mechanicalSelect[i] ) {
if (debugLevel>debugThreshold) debugParameterNames[np]=mechanicalFocusingModel.getName(i);
pars[np++]=mechanicalFocusingModel.paramValues[i];
}
} }
for (int n=0;n<channelSelect.length;n++) if (channelSelect[n]){ for (int n=0;n<channelSelect.length;n++) if (channelSelect[n]){
boolean isMasterDir=(n%2) == (sagittalMaster?0:1); boolean isMasterDir=(n%2) == (sagittalMaster?0:1);
int index=0; int index=0;
for (int i=0;i<curvatureModel[n].modelParams.length;i++) for (int j=0;j<curvatureModel[n].modelParams[0].length;j++){ for (int i=0;i<curvatureModel[n].modelParams.length;i++) for (int j=0;j<curvatureModel[n].modelParams[0].length;j++){
if ((isMasterDir || (j!=0)) && ((curvatureSelect[n]==null) || curvatureSelect[n][index] )) { if ((isMasterDir || (j!=0)) && ((curvatureSelect[n]==null) || curvatureSelect[n][index] )) {
if (debugLevel>debugThreshold) debugParameterNames[np]="chn"+n+"-"+curvatureModel[n].getZName(i)+":"+curvatureModel[n].getRadialName(j);
pars[np++]=curvatureModel[n].modelParams[i][j]; pars[np++]=curvatureModel[n].modelParams[i][j];
} }
index++; index++;
...@@ -3415,7 +3982,16 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3415,7 +3982,16 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
if (debugLevel>1) 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]; String [] corrNames=(debugLevel>debugThreshold)?getCorrNames():null;
for (int i=0;i<nCorrPars;i++) {
if (debugLevel>debugThreshold) debugParameterNames[np]="corr_par-"+corrNames[i];
pars[np++]=sampleCorrVector[i];
}
if (debugLevel>1){
for (int i=0;i<pars.length;i++){
System.out.println(i+" "+debugParameterNames[i]+" = "+pars[i]);
}
}
return pars; return pars;
} }
...@@ -3570,6 +4146,12 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3570,6 +4146,12 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
} }
} }
if (debugLevel==10){
System.out.println("getValsDerivatives(), #="+np+" (of "+deriv[nChn].length+ ")");
for (int ii=0;ii<np;ii++) if (deriv[nChn][ii]!=0.0){
System.out.println("getValsDerivatives(), #="+ii+" (of "+deriv[nChn].length+ ") c="+c+" nChn="+nChn+" deriv="+deriv[nChn][ii]);
}
}
// add correction parameters? // add correction parameters?
// now np points to the first correction parameter // now np points to the first correction parameter
// correction parameters do not depend on sagittalMaster - each mayy have own shift // correction parameters do not depend on sagittalMaster - each mayy have own shift
...@@ -3578,7 +4160,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3578,7 +4160,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
int [] ncp=curvatureModel[n].getNumPars(); // {(z),(r)} int [] ncp=curvatureModel[n].getNumPars(); // {(z),(r)}
for (int i=0;i<ncp[0];i++) if (sampleCorrChnParIndex[n][i]>=0){ for (int i=0;i<ncp[0];i++) if (sampleCorrChnParIndex[n][i]>=0){
// np now points to the first corr parameter // np now points to the first corr parameter
deriv[nChn][np+sampleCorrChnParIndex[n][i]+sampleIndex]=deriv_curv[n][i*ncp[1]]; deriv[nChn][np+sampleCorrChnParIndex[n][i]+sampleIndex]=(nChn==n)?deriv_curv[n][i*ncp[1]]:0.0;
} }
} }
} }
...@@ -3662,7 +4244,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3662,7 +4244,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
} }
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
if (paramValues==null) { if (paramValues!=null) {
for (int i=0;i<paramValues.length;i++){ for (int i=0;i<paramValues.length;i++){
properties.setProperty(prefix+descriptions[i][0],paramValues[i]+""); properties.setProperty(prefix+descriptions[i][0],paramValues[i]+"");
} }
...@@ -3702,6 +4284,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3702,6 +4284,9 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
public String getDescription(int i){ public String getDescription(int i){
return descriptions[i][1]; return descriptions[i][1];
} }
public String getName(int i){
return descriptions[i][0];
}
public String getDescription(MECH_PAR mech_par){ public String getDescription(MECH_PAR mech_par){
return descriptions[mech_par.ordinal()][1]; return descriptions[mech_par.ordinal()][1];
} }
...@@ -3772,7 +4357,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3772,7 +4357,7 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double py, double py,
double[] deriv){ double[] deriv){
double debugMot=6545; double debugMot=6545;
int debugThreshold=1; int debugThreshold=2;
boolean dbg = (debugLevel>debugThreshold); boolean dbg = (debugLevel>debugThreshold);
/* /*
kM3=K0+KD3 kM3=K0+KD3
...@@ -3869,21 +4454,21 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){ ...@@ -3869,21 +4454,21 @@ public boolean LevenbergMarquardt(boolean openDialog, int debugLevel){
double zx_cM2= (-zM2_cM2)*zx_a; double zx_cM2= (-zM2_cM2)*zx_a;
double zx_sM3= (2*zM3_sM3)*zx_a; double zx_sM3= (2*zM3_sM3)*zx_a;
double zx_cM3= (2*zM3_cM3)*zx_a; double zx_cM3= (2*zM3_cM3)*zx_a;
double zx_mpX0=dx_mpX0/(4*getValue(MECH_PAR.Lx)); double zx_mpX0=dx_mpX0*(getValue(MECH_PAR.tx)+(2*zM3-zM1-zM2)/(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=dy*(getValue(MECH_PAR.ty)+(zM2-zM1)/(2*getValue(MECH_PAR.Ly)));
double zy_a=dy/(2*getValue(MECH_PAR.Ly)); double zy_a=dy/(2*getValue(MECH_PAR.Ly));
double zy_K0= (zM2_K0- zM1_K0) *zy_a; // double zy_K0= (zM1_K0- zM2_K0) *zy_a; double zy_K0= (zM2_K0- zM1_K0) *zy_a;
double zy_KD1= (zM2_KD1-zM1_KD1)*zy_a; // double zy_KD1= (zM2_KD1-zM1_KD1)*zy_a; double zy_KD1= (zM2_KD1-zM1_KD1)*zy_a;
double zy_KD3= (zM2_KD3-zM1_KD3)*zy_a; // double zy_KD3= (zM1_KD3-zM2_KD3)*zy_a; double zy_KD3= (zM2_KD3-zM1_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*(getValue(MECH_PAR.ty)+(zM2-zM1)/(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)); double zy_Ly= -dy*(zM2-zM1)/(2*getValue(MECH_PAR.Ly)*getValue(MECH_PAR.Ly));
......
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