Commit 4ffb8a32 authored by Andrey Filippov's avatar Andrey Filippov

working on calculating grids for low frequency pattern

parent 78aea970
...@@ -1413,9 +1413,13 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970 ...@@ -1413,9 +1413,13 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*"); NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) { for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName(); String name= allNodes.item(i).getNodeName();
String value=allNodes.item(i).getFirstChild().getNodeValue(); String value="";
imp.setProperty(name, value); try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch(Exception e) {
}
imp.setProperty(name, value);
} }
return true; return true;
......
...@@ -70,6 +70,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -70,6 +70,7 @@ import com.elphel.imagej.common.WindowTools;
import com.elphel.imagej.jp4.JP46_Reader_camera; import com.elphel.imagej.jp4.JP46_Reader_camera;
import com.elphel.imagej.lwir.LwirReader; import com.elphel.imagej.lwir.LwirReader;
import com.elphel.imagej.lwir.LwirReaderParameters; import com.elphel.imagej.lwir.LwirReaderParameters;
import com.elphel.imagej.readers.EyesisTiff;
import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/ import Jama.Matrix; // Download here: http://math.nist.gov/javanumerics/jama/
import ij.IJ; import ij.IJ;
...@@ -222,10 +223,20 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene ...@@ -222,10 +223,20 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
0.4, // corrRingWidth - ring (around r=0.5 dist to opposite corr) width , center circle r=0.5*PATTERN_DETECT.corrRingWidth 0.4, // corrRingWidth - ring (around r=0.5 dist to opposite corr) width , center circle r=0.5*PATTERN_DETECT.corrRingWidth
5.0, // minCorrContrast - discrimination threshold between good and bad pattern correlation 5.0, // minCorrContrast - discrimination threshold between good and bad pattern correlation
0.0, // minGridPeriod 0.0, // minGridPeriod
0.0, // maxGridPeriod 0.0, // maxGridPeriod
0.0, // minGridPeriodLwir
0.0, // maxGridPeriodLwir
0.0, // debugX+""); 0.0, // debugX+"");
0.0, // debugY+""); 0.0, // debugY+"");
-1.0 // this.debugRadius+""); -1.0, // this.debugRadius+"");
false, // public boolean use_large_cells = false; // new method based on phase correlation should work with large cells,
// so only first negative correlation (1/2 period) fits in window
0.5, // public double phaseCoeff = 0.5; // "phasiness" of correlation
0.3, // public double lowpass_sigma = 0.3; // for phase correlation - frequency fraction of maximal
0.03, // public double min_frac = 0.03; // do not use higher order autocorrelation if min/max
// is weaker than this fraction of the zero maximum
0.5, //public double min_sin = 0.5; // minimal sine for the angle between two pattern vectors
true //public boolean no_crazy = true; // fail if quadratic approximation fails or returns outside of +/- 1.5
); );
...@@ -674,11 +685,11 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -674,11 +685,11 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
panelConf1 = new Panel(); panelConf1 = new Panel();
panelConf1.setLayout(new GridLayout(1, 0, 5, 5)); panelConf1.setLayout(new GridLayout(1, 0, 5, 5));
addButton("Configure Globals",panelConf1); addButton("Configure Globals", panelConf1,color_configure);
addButton("Conf. Components",panelConf1); addButton("Conf. Components", panelConf1,color_configure);
addButton("Conf. Multifile",panelConf1,color_configure); addButton("Conf. Multifile", panelConf1,color_configure);
addButton("Conf. Simulation",panelConf1); addButton("Conf. Simulation", panelConf1,color_configure);
addButton("Conf. Pattern Detection",panelConf1); addButton("Conf. Pattern Detection",panelConf1,color_configure);
addButton("Waves",panelConf1); addButton("Waves",panelConf1);
//WavePatternGenerator //WavePatternGenerator
add(panelConf1); add(panelConf1);
...@@ -994,6 +1005,8 @@ if (MORE_BUTTONS) { ...@@ -994,6 +1005,8 @@ if (MORE_BUTTONS) {
addButton("Configure Goniometer", panelLWIR,color_configure); addButton("Configure Goniometer", panelLWIR,color_configure);
addButton("Goniometer Move", panelLWIR,color_debug); addButton("Goniometer Move", panelLWIR,color_debug);
addButton("LWIR Goniometer", panelLWIR,color_conf_process); addButton("LWIR Goniometer", panelLWIR,color_conf_process);
addButton("LWIR grids", panelLWIR,color_process);
add(panelLWIR); add(panelLWIR);
pack(); pack();
...@@ -1141,7 +1154,7 @@ if (MORE_BUTTONS) { ...@@ -1141,7 +1154,7 @@ if (MORE_BUTTONS) {
return; return;
/* ======================================================================== */ /* ======================================================================== */
} else if (label.equals("Conf. Pattern Detection")) { } else if (label.equals("Conf. Pattern Detection")) {
showPatternDetectParametersDialog(PATTERN_DETECT); showPatternDetectParametersDialog(PATTERN_DETECT, (LWIR_READER != null));
return; return;
/* ======================================================================== */ /* ======================================================================== */
} else if (label.equals("Waves")) { } else if (label.equals("Waves")) {
...@@ -1404,6 +1417,8 @@ if (MORE_BUTTONS) { ...@@ -1404,6 +1417,8 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.calculateDistortions( matchSimulatedPattern.calculateDistortions(
DISTORTION, // DISTORTION, //
PATTERN_DETECT, PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL, SIMUL,
COMPONENTS.equalizeGreens, COMPONENTS.equalizeGreens,
imp_sel, imp_sel,
...@@ -1800,6 +1815,8 @@ if (MORE_BUTTONS) { ...@@ -1800,6 +1815,8 @@ if (MORE_BUTTONS) {
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions( int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
DISTORTION, // DISTORTION, //
PATTERN_DETECT, PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL, SIMUL,
COMPONENTS.equalizeGreens, COMPONENTS.equalizeGreens,
imp_sel, imp_sel,
...@@ -2567,113 +2584,7 @@ if (MORE_BUTTONS) { ...@@ -2567,113 +2584,7 @@ if (MORE_BUTTONS) {
IJ.showMessage("Laser pointer data needed for this function is not provided"); IJ.showMessage("Laser pointer data needed for this function is not provided");
return; return;
} }
long startTime=System.nanoTime(); calculateGrids();
boolean noMessageBoxes=true;
String prefix="grid-";
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
DISTORTION_PROCESS_CONFIGURATION.debugLevel=MASTER_DEBUG_LEVEL;
if (matchSimulatedPattern==null) matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
String [] sourceFilesList=DISTORTION_PROCESS_CONFIGURATION.selectSourceFiles(); // select files - with/without dialog
boolean saveGrids=DISTORTION_PROCESS_CONFIGURATION.saveGridImages;
boolean overwriteGrids=DISTORTION_PROCESS_CONFIGURATION.overwriteResultFiles;
if (sourceFilesList==null) return;
showPatternMinMaxPeriodDialog(PATTERN_DETECT);
for (int numFile=0;numFile<sourceFilesList.length;numFile++){
long startFileTime=System.nanoTime();
if (DEBUG_LEVEL>0){
System.out.println(IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+"s: Processing file # "+(numFile+1)+ " (of "+ sourceFilesList.length+"): "+sourceFilesList[numFile]);
}
if (saveGrids && !overwriteGrids){ // check if result already exists
int i = sourceFilesList[numFile].lastIndexOf('/');
if (i>0){
String path=prefix+sourceFilesList[numFile].substring(i+1);
String srcDir=DISTORTION_PROCESS_CONFIGURATION.selectGridFileDirectory(true,DISTORTION_PROCESS_CONFIGURATION.gridDirectory,true);
if (srcDir==null){
saveGrids=false; // do not ask about the next ones too
} else {
path=DISTORTION_PROCESS_CONFIGURATION.gridDirectory+Prefs.getFileSeparator()+path;
// File rsltFile=new File(path);
if ((new File(path)).exists()){
if (DEBUG_LEVEL>0) System.out.println("-->>> Skipping existing "+path+" (as requested in \"Configure Process Distortions\")");
continue;
}
}
}
}
imp_sel=new ImagePlus(sourceFilesList[numFile]); // read source file
JP4_INSTANCE.decodeProperiesFromInfo(imp_sel);
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // TODO: is it needed each time?
if (!DISTORTION_PROCESS_CONFIGURATION.useNoPonters && (matchSimulatedPattern.getPointersXY(imp_sel,LASER_POINTERS.laserUVMap.length)==null)) {
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
continue; // no pointers in this image
}
// /getPointersXY(ImagePlus imp, int numPointers){ if
// calculate distortion grid for it
matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPattern.invalidateFocusMask();
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
LASER_POINTERS, // LaserPointer laserPointer, // LaserPointer object or null
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, //
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // allowed mismatch (fraction of period) or 0 - orientation only
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level, // debug level
noMessageBoxes);
if (DEBUG_LEVEL>1) System.out.println("numAbsolutePoints="+numAbsolutePoints);
if ((numAbsolutePoints==DISTORTION.errPatternNotFound) || (numAbsolutePoints==DISTORTION.errTooFewCells)) {
if (DEBUG_LEVEL>0) System.out.println("Grid "+(numFile+1)+" not found or too small ("+numAbsolutePoints+"), wasted "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+" seconds )\n");
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
continue; // too few cells detected
}
if (DISTORTION_PROCESS_CONFIGURATION.useNoPonters || (numAbsolutePoints>0)){
//Calculate grid contrast and brightness for each color component
matchSimulatedPattern.calcGridIntensities (
DISTORTION, //final DistortionParameters distortionParameters, //
COMPONENTS.equalizeGreens,
imp_sel, // image to process
THREADS_MAX);
ImagePlus imp_calibrated=matchSimulatedPattern.getCalibratedPatternAsImage(imp_sel,prefix, numAbsolutePoints);
if (DISTORTION_PROCESS_CONFIGURATION.showGridImages) imp_calibrated.show();
if (saveGrids){
FileSaver fs=new FileSaver(imp_calibrated);
String srcDir=DISTORTION_PROCESS_CONFIGURATION.selectGridFileDirectory(true,DISTORTION_PROCESS_CONFIGURATION.gridDirectory,true);
if (srcDir==null){
saveGrids=false; // do not ask about the next ones too
} else {
String path=DISTORTION_PROCESS_CONFIGURATION.gridDirectory+Prefs.getFileSeparator()+imp_calibrated.getTitle();
if (UPDATE_STATUS) IJ.showStatus("Saving "+path);
if (DEBUG_LEVEL>0) System.out.println("-->>> Saving "+path+" - using "+numAbsolutePoints+" laser pointer references");
fs.saveAsTiffStack(path);
}
}
}
if (DEBUG_LEVEL>0) System.out.println("Grid "+(numFile+1)+" calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" (in "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+"s )\n");
//
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
}
if (DEBUG_LEVEL>0) System.out.println(((this.SYNC_COMMAND.stopRequested.get()>0)?"Partial (interrupted by user) set of grids":"All")+ " grids calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return; return;
} }
/* ======================================================================== */ /* ======================================================================== */
...@@ -9506,6 +9417,15 @@ if (MORE_BUTTONS) { ...@@ -9506,6 +9417,15 @@ if (MORE_BUTTONS) {
/// POWER_CONTROL.lightsOff(); /// POWER_CONTROL.lightsOff();
return; return;
} }
/* ======================================================================== */
if (label.equals("LWIR grids")) {
// if ((LASER_POINTERS==null) || (LASER_POINTERS.laserUVMap.length==0)){
// IJ.showMessage("Laser pointer data needed for this function is not provided");
// return;
// }
calculateLwirGrids();
return;
}
...@@ -9522,7 +9442,250 @@ if (MORE_BUTTONS) { ...@@ -9522,7 +9442,250 @@ if (MORE_BUTTONS) {
/* ======================================================================== */ /* ======================================================================== */
/* ======================================================================== */ /* ======================================================================== */
public void calculateLwirGrids() {
long startTime=System.nanoTime();
boolean noMessageBoxes=true;
String prefix="grid-";
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
DISTORTION_PROCESS_CONFIGURATION.debugLevel=MASTER_DEBUG_LEVEL;
if (matchSimulatedPattern==null) matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
String [] sourceSetList = DISTORTION_PROCESS_CONFIGURATION.selectSourceSets();
LWIR_PARAMETERS.selectSourceChannels();
boolean [] sel_chn = LWIR_PARAMETERS.getSelectedVnir(); // start with regular cameras only
int numFiles = LWIR_PARAMETERS.getSourceFilesFlat(sourceSetList, sel_chn).length; // just the number
String [][] sourceFilesList=LWIR_PARAMETERS.getSourceFiles(sourceSetList, sel_chn);
// String [] sourceFilesList=DISTORTION_PROCESS_CONFIGURATION.selectSourceFiles(); // select files - with/without dialog
boolean saveGrids=DISTORTION_PROCESS_CONFIGURATION.saveGridImages;
boolean overwriteGrids=DISTORTION_PROCESS_CONFIGURATION.overwriteResultFiles;
if (sourceSetList==null) return;
showPatternMinMaxPeriodDialog(PATTERN_DETECT, true);
int this_file = 0;
// if (DEBUG_LEVEL <100) return;
String gridDir=DISTORTION_PROCESS_CONFIGURATION.selectGridFileDirectory(
true,DISTORTION_PROCESS_CONFIGURATION.gridDirectory,true);
if (gridDir == null) saveGrids=false; // do not ask about the next ones too
for (int nset = 0; nset < sourceFilesList.length; nset++){
String set_name = sourceSetList[nset];
int i = set_name.lastIndexOf(Prefs.getFileSeparator());
if (i >=0) set_name = set_name.substring (set_name.lastIndexOf(Prefs.getFileSeparator())+1);
// create directory if it does not exist yet
String gridSetPath = null;
if (saveGrids) {
gridSetPath = gridDir + Prefs.getFileSeparator() + set_name;
File set_dir = new File(gridSetPath);
if (!set_dir.exists()) {
set_dir.mkdirs(); // including parent
}
}
for (int nfile = 0; nfile < sourceFilesList[nset].length; nfile++) if (sourceFilesList[nset][nfile] != null){
long startFileTime=System.nanoTime();
if (DEBUG_LEVEL>0){
System.out.println(IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+"s: Processing file # "+(this_file+1)+
" (of "+ sourceFilesList.length+"): " + numFiles);
}
if (saveGrids && !overwriteGrids){ // check if result already exists
i = sourceFilesList[nset][nfile].lastIndexOf('/');
if (i>0){
String grid_name = prefix+sourceFilesList[nset][nfile].substring(i+1);
String grid_path = gridSetPath + Prefs.getFileSeparator() + grid_name;
if ((new File(grid_path)).exists()){
if (DEBUG_LEVEL>0) System.out.println("-->>> Skipping existing "+grid_path+" (as requested in \"Configure Process Distortions\")");
continue;
}
}
}
imp_sel=new ImagePlus(sourceFilesList[nset][nfile]); // read source file
EyesisTiff.decodeProperiesFromInfo(imp_sel);
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // TODO: is it needed each time?
matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPattern.invalidateFocusMask();
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
null, // LASER_POINTERS, // LaserPointer laserPointer, // LaserPointer object or null
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, //
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // allowed mismatch (fraction of period) or 0 - orientation only
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level, // debug level
noMessageBoxes);
if (DEBUG_LEVEL>1) System.out.println("numAbsolutePoints="+numAbsolutePoints);
if ((numAbsolutePoints==DISTORTION.errPatternNotFound) || (numAbsolutePoints==DISTORTION.errTooFewCells)) {
if (DEBUG_LEVEL>0) System.out.println("Grid "+(this_file+1)+" not found or too small ("+numAbsolutePoints+"), wasted "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+" seconds )\n");
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
continue; // too few cells detected
}
if (DISTORTION_PROCESS_CONFIGURATION.useNoPonters || (numAbsolutePoints>0)){
//Calculate grid contrast and brightness for each color component
matchSimulatedPattern.calcGridIntensities (
DISTORTION, //final DistortionParameters distortionParameters, //
COMPONENTS.equalizeGreens,
imp_sel, // image to process
THREADS_MAX);
ImagePlus imp_calibrated=matchSimulatedPattern.getCalibratedPatternAsImage(imp_sel,prefix, numAbsolutePoints);
if (DISTORTION_PROCESS_CONFIGURATION.showGridImages) imp_calibrated.show();
if (saveGrids){
FileSaver fs=new FileSaver(imp_calibrated);
String srcDir=DISTORTION_PROCESS_CONFIGURATION.selectGridFileDirectory(true,DISTORTION_PROCESS_CONFIGURATION.gridDirectory,true);
if (srcDir==null){
saveGrids=false; // do not ask about the next ones too
} else {
String path=DISTORTION_PROCESS_CONFIGURATION.gridDirectory+Prefs.getFileSeparator()+imp_calibrated.getTitle();
if (UPDATE_STATUS) IJ.showStatus("Saving "+path);
if (DEBUG_LEVEL>0) System.out.println("-->>> Saving "+path+" - using "+numAbsolutePoints+" laser pointer references");
fs.saveAsTiffStack(path);
}
}
}
if (DEBUG_LEVEL>0) System.out.println("Grid "+(this_file+1)+" calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" (in "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+"s )\n");
//
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
this_file++;
}
}
if (DEBUG_LEVEL>0) System.out.println(((this.SYNC_COMMAND.stopRequested.get()>0)?"Partial (interrupted by user) set of grids":"All")+ " grids calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return;
}
/* ======================================================================== */ /* ======================================================================== */
public void calculateGrids() {
long startTime=System.nanoTime();
boolean noMessageBoxes=true;
String prefix="grid-";
DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
DISTORTION_PROCESS_CONFIGURATION.debugLevel=MASTER_DEBUG_LEVEL;
if (matchSimulatedPattern==null) matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
matchSimulatedPattern.debugLevel=MASTER_DEBUG_LEVEL;
String [] sourceFilesList=DISTORTION_PROCESS_CONFIGURATION.selectSourceFiles(); // select files - with/without dialog
boolean saveGrids=DISTORTION_PROCESS_CONFIGURATION.saveGridImages;
boolean overwriteGrids=DISTORTION_PROCESS_CONFIGURATION.overwriteResultFiles;
if (sourceFilesList==null) return;
showPatternMinMaxPeriodDialog(PATTERN_DETECT,false);
for (int numFile=0;numFile<sourceFilesList.length;numFile++){
long startFileTime=System.nanoTime();
if (DEBUG_LEVEL>0){
System.out.println(IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+"s: Processing file # "+(numFile+1)+ " (of "+ sourceFilesList.length+"): "+sourceFilesList[numFile]);
}
if (saveGrids && !overwriteGrids){ // check if result already exists
int i = sourceFilesList[numFile].lastIndexOf('/');
if (i>0){
String path=prefix+sourceFilesList[numFile].substring(i+1);
String srcDir=DISTORTION_PROCESS_CONFIGURATION.selectGridFileDirectory(true,DISTORTION_PROCESS_CONFIGURATION.gridDirectory,true);
if (srcDir==null){
saveGrids=false; // do not ask about the next ones too
} else {
path=DISTORTION_PROCESS_CONFIGURATION.gridDirectory+Prefs.getFileSeparator()+path;
// File rsltFile=new File(path);
if ((new File(path)).exists()){
if (DEBUG_LEVEL>0) System.out.println("-->>> Skipping existing "+path+" (as requested in \"Configure Process Distortions\")");
continue;
}
}
}
}
imp_sel=new ImagePlus(sourceFilesList[numFile]); // read source file
JP4_INSTANCE.decodeProperiesFromInfo(imp_sel);
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); // TODO: is it needed each time?
if (!DISTORTION_PROCESS_CONFIGURATION.useNoPonters && (matchSimulatedPattern.getPointersXY(imp_sel,LASER_POINTERS.laserUVMap.length)==null)) {
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
continue; // no pointers in this image
}
// /getPointersXY(ImagePlus imp, int numPointers){ if
// calculate distortion grid for it
matchSimulatedPattern.invalidateFlatFieldForGrid(); //Reset Flat Field calibration - different image.
matchSimulatedPattern.invalidateFocusMask();
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
DISTORTION, //
PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL,
COMPONENTS.equalizeGreens,
imp_sel,
LASER_POINTERS, // LaserPointer laserPointer, // LaserPointer object or null
DISTORTION_PROCESS_CONFIGURATION.removeOutOfGridPointers, //
null, // double [][][] hintGrid, // predicted grid array (or null)
0, // double hintGridTolerance, // allowed mismatch (fraction of period) or 0 - orientation only
THREADS_MAX,
UPDATE_STATUS,
DEBUG_LEVEL,
DISTORTION.loop_debug_level, // debug level
noMessageBoxes);
if (DEBUG_LEVEL>1) System.out.println("numAbsolutePoints="+numAbsolutePoints);
if ((numAbsolutePoints==DISTORTION.errPatternNotFound) || (numAbsolutePoints==DISTORTION.errTooFewCells)) {
if (DEBUG_LEVEL>0) System.out.println("Grid "+(numFile+1)+" not found or too small ("+numAbsolutePoints+"), wasted "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+" seconds )\n");
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
continue; // too few cells detected
}
if (DISTORTION_PROCESS_CONFIGURATION.useNoPonters || (numAbsolutePoints>0)){
//Calculate grid contrast and brightness for each color component
matchSimulatedPattern.calcGridIntensities (
DISTORTION, //final DistortionParameters distortionParameters, //
COMPONENTS.equalizeGreens,
imp_sel, // image to process
THREADS_MAX);
ImagePlus imp_calibrated=matchSimulatedPattern.getCalibratedPatternAsImage(imp_sel,prefix, numAbsolutePoints);
if (DISTORTION_PROCESS_CONFIGURATION.showGridImages) imp_calibrated.show();
if (saveGrids){
FileSaver fs=new FileSaver(imp_calibrated);
String srcDir=DISTORTION_PROCESS_CONFIGURATION.selectGridFileDirectory(true,DISTORTION_PROCESS_CONFIGURATION.gridDirectory,true);
if (srcDir==null){
saveGrids=false; // do not ask about the next ones too
} else {
String path=DISTORTION_PROCESS_CONFIGURATION.gridDirectory+Prefs.getFileSeparator()+imp_calibrated.getTitle();
if (UPDATE_STATUS) IJ.showStatus("Saving "+path);
if (DEBUG_LEVEL>0) System.out.println("-->>> Saving "+path+" - using "+numAbsolutePoints+" laser pointer references");
fs.saveAsTiffStack(path);
}
}
}
if (DEBUG_LEVEL>0) System.out.println("Grid "+(numFile+1)+" calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+" (in "+
IJ.d2s(0.000000001*(System.nanoTime()-startFileTime),3)+"s )\n");
//
if (this.SYNC_COMMAND.stopRequested.get()>0) {
System.out.println("User requested stop");
break;
}
}
if (DEBUG_LEVEL>0) System.out.println(((this.SYNC_COMMAND.stopRequested.get()>0)?"Partial (interrupted by user) set of grids":"All")+ " grids calculation done at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return;
}
/* ======================================================================== */ /* ======================================================================== */
public void processCalibrationFiles() { public void processCalibrationFiles() {
if (!showProcessCalibrationFilesDialog(PROCESS_PARAMETERS)) return; if (!showProcessCalibrationFilesDialog(PROCESS_PARAMETERS)) return;
...@@ -9570,6 +9733,8 @@ if (MORE_BUTTONS) { ...@@ -9570,6 +9733,8 @@ if (MORE_BUTTONS) {
matchSimulatedPattern.calculateDistortions( matchSimulatedPattern.calculateDistortions(
DISTORTION, // DISTORTION, //
PATTERN_DETECT, PATTERN_DETECT,
PATTERN_DETECT.minGridPeriod/2,
PATTERN_DETECT.maxGridPeriod/2,
SIMUL, SIMUL,
COMPONENTS.equalizeGreens, COMPONENTS.equalizeGreens,
imp_sel, imp_sel,
...@@ -12475,7 +12640,7 @@ if (MORE_BUTTONS) { ...@@ -12475,7 +12640,7 @@ if (MORE_BUTTONS) {
throw new IllegalArgumentException (msg); throw new IllegalArgumentException (msg);
} }
matchSimulatedPattern.debugLevel=debugLevel; matchSimulatedPattern.debugLevel=debugLevel;
/*
double sharpnessOld=matchSimulatedPattern.focusQualityOld( double sharpnessOld=matchSimulatedPattern.focusQualityOld(
imp, imp,
focusMeasurementParameters.sampleSize, // will be twice the regualr FFT size focusMeasurementParameters.sampleSize, // will be twice the regualr FFT size
...@@ -12492,6 +12657,7 @@ if (MORE_BUTTONS) { ...@@ -12492,6 +12657,7 @@ if (MORE_BUTTONS) {
lensDistortionParameters.py0, lensDistortionParameters.py0,
debugLevel); debugLevel);
if (debugLevel>0) System.out.println("Focus qualityOld1="+sharpnessOld1); if (debugLevel>0) System.out.println("Focus qualityOld1="+sharpnessOld1);
*/
double sharpness=matchSimulatedPattern.focusQuality( double sharpness=matchSimulatedPattern.focusQuality(
imp, imp,
focusMeasurementParameters.sampleSize, // will be twice the regualr FFT size focusMeasurementParameters.sampleSize, // will be twice the regualr FFT size
...@@ -17017,9 +17183,13 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17017,9 +17183,13 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
mapCell.x=nTileX*size; mapCell.x=nTileX*size;
pixels=splitBayer(imp, mapCell,COMPONENTS.equalizeGreens); pixels=splitBayer(imp, mapCell,COMPONENTS.equalizeGreens);
pixels[4]= normalizeAndWindow (pixels[4], hamming); pixels[4]= normalizeAndWindow (pixels[4], hamming);
patternMap[nTileY][nTileX]=matchSimulatedPattern.findPattern(pixels[4], patternMap[nTileY][nTileX]=matchSimulatedPattern.findPattern(
null,
pixels[4],
size, size,
patternDetectParameters, patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
true, true,
title); // title - will not be used title); // title - will not be used
/* Now verify by correlating with the actual pattern */ /* Now verify by correlating with the actual pattern */
...@@ -17581,6 +17751,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17581,6 +17751,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
if (matchSimulatedPattern.PATTERN_GRID==null) { if (matchSimulatedPattern.PATTERN_GRID==null) {
double[][] distortedPattern= matchSimulatedPattern.findPatternDistorted(input_bayer, // pixel array to process (no windowing!) double[][] distortedPattern= matchSimulatedPattern.findPatternDistorted(input_bayer, // pixel array to process (no windowing!)
patternDetectParameters, patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
true, //(greensToProcess==4), // boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly true, //(greensToProcess==4), // boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly
title); // title prefix to use for debug images title); // title prefix to use for debug images
...@@ -19833,7 +20005,7 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -19833,7 +20005,7 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
return true; return true;
} }
/* ======================================================================== */ /* ======================================================================== */
public boolean showPatternDetectParametersDialog(MatchSimulatedPattern.PatternDetectParameters patternDetectParameters) { public boolean showPatternDetectParametersDialog(MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, boolean use_lwir) {
///gaussWidth ///gaussWidth
GenericDialog gd = new GenericDialog("Parameters"); GenericDialog gd = new GenericDialog("Parameters");
gd.addNumericField("Gaussian width for the window function (<=0 - use Hamming):", patternDetectParameters.gaussWidth, 3); gd.addNumericField("Gaussian width for the window function (<=0 - use Hamming):", patternDetectParameters.gaussWidth, 3);
...@@ -19849,16 +20021,30 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -19849,16 +20021,30 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
gd.addNumericField("Minimal pattern correlation contrast" , patternDetectParameters.minCorrContrast, 3); //5.0; // Discrimination threshold between good and bad pattern correleation gd.addNumericField("Minimal pattern correlation contrast" , patternDetectParameters.minCorrContrast, 3); //5.0; // Discrimination threshold between good and bad pattern correleation
gd.addNumericField("Minimal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.minGridPeriod, 2,5,"pix"); gd.addNumericField("Minimal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.minGridPeriod, 2,5,"pix");
gd.addNumericField("Maximal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.maxGridPeriod, 2,5,"pix"); gd.addNumericField("Maximal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.maxGridPeriod, 2,5,"pix");
if (use_lwir) {
gd.addNumericField("Minimal pattern grid period for LWIR sensors (<=0.0 - do not check)" , patternDetectParameters.minGridPeriodLwir, 2,5,"pix");
gd.addNumericField("Maximal pattern grid period for LWIR sensors (<=0.0 - do not check)" , patternDetectParameters.maxGridPeriodLwir, 2,5,"pix");
}
gd.addMessage("----- debug -----"); gd.addMessage("----- debug -----");
gd.addNumericField("Debug grid near pixel X" , patternDetectParameters.debugX, 1,6,"pix"); gd.addNumericField("Debug grid near pixel X" , patternDetectParameters.debugX, 1,6,"pix");
gd.addNumericField("Debug grid near pixel X" , patternDetectParameters.debugY, 1,6,"pix"); gd.addNumericField("Debug grid near pixel X" , patternDetectParameters.debugY, 1,6,"pix");
gd.addNumericField("Debug grid nodes at this distance of (x,Y) - <0 - no debug", patternDetectParameters.debugRadius, 1,5,"pix"); gd.addNumericField("Debug grid nodes at this distance of (x,Y) - <0 - no debug", patternDetectParameters.debugRadius, 1,5,"pix");
gd.addMessage("----- New method that should work with large cells (only half-period negative correlations fit in window) -----");
gd.addCheckbox ("Use large cell method (with phase correlation)", patternDetectParameters.use_large_cells); // true;
gd.addNumericField("\"phasiness\" of correlation" , patternDetectParameters.phaseCoeff, 2,5,"");
gd.addNumericField("Low-pass sigma for phase correlation - frequency fraction of maximal", patternDetectParameters.lowpass_sigma, 2,5,"");
gd.addNumericField("Minimal min/max amplitude fraction of the zero one" , patternDetectParameters.min_frac, 2,5,"");
gd.addNumericField("Minimal absolute value of sine of the patern vectors angle" , patternDetectParameters.min_sin, 2,5,"");
gd.addCheckbox ("Fail if quadratic approximation fails or returns outside of +/- 1.5", patternDetectParameters.no_crazy); // true;
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
patternDetectParameters.gaussWidth= gd.getNextNumber(); //0.4 patternDetectParameters.gaussWidth= gd.getNextNumber(); //0.4
patternDetectParameters.corrGamma= gd.getNextNumber(); //0.2; lower the value - higher harmonics will participate in pattern frequency measurements patternDetectParameters.corrGamma= gd.getNextNumber(); //0.2; lower the value - higher harmonics will participate in pattern frequency measurements
patternDetectParameters.corrSigma= gd.getNextNumber(); // 1.5; // pattern detection: high-pass filter (0.0 - none) gamma(PS) patternDetectParameters.corrSigma= gd.getNextNumber(); // 1.5; // pattern detection: high-pass filter (0.0 - none) gamma(PS)
patternDetectParameters.diffSpectrCorr= (int) gd.getNextNumber(); patternDetectParameters.diffSpectrCorr= (int) gd.getNextNumber();
patternDetectParameters.shrinkClusters= gd.getNextNumber(); // 0.5; // Shrink clusters by this ratio (remove lowest) after initial separation patternDetectParameters.shrinkClusters= gd.getNextNumber(); // 0.5; // Shrink clusters by this ratio (remove lowest) after initial separation
patternDetectParameters.multiplesToTry= (int) gd.getNextNumber(); patternDetectParameters.multiplesToTry= (int) gd.getNextNumber();
...@@ -19869,23 +20055,44 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -19869,23 +20055,44 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
patternDetectParameters.minCorrContrast= gd.getNextNumber(); patternDetectParameters.minCorrContrast= gd.getNextNumber();
patternDetectParameters.minGridPeriod= gd.getNextNumber(); patternDetectParameters.minGridPeriod= gd.getNextNumber();
patternDetectParameters.maxGridPeriod= gd.getNextNumber(); patternDetectParameters.maxGridPeriod= gd.getNextNumber();
if (use_lwir) {
patternDetectParameters.minGridPeriodLwir= gd.getNextNumber();
patternDetectParameters.maxGridPeriodLwir= gd.getNextNumber();
}
patternDetectParameters.debugX= gd.getNextNumber(); patternDetectParameters.debugX= gd.getNextNumber();
patternDetectParameters.debugY= gd.getNextNumber(); patternDetectParameters.debugY= gd.getNextNumber();
patternDetectParameters.debugRadius= gd.getNextNumber(); patternDetectParameters.debugRadius= gd.getNextNumber();
patternDetectParameters.use_large_cells= gd.getNextBoolean();
patternDetectParameters.phaseCoeff= gd.getNextNumber();
patternDetectParameters.lowpass_sigma= gd.getNextNumber();
patternDetectParameters.min_frac= gd.getNextNumber();
patternDetectParameters.min_sin= gd.getNextNumber();
patternDetectParameters.no_crazy= gd.getNextBoolean();
return true; return true;
} }
public boolean showPatternMinMaxPeriodDialog(MatchSimulatedPattern.PatternDetectParameters patternDetectParameters) { public boolean showPatternMinMaxPeriodDialog(MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, boolean use_lwir) {
///gaussWidth ///gaussWidth
GenericDialog gd = new GenericDialog("Min/Max opattern grid period"); GenericDialog gd = new GenericDialog("Min/Max opattern grid period");
gd.addNumericField("Minimal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.minGridPeriod, 2,5,"pix"); gd.addNumericField("Minimal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.minGridPeriod, 2,5,"pix");
gd.addNumericField("Maximal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.maxGridPeriod, 2,5,"pix"); gd.addNumericField("Maximal pattern grid period (<=0.0 - do not check)" , patternDetectParameters.maxGridPeriod, 2,5,"pix");
gd.addMessage ("TODO: Calculate min/max from pattern data and distance"); gd.addMessage ("TODO: Calculate min/max from pattern data and distance");
gd.showDialog(); if (use_lwir) {
if (gd.wasCanceled()) return false; gd.addNumericField("Minimal pattern grid period for LWIR sensors (<=0.0 - do not check)" , patternDetectParameters.minGridPeriodLwir, 2,5,"pix");
patternDetectParameters.minGridPeriod= gd.getNextNumber(); gd.addNumericField("Maximal pattern grid period for LWIR sensors (<=0.0 - do not check)" , patternDetectParameters.maxGridPeriodLwir, 2,5,"pix");
patternDetectParameters.maxGridPeriod= gd.getNextNumber(); }
return true; gd.showDialog();
} if (gd.wasCanceled()) return false;
patternDetectParameters.minGridPeriod= gd.getNextNumber();
patternDetectParameters.maxGridPeriod= gd.getNextNumber();
if (use_lwir) {
patternDetectParameters.minGridPeriodLwir= gd.getNextNumber();
patternDetectParameters.maxGridPeriodLwir= gd.getNextNumber();
}
return true;
}
/* ======================================================================== */ /* ======================================================================== */
...@@ -6,7 +6,7 @@ package com.elphel.imagej.calibration; ...@@ -6,7 +6,7 @@ package com.elphel.imagej.calibration;
** Copyright (C) 2011-2014 Elphel, Inc. ** Copyright (C) 2011-2014 Elphel, Inc.
** **
** -----------------------------------------------------------------------------** ** -----------------------------------------------------------------------------**
** **
** DistortionProcessConfiguration.java is free software: you can redistribute it and/or modify ** DistortionProcessConfiguration.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or ** the Free Software Foundation, either version 3 of the License, or
...@@ -23,16 +23,17 @@ package com.elphel.imagej.calibration; ...@@ -23,16 +23,17 @@ package com.elphel.imagej.calibration;
** **
*/ */
import ij.IJ;
import ij.Prefs;
import ij.gui.GenericDialog;
import java.io.File; import java.io.File;
import java.io.FilenameFilter;
import java.util.Properties; import java.util.Properties;
import com.elphel.imagej.common.WindowTools; import com.elphel.imagej.common.WindowTools;
import ij.IJ;
import ij.Prefs;
import ij.gui.GenericDialog;
public class DistortionProcessConfiguration{ public class DistortionProcessConfiguration{
public String sourceDirectory=""; public String sourceDirectory="";
public String gridDirectory= ""; public String gridDirectory= "";
...@@ -50,7 +51,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -50,7 +51,7 @@ import com.elphel.imagej.common.WindowTools;
public String selectSourceDirectory(boolean smart, String defaultPath, boolean newAllowed) { public String selectSourceDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Source (acquired from the camera) image directory", // title "Source (acquired from the camera) image directory", // title
"Select source directory", // button "Select source directory", // button
null, // filter null, // filter
...@@ -61,7 +62,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -61,7 +62,7 @@ import com.elphel.imagej.common.WindowTools;
public String selectGridFileDirectory(boolean smart, String defaultPath, boolean newAllowed) { public String selectGridFileDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Grid files directory (grid patterns extracted from the images)", // title "Grid files directory (grid patterns extracted from the images)", // title
"Select grid files directory", // button "Select grid files directory", // button
null, // filter null, // filter
...@@ -69,7 +70,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -69,7 +70,7 @@ import com.elphel.imagej.common.WindowTools;
if (dir!=null) this.gridDirectory=dir; if (dir!=null) this.gridDirectory=dir;
return dir; return dir;
} }
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"sourceDirectory", this.sourceDirectory); properties.setProperty(prefix+"sourceDirectory", this.sourceDirectory);
properties.setProperty(prefix+"gridDirectory", this.gridDirectory); properties.setProperty(prefix+"gridDirectory", this.gridDirectory);
...@@ -123,9 +124,9 @@ import com.elphel.imagej.common.WindowTools; ...@@ -123,9 +124,9 @@ import com.elphel.imagej.common.WindowTools;
gd.addCheckbox ("Show grid files as images", this.showGridImages); gd.addCheckbox ("Show grid files as images", this.showGridImages);
gd.addCheckbox ("Save grid files", this.saveGridImages); gd.addCheckbox ("Save grid files", this.saveGridImages);
gd.addCheckbox ("Overwrite existing result files", this.overwriteResultFiles); gd.addCheckbox ("Overwrite existing result files", this.overwriteResultFiles);
gd.addNumericField("Debug level", this.debugLevel,0); gd.addNumericField("Debug level", this.debugLevel,0);
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
...@@ -144,7 +145,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -144,7 +145,7 @@ import com.elphel.imagej.common.WindowTools;
this.debugLevel= (int) gd.getNextNumber(); this.debugLevel= (int) gd.getNextNumber();
System.out.println("1.newSourceDirectory = "+newSourceDirectory); System.out.println("1.newSourceDirectory = "+newSourceDirectory);
System.out.println("1.newGridDirectory = "+ newGridDirectory); System.out.println("1.newGridDirectory = "+ newGridDirectory);
if ((newSourceDirectory.length()==0) || (newSourceDirectory.indexOf('?')>=0)) if ((newSourceDirectory.length()==0) || (newSourceDirectory.indexOf('?')>=0))
newSourceDirectory= selectSourceDirectory(false, this.sourceDirectory, true); newSourceDirectory= selectSourceDirectory(false, this.sourceDirectory, true);
else else
newSourceDirectory= selectSourceDirectory(true, newSourceDirectory, true); // if matches, no dialog newSourceDirectory= selectSourceDirectory(true, newSourceDirectory, true); // if matches, no dialog
...@@ -174,7 +175,7 @@ import com.elphel.imagej.common.WindowTools; ...@@ -174,7 +175,7 @@ import com.elphel.imagej.common.WindowTools;
if (this.sourceDirectory.length()==0){ if (this.sourceDirectory.length()==0){
defaultPaths[0]=""; defaultPaths[0]="";
} }
CalibrationFileManagement.MultipleExtensionsFileFilter sourceFilter = CalibrationFileManagement.MultipleExtensionsFileFilter sourceFilter =
new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Source files"); new CalibrationFileManagement.MultipleExtensionsFileFilter("",extensions,"Source files");
String [] sourceFiles=null; String [] sourceFiles=null;
...@@ -206,5 +207,26 @@ import com.elphel.imagej.common.WindowTools; ...@@ -206,5 +207,26 @@ import com.elphel.imagej.common.WindowTools;
} }
return sourceFiles; return sourceFiles;
} }
public String[] selectSourceSets() {
File dir= new File (this.sourceDirectory);
if (this.debugLevel>1) System.out.println("selectSourceSets, dir="+this.sourceDirectory);
if (!dir.exists()) {
String error="Source directory "+this.sourceDirectory+" does not exist.";
IJ.showMessage("No files selected");
if (this.debugLevel>1) System.out.println("selectSourceFiles() ERROR:"+error);
return null;
}
File [] sourceFileSets = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File current, String name) {
return new File(current, name).isDirectory();
}
});
String [] sourceSets = new String[sourceFileSets.length];
for (int i=0;i<sourceSets.length;i++) sourceSets[i]=sourceFileSets[i].getPath();
return sourceSets;
}
} }
package com.elphel.imagej.calibration; package com.elphel.imagej.calibration;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.gui.GenericDialog;
import ij.io.FileSaver;
import ij.io.Opener;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -19,14 +9,22 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -19,14 +9,22 @@ import java.util.concurrent.atomic.AtomicInteger;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import com.elphel.imagej.calibration.CalibrationFileManagement.MultipleExtensionsFileFilter;
import com.elphel.imagej.calibration.SimulationPattern.SimulParameters;
import com.elphel.imagej.common.DoubleFHT; import com.elphel.imagej.common.DoubleFHT;
import com.elphel.imagej.common.DoubleGaussianBlur; import com.elphel.imagej.common.DoubleGaussianBlur;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.common.WindowTools; import com.elphel.imagej.common.WindowTools;
import com.elphel.imagej.jp4.JP46_Reader_camera; import com.elphel.imagej.jp4.JP46_Reader_camera;
import ij.IJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.gui.GenericDialog;
import ij.io.FileSaver;
import ij.io.Opener;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
public class EyesisAberrations { public class EyesisAberrations {
public double [][][][] pdfKernelMap=null; public double [][][][] pdfKernelMap=null;
JP46_Reader_camera JP4_INSTANCE= new JP46_Reader_camera(false); JP46_Reader_camera JP4_INSTANCE= new JP46_Reader_camera(false);
...@@ -34,7 +32,7 @@ public class EyesisAberrations { ...@@ -34,7 +32,7 @@ public class EyesisAberrations {
public AtomicInteger stopRequested=null; // 1 - stop now, 2 - when convenient public AtomicInteger stopRequested=null; // 1 - stop now, 2 - when convenient
public Distortions distortions=null; public Distortions distortions=null;
public AberrationParameters aberrationParameters=null; public AberrationParameters aberrationParameters=null;
public EyesisAberrations (AtomicInteger stopRequested, public EyesisAberrations (AtomicInteger stopRequested,
AberrationParameters aberrationParameters){ AberrationParameters aberrationParameters){
this.stopRequested=stopRequested; this.stopRequested=stopRequested;
...@@ -43,7 +41,7 @@ public class EyesisAberrations { ...@@ -43,7 +41,7 @@ public class EyesisAberrations {
public void setDistortions(Distortions distortions){ public void setDistortions(Distortions distortions){
this.distortions=distortions; this.distortions=distortions;
} }
int countExistentFiles(String directory,String [] paths, boolean remove){ int countExistentFiles(String directory,String [] paths, boolean remove){
int numFiles=0; int numFiles=0;
for (int i=0;i<paths.length;i++) if (paths[i]!=null){ for (int i=0;i<paths.length;i++) if (paths[i]!=null){
...@@ -127,7 +125,7 @@ public class EyesisAberrations { ...@@ -127,7 +125,7 @@ public class EyesisAberrations {
inverseParameters, // size (side of square) of direct PSF kernel inverseParameters, // size (side of square) of direct PSF kernel
threadsMax, // size (side of square) of reverse PSF kernel threadsMax, // size (side of square) of reverse PSF kernel
updateStatus, updateStatus,
globalDebugLevel); globalDebugLevel);
ImagePlus impInvertedPSF = new ImagePlus("interpolated kernel stack", stack); ImagePlus impInvertedPSF = new ImagePlus("interpolated kernel stack", stack);
JP46_Reader_camera jp4_instance= new JP46_Reader_camera(false); JP46_Reader_camera jp4_instance= new JP46_Reader_camera(false);
...@@ -139,14 +137,14 @@ public class EyesisAberrations { ...@@ -139,14 +137,14 @@ public class EyesisAberrations {
if (showResult) { if (showResult) {
impInvertedPSF.getProcessor().resetMinAndMax(); // imp_psf will be reused impInvertedPSF.getProcessor().resetMinAndMax(); // imp_psf will be reused
impInvertedPSF.show(); impInvertedPSF.show();
} }
if (saveResult){ if (saveResult){
if (globalDebugLevel>0) System.out.println((numProcessed+1)+" of "+numToProcess+": saving invered (of the file"+srcPaths[nChn]+") kernel to "+resultPaths[nChn]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (globalDebugLevel>0) System.out.println((numProcessed+1)+" of "+numToProcess+": saving invered (of the file"+srcPaths[nChn]+") kernel to "+resultPaths[nChn]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
FileSaver fs=new FileSaver(impInvertedPSF); FileSaver fs=new FileSaver(impInvertedPSF);
fs.saveAsTiffStack(resultPaths[nChn]); fs.saveAsTiffStack(resultPaths[nChn]);
} }
numProcessed++; numProcessed++;
if (stopRequested.get()>0) { if (stopRequested.get()>0) {
if (globalDebugLevel>0) System.out.println("User requested stop"); if (globalDebugLevel>0) System.out.println("User requested stop");
break; break;
} }
...@@ -162,7 +160,7 @@ public class EyesisAberrations { ...@@ -162,7 +160,7 @@ public class EyesisAberrations {
} }
return true; return true;
} }
public ImageStack reversePSFKernelStack( public ImageStack reversePSFKernelStack(
final ImageStack PSFStack, // stack of 3 32-bit (float) images, made of square kernels final ImageStack PSFStack, // stack of 3 32-bit (float) images, made of square kernels
final EyesisAberrations.InverseParameters inverseParameters, // size (side of square) of direct PSF kernel final EyesisAberrations.InverseParameters inverseParameters, // size (side of square) of direct PSF kernel
...@@ -181,6 +179,7 @@ public class EyesisAberrations { ...@@ -181,6 +179,7 @@ public class EyesisAberrations {
final int numberOfKernelsInChn=tilesY*tilesX; final int numberOfKernelsInChn=tilesY*tilesX;
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
float [] pixels=null; float [] pixels=null;
double [] kernel= new double[inverseParameters.dSize*inverseParameters.dSize]; double [] kernel= new double[inverseParameters.dSize*inverseParameters.dSize];
...@@ -200,7 +199,7 @@ public class EyesisAberrations { ...@@ -200,7 +199,7 @@ public class EyesisAberrations {
pixels=(float[]) PSFStack.getPixels(chn+1); pixels=(float[]) PSFStack.getPixels(chn+1);
chn0=chn; chn0=chn;
} }
extractOneKernel( pixels, // array of combined square kernels, each extractOneKernel( pixels, // array of combined square kernels, each
kernel, // will be filled, should have correct size before call kernel, // will be filled, should have correct size before call
tilesX, // number of kernels in a row tilesX, // number of kernels in a row
tileX, // horizontal number of kernel to extract tileX, // horizontal number of kernel to extract
...@@ -221,12 +220,12 @@ public class EyesisAberrations { ...@@ -221,12 +220,12 @@ public class EyesisAberrations {
variableSigmas, // array of sigmas to be used for each pixel, matches pixels[] variableSigmas, // array of sigmas to be used for each pixel, matches pixels[]
3.5, // drop calculatin if farther then nSigma 3.5, // drop calculatin if farther then nSigma
0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it 0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it
0, // int WOICenterY, // 0, // int WOICenterY, //
inverseParameters.rSize, //int WOIWidth, reduce later inverseParameters.rSize, //int WOIWidth, reduce later
inverseParameters.rSize, //int WOIHeight) inverseParameters.rSize, //int WOIHeight)
globalDebugLevel); globalDebugLevel);
} }
/* reverse PSF kernel */ /* reverse PSF kernel */
rKernel= cleanupAndReversePSF (rKernel, // input pixels rKernel= cleanupAndReversePSF (rKernel, // input pixels
inverseParameters, inverseParameters,
...@@ -252,7 +251,7 @@ public class EyesisAberrations { ...@@ -252,7 +251,7 @@ public class EyesisAberrations {
variableSigmas, // array of sigmas to be used for each pixel, matches pixels[] variableSigmas, // array of sigmas to be used for each pixel, matches pixels[]
3.5, // drop calculation if farther then nSigma 3.5, // drop calculation if farther then nSigma
0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it 0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it
0, // int WOICenterY, // 0, // int WOICenterY, //
inverseParameters.rSize, //int WOIWidth, reduce later inverseParameters.rSize, //int WOIWidth, reduce later
inverseParameters.rSize, inverseParameters.rSize,
globalDebugLevel); //int WOIHeight) globalDebugLevel); //int WOIHeight)
...@@ -280,7 +279,7 @@ public class EyesisAberrations { ...@@ -280,7 +279,7 @@ public class EyesisAberrations {
} }
return outStack; return outStack;
} }
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
private double [] maskReversePSFKernel( double []rpsf_pixels, // reversed psf, square array private double [] maskReversePSFKernel( double []rpsf_pixels, // reversed psf, square array
double [] ellipse_coeff, // ellipse coefficients from _direct_ kernel double [] ellipse_coeff, // ellipse coefficients from _direct_ kernel
...@@ -308,8 +307,8 @@ public class EyesisAberrations { ...@@ -308,8 +307,8 @@ public class EyesisAberrations {
} }
/* ======================================================================== */ /* ======================================================================== */
private double [] createSigmasFromCenter( private double [] createSigmasFromCenter(
int size, // side of square int size, // side of square
double sigma_to_radius, // variable blurring - sigma will be proportional distance from the center double sigma_to_radius, // variable blurring - sigma will be proportional distance from the center
...@@ -329,8 +328,8 @@ public class EyesisAberrations { ...@@ -329,8 +328,8 @@ public class EyesisAberrations {
return sigmas; return sigmas;
} }
/* ======================================================================== */ /* ======================================================================== */
public double [] cleanupAndReversePSF (double [] psf_pixels, // input pixels public double [] cleanupAndReversePSF (double [] psf_pixels, // input pixels
EyesisAberrations.InverseParameters inverseParameters, // size (side of square) of direct PSF kernel EyesisAberrations.InverseParameters inverseParameters, // size (side of square) of direct PSF kernel
...@@ -430,7 +429,7 @@ public class EyesisAberrations { ...@@ -430,7 +429,7 @@ public class EyesisAberrations {
double [] pixels=null; double [] pixels=null;
/* convert back original dimension array if there was no decimation or debug is set (in that case both sizes arrays will be converted) */ /* convert back original dimension array if there was no decimation or debug is set (in that case both sizes arrays will be converted) */
/* Convert fft array back to fht array and /* Convert fft array back to fht array and
set fht pixels with new values */ set fht pixels with new values */
pixels=FFTHalf2FHT (fft_complex,size); pixels=FFTHalf2FHT (fft_complex,size);
/* optionally show the result FHT*/ /* optionally show the result FHT*/
...@@ -440,7 +439,7 @@ public class EyesisAberrations { ...@@ -440,7 +439,7 @@ public class EyesisAberrations {
/* return inverted psf pixels */ /* return inverted psf pixels */
return pixels; return pixels;
} }
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
/* finds cluster (with the center at DC) by flooding from DC, so total energy is cutoff_energy fraction /* finds cluster (with the center at DC) by flooding from DC, so total energy is cutoff_energy fraction
...@@ -555,7 +554,7 @@ public class EyesisAberrations { ...@@ -555,7 +554,7 @@ public class EyesisAberrations {
iy=-iy; iy=-iy;
} }
ix= (ix+size) % size; ix= (ix+size) % size;
floatPixels[i]=(float) clusterMap[iy][ix]; floatPixels[i]=clusterMap[iy][ix];
} }
ip.setPixels(floatPixels); ip.setPixels(floatPixels);
ip.resetMinAndMax(); ip.resetMinAndMax();
...@@ -609,9 +608,9 @@ public class EyesisAberrations { ...@@ -609,9 +608,9 @@ public class EyesisAberrations {
return result; return result;
} }
/* ======================================================================== */ /* ======================================================================== */
/* TODO: REPLACE doubleFHT */ /* TODO: REPLACE doubleFHT */
/* converts FHT results (frequency space) to complex numbers of [fftsize/2+1][fftsize] */ /* converts FHT results (frequency space) to complex numbers of [fftsize/2+1][fftsize] */
...@@ -639,20 +638,20 @@ public class EyesisAberrations { ...@@ -639,20 +638,20 @@ public class EyesisAberrations {
row2=(fftsize-row1) %fftsize; row2=(fftsize-row1) %fftsize;
for (col1=0;col1 < fftsize;col1++) { for (col1=0;col1 < fftsize;col1++) {
col2=(fftsize-col1) %fftsize; col2=(fftsize-col1) %fftsize;
fht_pixels[row1*fftsize+col1]=(double) (fft[row1][col1][0]-fft[row1][col1][1]); fht_pixels[row1*fftsize+col1]=fft[row1][col1][0]-fft[row1][col1][1];
fht_pixels[row2*fftsize+col2]=(double) (fft[row1][col1][0]+fft[row1][col1][1]); fht_pixels[row2*fftsize+col2]=fft[row1][col1][0]+fft[row1][col1][1];
} }
} }
return fht_pixels; return fht_pixels;
} }
/* interpolate kernels minimizing memory image - use directly the image stack (32-bit, float) with kernels. /* interpolate kernels minimizing memory image - use directly the image stack (32-bit, float) with kernels.
Add kernels around by either replication or extrapolation to compensate for "margins" in the original; kernels */ Add kernels around by either replication or extrapolation to compensate for "margins" in the original; kernels */
//TODO: FIXME: Does not work if overwrite is disabled //TODO: FIXME: Does not work if overwrite is disabled
public boolean interpolateKernels( public boolean interpolateKernels(
AtomicInteger stopRequested, // 1 - stop now, 2 - when convenient AtomicInteger stopRequested, // 1 - stop now, 2 - when convenient
EyesisAberrations.InterpolateParameters interpolateParameters, // INTERPOLATE EyesisAberrations.InterpolateParameters interpolateParameters, // INTERPOLATE
EyesisAberrations.MultiFilePSF multiFilePSF , // MULTIFILE_PSF = new EyesisAberrations.MultiFilePSF( EyesisAberrations.MultiFilePSF multiFilePSF , // MULTIFILE_PSF = new EyesisAberrations.MultiFilePSF(
...@@ -734,7 +733,7 @@ public class EyesisAberrations { ...@@ -734,7 +733,7 @@ public class EyesisAberrations {
if (showResult) { if (showResult) {
impInterpolatedPSF.getProcessor().resetMinAndMax(); // imp_psf will be reused impInterpolatedPSF.getProcessor().resetMinAndMax(); // imp_psf will be reused
impInterpolatedPSF.show(); impInterpolatedPSF.show();
} }
if (saveResult){ if (saveResult){
if (globalDebugLevel>0) System.out.println((numProcessed+1)+" of "+numToProcess+": saving interpolation result (of the file"+srcPaths[nChn]+") to "+ if (globalDebugLevel>0) System.out.println((numProcessed+1)+" of "+numToProcess+": saving interpolation result (of the file"+srcPaths[nChn]+") to "+
resultPaths[nChn]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); resultPaths[nChn]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
...@@ -742,7 +741,7 @@ public class EyesisAberrations { ...@@ -742,7 +741,7 @@ public class EyesisAberrations {
fs.saveAsTiffStack(resultPaths[nChn]); fs.saveAsTiffStack(resultPaths[nChn]);
} }
numProcessed++; numProcessed++;
if (stopRequested.get()>0) { if (stopRequested.get()>0) {
if (globalDebugLevel>0) System.out.println("User requested stop"); if (globalDebugLevel>0) System.out.println("User requested stop");
break; break;
} }
...@@ -798,7 +797,7 @@ public class EyesisAberrations { ...@@ -798,7 +797,7 @@ public class EyesisAberrations {
int [] inTopLeft=new int [2]; // top left kernel in the input array int [] inTopLeft=new int [2]; // top left kernel in the input array
double [][] firstFHTColumn=null; double [][] firstFHTColumn=null;
double [][] secondFHTColumn=null; double [][] secondFHTColumn=null;
double [][][] cornerFHT=new double[2][2][interpolateParameters.size*interpolateParameters.size]; //[y][x][pixel] double [][][] cornerFHT=new double[2][2][interpolateParameters.size*interpolateParameters.size]; //[y][x][pixel]
double [] swapArray=null; double [] swapArray=null;
for (chn=0;chn<nChn;chn++) { for (chn=0;chn<nChn;chn++) {
...@@ -870,12 +869,12 @@ public class EyesisAberrations { ...@@ -870,12 +869,12 @@ public class EyesisAberrations {
" outTopLeft[0]="+outTopLeft[0]+" outTopLeft[1]="+outTopLeft[1]); " outTopLeft[0]="+outTopLeft[0]+" outTopLeft[1]="+outTopLeft[1]);
if (firstFHTColumn==null) { /* First colum needs to be input and calculated*/ if (firstFHTColumn==null) { /* First colum needs to be input and calculated*/
extractOneKernel( pixels, // array of combined square kernels, each extractOneKernel( pixels, // array of combined square kernels, each
cornerFHT[0][0], // will be filled, should have correct size before call cornerFHT[0][0], // will be filled, should have correct size before call
inTilesX, // number of kernels in a row inTilesX, // number of kernels in a row
inTopLeft[0], // horizontal number of kernel to extract inTopLeft[0], // horizontal number of kernel to extract
inTopLeft[1]); // vertical number of kernel to extract inTopLeft[1]); // vertical number of kernel to extract
extractOneKernel( pixels, // array of combined square kernels, each extractOneKernel( pixels, // array of combined square kernels, each
cornerFHT[1][0], // will be filled, should have correct size before call cornerFHT[1][0], // will be filled, should have correct size before call
inTilesX, // number of kernels in a row inTilesX, // number of kernels in a row
inTopLeft[0], // horizontal number of kernel to extract inTopLeft[0], // horizontal number of kernel to extract
...@@ -893,12 +892,12 @@ public class EyesisAberrations { ...@@ -893,12 +892,12 @@ public class EyesisAberrations {
if (globalDebugLevel>2) System.out.println(" firstFHTColumn.length="+firstFHTColumn.length); if (globalDebugLevel>2) System.out.println(" firstFHTColumn.length="+firstFHTColumn.length);
} }
if (secondFHTColumn==null) { /* Last colum needs to be input and calculated*/ if (secondFHTColumn==null) { /* Last colum needs to be input and calculated*/
extractOneKernel( pixels, // array of combined square kernels, each extractOneKernel( pixels, // array of combined square kernels, each
cornerFHT[0][1], // will be filled, should have correct size before call cornerFHT[0][1], // will be filled, should have correct size before call
inTilesX, // number of kernels in a row inTilesX, // number of kernels in a row
inTopLeft[0]+1, // horizontal number of kernel to extract inTopLeft[0]+1, // horizontal number of kernel to extract
inTopLeft[1]); // vertical number of kernel to extract inTopLeft[1]); // vertical number of kernel to extract
extractOneKernel( pixels, // array of combined square kernels, each extractOneKernel( pixels, // array of combined square kernels, each
cornerFHT[1][1], // will be filled, should have correct size before call cornerFHT[1][1], // will be filled, should have correct size before call
inTilesX, // number of kernels in a row inTilesX, // number of kernels in a row
inTopLeft[0]+1, // horizontal number of kernel to extract inTopLeft[0]+1, // horizontal number of kernel to extract
...@@ -953,7 +952,7 @@ public class EyesisAberrations { ...@@ -953,7 +952,7 @@ public class EyesisAberrations {
} }
} }
} }
} }
/* prepare result stack to return */ /* prepare result stack to return */
ImageStack outStack=new ImageStack(outTilesX*interpolateParameters.size,outTilesY*interpolateParameters.size); ImageStack outStack=new ImageStack(outTilesX*interpolateParameters.size,outTilesY*interpolateParameters.size);
for (chn=0;chn<nChn;chn++) { for (chn=0;chn<nChn;chn++) {
...@@ -962,7 +961,7 @@ public class EyesisAberrations { ...@@ -962,7 +961,7 @@ public class EyesisAberrations {
return outStack; return outStack;
} }
/* ======================================================================== */ /* ======================================================================== */
/* Used in interpolateKernelStack() */ /* Used in interpolateKernelStack() */
private void storeOneKernel( private void storeOneKernel(
float [] pixels, // float [] array of combined square kernels - will be filled float [] pixels, // float [] array of combined square kernels - will be filled
double [] kernel, // square kernel to store double [] kernel, // square kernel to store
...@@ -978,8 +977,8 @@ public class EyesisAberrations { ...@@ -978,8 +977,8 @@ public class EyesisAberrations {
} }
/* ======================================================================== */ /* ======================================================================== */
public String [][] preparePartialKernelsFilesList( public String [][] preparePartialKernelsFilesList(
int debugLevel){ int debugLevel){
DistortionCalibrationData distortionCalibrationData= distortions.fittingStrategy.distortionCalibrationData; DistortionCalibrationData distortionCalibrationData= distortions.fittingStrategy.distortionCalibrationData;
...@@ -1003,7 +1002,7 @@ public class EyesisAberrations { ...@@ -1003,7 +1002,7 @@ public class EyesisAberrations {
partialKernelPaths[imgNum]=this.aberrationParameters.partialPrefix+IJ.d2s(distortionCalibrationData.gIP[imgNum].timestamp,6).replace('.','_')+ partialKernelPaths[imgNum]=this.aberrationParameters.partialPrefix+IJ.d2s(distortionCalibrationData.gIP[imgNum].timestamp,6).replace('.','_')+
String.format("-%02d"+this.aberrationParameters.partialSuffix, distortionCalibrationData.gIP[imgNum].channel); // sensor number String.format("-%02d"+this.aberrationParameters.partialSuffix, distortionCalibrationData.gIP[imgNum].channel); // sensor number
// partialKernelPaths[imgNum]=this.aberrationParameters.sourceDirectory+Prefs.getFileSeparator()+filename; // partialKernelPaths[imgNum]=this.aberrationParameters.sourceDirectory+Prefs.getFileSeparator()+filename;
if (debugLevel>2) System.out.println("preparePartialKernelsFilesList() "+imgNum+": "+partialKernelPaths[imgNum]); if (debugLevel>2) System.out.println("preparePartialKernelsFilesList() "+imgNum+": "+partialKernelPaths[imgNum]);
} }
...@@ -1022,8 +1021,8 @@ public class EyesisAberrations { ...@@ -1022,8 +1021,8 @@ public class EyesisAberrations {
IJ.showMessage("Warning",msg); IJ.showMessage("Warning",msg);
return null; return null;
} }
int numChannels=distortions.fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels int numChannels=distortions.fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels
String [][] fileList=new String[numChannels][]; String [][] fileList=new String[numChannels][];
for (int numChn=0;numChn<numChannels;numChn++){ for (int numChn=0;numChn<numChannels;numChn++){
...@@ -1059,14 +1058,14 @@ public class EyesisAberrations { ...@@ -1059,14 +1058,14 @@ public class EyesisAberrations {
} }
/* /*
int numChannels=this.fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels int numChannels=this.fittingStrategy.distortionCalibrationData.getNumChannels(); // number of used channels
*/ */
public boolean createPartialKernels( public boolean createPartialKernels(
AtomicInteger stopRequested, // 1 - stop now, 2 - when convenient AtomicInteger stopRequested, // 1 - stop now, 2 - when convenient
int mapFFTsize, // scanImageForPatterns:FFT size int mapFFTsize, // scanImageForPatterns:FFT size
int fft_overlap, int fft_overlap,
int fft_size, int fft_size,
int PSF_subpixel, int PSF_subpixel,
OTFFilterParameters otfFilterParameters, OTFFilterParameters otfFilterParameters,
PSFParameters psfParameters, PSFParameters psfParameters,
int PSFKernelSize, // size of square used in the new map (should be multiple of map step) int PSFKernelSize, // size of square used in the new map (should be multiple of map step)
...@@ -1116,7 +1115,7 @@ public class EyesisAberrations { ...@@ -1116,7 +1115,7 @@ public class EyesisAberrations {
int numChannel=distortionCalibrationData.gIP[imgNum].channel; int numChannel=distortionCalibrationData.gIP[imgNum].channel;
if (debugLevel>2){ if (debugLevel>2){
System.out.println("Image "+imgNum+" channel "+numChannel+" is "+(selectedChannels[numChannel]?"ENABLED":"DISABLED")); System.out.println("Image "+imgNum+" channel "+numChannel+" is "+(selectedChannels[numChannel]?"ENABLED":"DISABLED"));
} }
if (!selectedChannels[numChannel]){ if (!selectedChannels[numChannel]){
selectedImages[imgNum]=false; selectedImages[imgNum]=false;
numDeselected++; numDeselected++;
...@@ -1139,7 +1138,7 @@ public class EyesisAberrations { ...@@ -1139,7 +1138,7 @@ public class EyesisAberrations {
String filename=this.aberrationParameters.sourcePrefix+IJ.d2s(distortionCalibrationData.gIP[imgNum].timestamp,6).replace('.','_')+ String filename=this.aberrationParameters.sourcePrefix+IJ.d2s(distortionCalibrationData.gIP[imgNum].timestamp,6).replace('.','_')+
String.format("-%02d"+this.aberrationParameters.sourceSuffix, distortionCalibrationData.gIP[imgNum].channel); // sensor number String.format("-%02d"+this.aberrationParameters.sourceSuffix, distortionCalibrationData.gIP[imgNum].channel); // sensor number
sourcePaths[imgNum]=this.aberrationParameters.sourceDirectory+Prefs.getFileSeparator()+filename; sourcePaths[imgNum]=this.aberrationParameters.sourceDirectory+Prefs.getFileSeparator()+filename;
File srcFile=new File(sourcePaths[imgNum]); File srcFile=new File(sourcePaths[imgNum]);
if (!srcFile.exists()){ if (!srcFile.exists()){
if (skipMissing) { if (skipMissing) {
if (debugLevel>0) System.out.println("Skipping missing file: "+sourcePaths[imgNum]); if (debugLevel>0) System.out.println("Skipping missing file: "+sourcePaths[imgNum]);
...@@ -1252,13 +1251,13 @@ public class EyesisAberrations { ...@@ -1252,13 +1251,13 @@ public class EyesisAberrations {
int iRetry=0; int iRetry=0;
for (iRetry=0;iRetry<MaxRetries;iRetry++){ // is this retry needed? for (iRetry=0;iRetry<MaxRetries;iRetry++){ // is this retry needed?
try { try {
double [][][] projectedGrid=null; double [][][] projectedGrid=null;
double hintTolerance=0.0; double hintTolerance=0.0;
if (partialToReprojected){ // replace px, py with projected values form the grid if (partialToReprojected){ // replace px, py with projected values form the grid
// this.distortions is set to the global LENS_DISTORTIONS // this.distortions is set to the global LENS_DISTORTIONS
int numGridImage=fileIndices[imgNum]; int numGridImage=fileIndices[imgNum];
projectedGrid=distortions.estimateGridOnSensor( // return grid array [v][u][0- x, 1 - y, 2 - u, 3 - v] projectedGrid=distortions.estimateGridOnSensor( // return grid array [v][u][0- x, 1 - y, 2 - u, 3 - v]
distortions.fittingStrategy.distortionCalibrationData.getImageStation(numGridImage), // station number, distortions.fittingStrategy.distortionCalibrationData.getImageStation(numGridImage), // station number,
distortions.fittingStrategy.distortionCalibrationData.gIP[numGridImage].channel, // subCamera, distortions.fittingStrategy.distortionCalibrationData.gIP[numGridImage].channel, // subCamera,
Double.NaN, // goniometerHorizontal, - not used Double.NaN, // goniometerHorizontal, - not used
...@@ -1277,10 +1276,12 @@ public class EyesisAberrations { ...@@ -1277,10 +1276,12 @@ public class EyesisAberrations {
} }
} }
} }
int rslt=matchSimulatedPattern.calculateDistortions( int rslt=matchSimulatedPattern.calculateDistortions(
distortionParameters, // distortionParameters, //
patternDetectParameters, patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
colorComponents.equalizeGreens, colorComponents.equalizeGreens,
imp, imp,
...@@ -1313,11 +1314,11 @@ public class EyesisAberrations { ...@@ -1313,11 +1314,11 @@ public class EyesisAberrations {
updateStatus, updateStatus,
debugLevel, debugLevel,
loopDebugLevel); // debug level loopDebugLevel); // debug level
createPSFMap( createPSFMap(
matchSimulatedPattern, matchSimulatedPattern,
matchSimulatedPattern.applyFlatField (imp), // if grid is flat-field calibrated, apply it (may throw here) matchSimulatedPattern.applyFlatField (imp), // if grid is flat-field calibrated, apply it (may throw here)
null, // int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent PSF_KERNEL_MAP structure) null, // int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent PSF_KERNEL_MAP structure)
multiFilePSF.overexposedMaxFraction, //MULTIFILE_PSF.overexposedMaxFraction, multiFilePSF.overexposedMaxFraction, //MULTIFILE_PSF.overexposedMaxFraction,
simulParameters, //SIMUL, //simulation parameters simulParameters, //SIMUL, //simulation parameters
mapFFTsize, // MAP_FFT_SIZE, // scanImageForPatterns:FFT size int mapFFTsize, // scanImageForPatterns:FFT size mapFFTsize, // MAP_FFT_SIZE, // scanImageForPatterns:FFT size int mapFFTsize, // scanImageForPatterns:FFT size
...@@ -1325,7 +1326,7 @@ public class EyesisAberrations { ...@@ -1325,7 +1326,7 @@ public class EyesisAberrations {
fft_overlap, //FFT_OVERLAP, // int fft_overlap, fft_overlap, //FFT_OVERLAP, // int fft_overlap,
fft_size, // FFT_SIZE, // int fft_size, fft_size, // FFT_SIZE, // int fft_size,
colorComponents, //COMPONENTS, // ColorComponents colorComponents, colorComponents, //COMPONENTS, // ColorComponents colorComponents,
PSF_subpixel, //PSF_SUBPIXEL, // int PSF_subpixel, PSF_subpixel, //PSF_SUBPIXEL, // int PSF_subpixel,
otfFilterParameters, // OTF_FILTER, // OTFFilterParameters otfFilterParameters, otfFilterParameters, // OTF_FILTER, // OTFFilterParameters otfFilterParameters,
psfParameters, //PSF_PARS, // final PSFParameters psfParameters psfParameters, //PSF_PARS, // final PSFParameters psfParameters
psfParameters.minDefinedArea , //PSF_PARS.minDefinedArea, // final double minDefinedArea, psfParameters.minDefinedArea , //PSF_PARS.minDefinedArea, // final double minDefinedArea,
...@@ -1347,20 +1348,20 @@ public class EyesisAberrations { ...@@ -1347,20 +1348,20 @@ public class EyesisAberrations {
} }
if (iRetry==MaxRetries) { if (iRetry==MaxRetries) {
System.out.println("File "+files[imgNum][1]+ " has problems - finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); System.out.println("File "+files[imgNum][1]+ " has problems - finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (stopRequested.get()>0) { if (stopRequested.get()>0) {
if (debugLevel>0) System.out.println("User requested stop"); if (debugLevel>0) System.out.println("User requested stop");
break; break;
} }
continue; continue;
} }
ImageStack stack=mergeKernelsToStack(this.pdfKernelMap); ImageStack stack=mergeKernelsToStack(this.pdfKernelMap);
// TODO: Add properties, // TODO: Add properties,
// Save configuration (filename with timestamp?) before files from the top class, test directory is writable // Save configuration (filename with timestamp?) before files from the top class, test directory is writable
if (stack!=null) { if (stack!=null) {
if (debugLevel>0) System.out.println("Saving result to"+files[imgNum][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (debugLevel>0) System.out.println("Saving result to"+files[imgNum][1]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
savePartialKernelStack( savePartialKernelStack(
...@@ -1370,11 +1371,11 @@ public class EyesisAberrations { ...@@ -1370,11 +1371,11 @@ public class EyesisAberrations {
psfParameters, psfParameters,
correlationSizesUsed); correlationSizesUsed);
} else { } else {
System.out.println("File "+files[imgNum][1]+ " has no useful PSF kernels - at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); System.out.println("File "+files[imgNum][1]+ " has no useful PSF kernels - at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
distortions.fittingStrategy.setNoUsefulPSFKernels(fileIndices[imgNum], true); // mark (need to save configuration) not to try them next time distortions.fittingStrategy.setNoUsefulPSFKernels(fileIndices[imgNum], true); // mark (need to save configuration) not to try them next time
// todo - write a placeholder file (different suffix/prefix) instead of using setNoUsefulPSFKernels()? // todo - write a placeholder file (different suffix/prefix) instead of using setNoUsefulPSFKernels()?
} }
if (stopRequested.get()>0) { if (stopRequested.get()>0) {
if (debugLevel>0) System.out.println("User requested stop"); if (debugLevel>0) System.out.println("User requested stop");
break; break;
} }
...@@ -1412,14 +1413,14 @@ public class EyesisAberrations { ...@@ -1412,14 +1413,14 @@ public class EyesisAberrations {
} }
} }
} }
ShowDoubleFloatArrays sdfa_instance=new ShowDoubleFloatArrays(); ShowDoubleFloatArrays sdfa_instance=new ShowDoubleFloatArrays();
ImagePlus impShow=new ImagePlus("CombinedKernels"); // just to show in the same window? ImagePlus impShow=new ImagePlus("CombinedKernels"); // just to show in the same window?
long startTime=System.nanoTime(); long startTime=System.nanoTime();
for (int nChn=0; nChn<fileList.length;nChn++) if (fileList[nChn]!=null){ for (int nChn=0; nChn<fileList.length;nChn++) if (fileList[nChn]!=null){
// TODO: add parameters to kernel files // TODO: add parameters to kernel files
boolean OK=combinePSFKernels ( boolean OK=combinePSFKernels (
interpolateParameters, // INTERPOLATE interpolateParameters, // INTERPOLATE
multiFilePSF , // MULTIFILE_PSF = new EyesisAberrations.MultiFilePSF( multiFilePSF , // MULTIFILE_PSF = new EyesisAberrations.MultiFilePSF(
...@@ -1433,7 +1434,7 @@ public class EyesisAberrations { ...@@ -1433,7 +1434,7 @@ public class EyesisAberrations {
thisDebugLevel, thisDebugLevel,
globalDebugLevel); globalDebugLevel);
if (OK && (globalDebugLevel>0)) System.out.println("Saved combined kernel for channel "+nChn+" to"+resultPaths[nChn]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)); if (OK && (globalDebugLevel>0)) System.out.println("Saved combined kernel for channel "+nChn+" to"+resultPaths[nChn]+ " at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
if (stopRequested.get()>0) { if (stopRequested.get()>0) {
if (globalDebugLevel>0) System.out.println("User requested stop"); if (globalDebugLevel>0) System.out.println("User requested stop");
break; break;
} }
...@@ -1441,8 +1442,8 @@ public class EyesisAberrations { ...@@ -1441,8 +1442,8 @@ public class EyesisAberrations {
} }
return true; return true;
} }
public boolean combinePSFKernels( public boolean combinePSFKernels(
EyesisAberrations.InterpolateParameters interpolateParameters, // INTERPOLATE EyesisAberrations.InterpolateParameters interpolateParameters, // INTERPOLATE
EyesisAberrations.MultiFilePSF multiFilePSF , // MULTIFILE_PSF = new EyesisAberrations.MultiFilePSF( EyesisAberrations.MultiFilePSF multiFilePSF , // MULTIFILE_PSF = new EyesisAberrations.MultiFilePSF(
...@@ -1455,7 +1456,7 @@ public class EyesisAberrations { ...@@ -1455,7 +1456,7 @@ public class EyesisAberrations {
boolean updateStatus, // UPDATE_STATUS boolean updateStatus, // UPDATE_STATUS
int thisDebugLevel, int thisDebugLevel,
int globalDebugLevel int globalDebugLevel
){ ){
double [][][][] psfKernelMap; // will be lost - do we need it outside double [][][][] psfKernelMap; // will be lost - do we need it outside
double [][][][][] kernelsElllipsePars = new double[filenames.length][][][][]; //x0,y0,a,b,c,area double [][][][][] kernelsElllipsePars = new double[filenames.length][][][][]; //x0,y0,a,b,c,area
if (thisDebugLevel>0){ if (thisDebugLevel>0){
...@@ -1500,7 +1501,7 @@ public class EyesisAberrations { ...@@ -1500,7 +1501,7 @@ public class EyesisAberrations {
// int chn, tileY,tileX; // int chn, tileY,tileX;
boolean [] channels=new boolean[nChn]; boolean [] channels=new boolean[nChn];
double a; double a;
if (thisDebugLevel>1) { if (thisDebugLevel>1) {
System.out.println("nFiles="+nFiles); System.out.println("nFiles="+nFiles);
System.out.println("kWidth="+kWidth); System.out.println("kWidth="+kWidth);
System.out.println("kHeight="+kHeight); System.out.println("kHeight="+kHeight);
...@@ -1536,7 +1537,7 @@ public class EyesisAberrations { ...@@ -1536,7 +1537,7 @@ public class EyesisAberrations {
} }
} }
/* /*
* Combine files - now just average all that are not NaN * Combine files - now just average all that are not NaN
*/ */
int [][] dirs={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}}; int [][] dirs={{-1,-1},{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1}};
...@@ -1551,7 +1552,7 @@ public class EyesisAberrations { ...@@ -1551,7 +1552,7 @@ public class EyesisAberrations {
if (D.isNaN()) weights[nFile+1][i]=0.0; if (D.isNaN()) weights[nFile+1][i]=0.0;
} }
} }
// Set weight to 0.5 if it has zero cells around // Set weight to 0.5 if it has zero cells around
for (int tileY=0;tileY<kHeight;tileY++) for (int tileX=0;tileX<kWidth;tileX++) { for (int tileY=0;tileY<kHeight;tileY++) for (int tileX=0;tileX<kWidth;tileX++) {
int index=tileY*kWidth+tileX; int index=tileY*kWidth+tileX;
if ( weights[nFile+1][index]>0.0){ if ( weights[nFile+1][index]>0.0){
...@@ -1562,8 +1563,8 @@ public class EyesisAberrations { ...@@ -1562,8 +1563,8 @@ public class EyesisAberrations {
weights[nFile+1][index]=0.5; // multiFilePSF.weightOnBorder; //0.5->0.01; weights[nFile+1][index]=0.5; // multiFilePSF.weightOnBorder; //0.5->0.01;
} }
} }
} }
weights[0][index]+=weights[nFile+1][index]; weights[0][index]+=weights[nFile+1][index];
} }
} }
if (thisDebugLevel>1) sdfa_instance.showArrays(weights, kWidth, kHeight, true, "weights0"); if (thisDebugLevel>1) sdfa_instance.showArrays(weights, kWidth, kHeight, true, "weights0");
...@@ -1581,7 +1582,7 @@ public class EyesisAberrations { ...@@ -1581,7 +1582,7 @@ public class EyesisAberrations {
for (int nFile=0;nFile<nFiles;nFile++) weightsMasked[0][i]+=weightsMasked[nFile+1][i]; for (int nFile=0;nFile<nFiles;nFile++) weightsMasked[0][i]+=weightsMasked[nFile+1][i];
} }
if (thisDebugLevel>1) sdfa_instance.showArrays(weightsMasked, kWidth, kHeight, true, "weightsMasked"); if (thisDebugLevel>1) sdfa_instance.showArrays(weightsMasked, kWidth, kHeight, true, "weightsMasked");
double [][][] psfRadius=c[5]; // later may remove all other calculations for c[i]? double [][][] psfRadius=c[5]; // later may remove all other calculations for c[i]?
double [][][] pxfCenterX=c[0]; // some outlayer kernels have large x/y shift with normal radius - remove them too double [][][] pxfCenterX=c[0]; // some outlayer kernels have large x/y shift with normal radius - remove them too
double [][][] pxfCenterY=c[1]; double [][][] pxfCenterY=c[1];
...@@ -1599,7 +1600,7 @@ public class EyesisAberrations { ...@@ -1599,7 +1600,7 @@ public class EyesisAberrations {
int samplesAfterAll= totalNumSamples - ((int) Math.floor(multiFilePSF.maxFracDiscardAll*totalNumSamples)); int samplesAfterAll= totalNumSamples - ((int) Math.floor(multiFilePSF.maxFracDiscardAll*totalNumSamples));
int numSamples=totalNumSamples; int numSamples=totalNumSamples;
while (numSamples>samplesAfterAll){ // calculate and remove worst sample until it is close enough to the average or too few samples are left while (numSamples>samplesAfterAll){ // calculate and remove worst sample until it is close enough to the average or too few samples are left
boolean removeOnlyWorse=numSamples>samplesAfterWorse; boolean removeOnlyWorse=numSamples>samplesAfterWorse;
for (int color=0;color<nChn;color++){ for (int color=0;color<nChn;color++){
...@@ -1634,9 +1635,9 @@ public class EyesisAberrations { ...@@ -1634,9 +1635,9 @@ public class EyesisAberrations {
" sumWeights="+IJ.d2s(sumWeights,3)); " sumWeights="+IJ.d2s(sumWeights,3));
*/ */
if (sumWeights>0.0) for (int color=0;color<nChn;color++) { if (sumWeights>0.0) for (int color=0;color<nChn;color++) {
radiusRatio[color][0][index]/=sumWeights; // average radius, without border-over-non-border cells radiusRatio[color][0][index]/=sumWeights; // average radius, without border-over-non-border cells
pxfCenterX[color][0][index]/=sumWeights; pxfCenterX[color][0][index]/=sumWeights;
pxfCenterY[color][0][index]/=sumWeights; pxfCenterY[color][0][index]/=sumWeights;
} }
double [] diffs=new double[nFiles]; double [] diffs=new double[nFiles];
double [] diffsXY2=new double[nFiles]; double [] diffsXY2=new double[nFiles];
...@@ -1703,18 +1704,18 @@ public class EyesisAberrations { ...@@ -1703,18 +1704,18 @@ public class EyesisAberrations {
" worstDiff="+IJ.d2s(worstDiff,3)+ " worstDiff="+IJ.d2s(worstDiff,3)+
" removeOnlyWorse="+removeOnlyWorse+ " removeOnlyWorse="+removeOnlyWorse+
" worstFile="+worstFile+" ("+filenames[worstFile]+")"); " worstFile="+worstFile+" ("+filenames[worstFile]+")");
System.out.println( System.out.println(
" this radius ={"+psfRadius[0][worstFile+1][index]+","+psfRadius[1][worstFile+1][index]+","+psfRadius[2][worstFile+1][index]+"}\n"+ " this radius ={"+psfRadius[0][worstFile+1][index]+","+psfRadius[1][worstFile+1][index]+","+psfRadius[2][worstFile+1][index]+"}\n"+
" mean radius ={"+radiusRatio[0][0][index]+","+radiusRatio[1][0][index]+","+radiusRatio[2][0][index]+"}\n"+ " mean radius ={"+radiusRatio[0][0][index]+","+radiusRatio[1][0][index]+","+radiusRatio[2][0][index]+"}\n"+
" this center X={"+pxfCenterX[0][worstFile+1][index]+","+pxfCenterX[1][worstFile+1][index]+","+pxfCenterX[2][worstFile+1][index]+"}\n"+ " this center X={"+pxfCenterX[0][worstFile+1][index]+","+pxfCenterX[1][worstFile+1][index]+","+pxfCenterX[2][worstFile+1][index]+"}\n"+
" mean center X={"+pxfCenterX[0][0][index]+","+pxfCenterX[1][0][index]+","+pxfCenterX[2][0][index]+"}\n"+ " mean center X={"+pxfCenterX[0][0][index]+","+pxfCenterX[1][0][index]+","+pxfCenterX[2][0][index]+"}\n"+
" this center Y={"+pxfCenterY[0][worstFile+1][index]+","+pxfCenterY[1][worstFile+1][index]+","+pxfCenterY[2][worstFile+1][index]+"}\n"+ " this center Y={"+pxfCenterY[0][worstFile+1][index]+","+pxfCenterY[1][worstFile+1][index]+","+pxfCenterY[2][worstFile+1][index]+"}\n"+
" mean center Y={"+pxfCenterY[0][0][index]+","+pxfCenterY[1][0][index]+","+pxfCenterY[2][0][index]+"}"); " mean center Y={"+pxfCenterY[0][0][index]+","+pxfCenterY[1][0][index]+","+pxfCenterY[2][0][index]+"}");
} }
if (numSamples<1) break; // nothing left if (numSamples<1) break; // nothing left
if (worstDiff>multiFilePSF.radiusDiffHigh){ if (worstDiff>multiFilePSF.radiusDiffHigh){
if ( (numSamples==1) && (globalDebugLevel>0)){ if ( (numSamples==1) && (globalDebugLevel>0)){
System.out.println("PSF size for the cell "+tileX+":"+tileY+", file# "+worstFile+" varies too much from the neighbor cells, so it is removed, creating a gap"); System.out.println("PSF size for the cell "+tileX+":"+tileY+", file# "+worstFile+" varies too much from the neighbor cells, so it is removed, creating a gap");
...@@ -1733,14 +1734,14 @@ public class EyesisAberrations { ...@@ -1733,14 +1734,14 @@ public class EyesisAberrations {
weights[0][index]+=weights[nFile+1][index]; weights[0][index]+=weights[nFile+1][index];
} }
} }
// for each channel, each cell - compare radius calculated for neighbors (use masked weights) and the cell // for each channel, each cell - compare radius calculated for neighbors (use masked weights) and the cell
// TODO: Filter out outlayers: Add bonus to cells surrounded by others? // TODO: Filter out outlayers: Add bonus to cells surrounded by others?
// double [][][][] c= new double[numResults][nChn][nFiles+1][kLength]; // double [][][][] c= new double[numResults][nChn][nFiles+1][kLength];
// double [][][] numVals=new double[numResults][nChn][kLength]; // double [][][] numVals=new double[numResults][nChn][kLength];
for (int chn=0;chn<nChn;chn++) { for (int chn=0;chn<nChn;chn++) {
...@@ -1767,9 +1768,9 @@ public class EyesisAberrations { ...@@ -1767,9 +1768,9 @@ public class EyesisAberrations {
for (int i=0;i<kLength;i++){ for (int i=0;i<kLength;i++){
if (numVals[nOut][chn][i]==0.0 )c[nOut][chn][0][i]=Double.NaN; if (numVals[nOut][chn][i]==0.0 )c[nOut][chn][0][i]=Double.NaN;
// else c[nOut][chn][0][i]/=numVals[nOut][chn][i]; // else c[nOut][chn][0][i]/=numVals[nOut][chn][i];
} }
} }
if (multiFilePSF.validateShowEllipse) { if (multiFilePSF.validateShowEllipse) {
sdfa_instance.showArrays(radiusRatio[chn], kWidth, kHeight, true, "ratio-"+chn); sdfa_instance.showArrays(radiusRatio[chn], kWidth, kHeight, true, "ratio-"+chn);
sdfa_instance.showArrays(c[5][chn],kWidth, kHeight, true, "radius-"+chn); sdfa_instance.showArrays(c[5][chn],kWidth, kHeight, true, "radius-"+chn);
...@@ -1780,7 +1781,7 @@ public class EyesisAberrations { ...@@ -1780,7 +1781,7 @@ public class EyesisAberrations {
sdfa_instance.showArrays(c[3][chn], kWidth, kHeight, true, "y2-"+chn); sdfa_instance.showArrays(c[3][chn], kWidth, kHeight, true, "y2-"+chn);
sdfa_instance.showArrays(c[4][chn], kWidth, kHeight, true, "xy-"+chn); sdfa_instance.showArrays(c[4][chn], kWidth, kHeight, true, "xy-"+chn);
sdfa_instance.showArrays(c[6][chn], kWidth, kHeight, true, "area-"+chn); sdfa_instance.showArrays(c[6][chn], kWidth, kHeight, true, "area-"+chn);
} }
} }
} }
...@@ -1813,7 +1814,7 @@ public class EyesisAberrations { ...@@ -1813,7 +1814,7 @@ public class EyesisAberrations {
int filledMissing=0; int filledMissing=0;
//Finalize accumulated kernels - transform them from frequency to space domain //Finalize accumulated kernels - transform them from frequency to space domain
inverseTransformKernels(psfKernelMap); inverseTransformKernels(psfKernelMap);
// should be done after inversion, because filled in kernels are just pointers to original ones // should be done after inversion, because filled in kernels are just pointers to original ones
if (multiFilePSF.fillMissing) filledMissing=fillMissingKernels (psfKernelMap); if (multiFilePSF.fillMissing) filledMissing=fillMissingKernels (psfKernelMap);
int numMissing=0; int numMissing=0;
ImageStack mergedStack= mergeKernelsToStack(psfKernelMap,originalSliceLabels); ImageStack mergedStack= mergeKernelsToStack(psfKernelMap,originalSliceLabels);
...@@ -1831,9 +1832,9 @@ public class EyesisAberrations { ...@@ -1831,9 +1832,9 @@ public class EyesisAberrations {
for (int tileY=0;tileY<kHeight;tileY++) for (int tileX=0;tileX<kWidth;tileX++) if ((psfKernelMap[tileY][tileX]==null) || (psfKernelMap[tileY][tileX][0]==null)) numMissing++; for (int tileY=0;tileY<kHeight;tileY++) for (int tileX=0;tileX<kWidth;tileX++) if ((psfKernelMap[tileY][tileX]==null) || (psfKernelMap[tileY][tileX][0]==null)) numMissing++;
ImagePlus imp_psf = new ImagePlus(resultPath, mergedStack); ImagePlus imp_psf = new ImagePlus(resultPath, mergedStack);
if (impProtoIndex>=0){ if (impProtoIndex>=0){
imp_sel=opener.openImage("", filenames[impProtoIndex]); imp_sel=opener.openImage("", filenames[impProtoIndex]);
jp4_instance.decodeProperiesFromInfo(imp_sel); jp4_instance.decodeProperiesFromInfo(imp_sel);
// copy properties from the source image // copy properties from the source image
jp4_instance.copyProperties (imp_sel,imp_psf); jp4_instance.copyProperties (imp_sel,imp_psf);
...@@ -1889,7 +1890,7 @@ public class EyesisAberrations { ...@@ -1889,7 +1890,7 @@ public class EyesisAberrations {
} }
return true; return true;
} }
private int fillMissingKernels(double [][][][] kernels){ private int fillMissingKernels(double [][][][] kernels){
int [][] dirs={{-1,0},{1,0},{0,-1},{0,1}}; int [][] dirs={{-1,0},{1,0},{0,-1},{0,1}};
List <Integer> kernelList=new ArrayList<Integer>(100); List <Integer> kernelList=new ArrayList<Integer>(100);
...@@ -1908,7 +1909,7 @@ public class EyesisAberrations { ...@@ -1908,7 +1909,7 @@ public class EyesisAberrations {
(kernels[newTileY][newTileX]!=null) && (kernels[newTileY][newTileX][0]!=null) ) { (kernels[newTileY][newTileX]!=null) && (kernels[newTileY][newTileX][0]!=null) ) {
kernelList.add(Index); kernelList.add(Index);
} }
} }
numMissing++; numMissing++;
} }
} }
...@@ -1930,7 +1931,7 @@ public class EyesisAberrations { ...@@ -1930,7 +1931,7 @@ public class EyesisAberrations {
Index=newTileY*width+newTileX; Index=newTileY*width+newTileX;
kernelList.add(Index); kernelList.add(Index);
} else if ((kernels[tileY][tileX]==null) || (kernels[tileY][tileX][0]==null)) { // may be already added } else if ((kernels[tileY][tileX]==null) || (kernels[tileY][tileX][0]==null)) { // may be already added
// need to copy - they will be subject to reverse fht ? // need to copy - they will be subject to reverse fht ?
kernels[tileY][tileX]=kernels[newTileY][newTileX]; kernels[tileY][tileX]=kernels[newTileY][newTileX];
System.out.println("fillMissingKernels: filled "+tileX+"/"+tileY); System.out.println("fillMissingKernels: filled "+tileX+"/"+tileY);
} }
...@@ -1940,9 +1941,9 @@ public class EyesisAberrations { ...@@ -1940,9 +1941,9 @@ public class EyesisAberrations {
} }
return numMissing; return numMissing;
} }
/* ======================================================================== */ /* ======================================================================== */
//Finalize accumulated kernels - transform them from frequency to space domain //Finalize accumulated kernels - transform them from frequency to space domain
public void inverseTransformKernels( public void inverseTransformKernels(
...@@ -1960,9 +1961,9 @@ public class EyesisAberrations { ...@@ -1960,9 +1961,9 @@ public class EyesisAberrations {
} }
// Will build global PSF_KERNEL_MAP (each [][][]element should be set to null? // Will build global PSF_KERNEL_MAP (each [][][]element should be set to null?
// kernels are supposed to be normalized? // kernels are supposed to be normalized?
public void accumulatePartialKernelStack( public void accumulatePartialKernelStack(
...@@ -1993,7 +1994,7 @@ public class EyesisAberrations { ...@@ -1993,7 +1994,7 @@ public class EyesisAberrations {
boolean debugThis= (index==debugIndex) && (debugLevel>1); boolean debugThis= (index==debugIndex) && (debugLevel>1);
if (theseWeights[index]>0.0){ if (theseWeights[index]>0.0){
extractOneKernel( extractOneKernel(
pixels, // array of combined square kernels, each pixels, // array of combined square kernels, each
kernel, // will be filled, should have correct size before call kernel, // will be filled, should have correct size before call
tilesX, // number of kernels in a row tilesX, // number of kernels in a row
tileX, // horizontal number of kernel to extract tileX, // horizontal number of kernel to extract
...@@ -2025,8 +2026,8 @@ public class EyesisAberrations { ...@@ -2025,8 +2026,8 @@ public class EyesisAberrations {
} }
} }
public double [][][][] kernelStackToEllipseCoefficients( public double [][][][] kernelStackToEllipseCoefficients(
ImageStack kernelStack, // Image stack, each slice consists of square kernels of one channel ImageStack kernelStack, // Image stack, each slice consists of square kernels of one channel
int size, // size of each kernel (should be square) int size, // size of each kernel (should be square)
...@@ -2044,7 +2045,7 @@ public class EyesisAberrations { ...@@ -2044,7 +2045,7 @@ public class EyesisAberrations {
int tileY,tileX, chn; //,subTileY,subTileX; int tileY,tileX, chn; //,subTileY,subTileX;
double [][][][] ellipseCoeffs=new double [tilesY][tilesX][nChn][]; double [][][][] ellipseCoeffs=new double [tilesY][tilesX][nChn][];
int length=size*size; int length=size*size;
double [] kernel=new double[length]; double [] kernel=new double[length];
double max; double max;
int [][]selection; int [][]selection;
double [] ec; double [] ec;
...@@ -2053,7 +2054,7 @@ public class EyesisAberrations { ...@@ -2053,7 +2054,7 @@ public class EyesisAberrations {
pixels=(float[]) kernelStack.getPixels(chn+1); pixels=(float[]) kernelStack.getPixels(chn+1);
for (tileY=0;tileY<tilesY;tileY++) for (tileX=0;tileX<tilesX;tileX++) { for (tileY=0;tileY<tilesY;tileY++) for (tileX=0;tileX<tilesX;tileX++) {
extractOneKernel( extractOneKernel(
pixels, // array of combined square kernels, each pixels, // array of combined square kernels, each
kernel, // will be filled, should have correct size before call kernel, // will be filled, should have correct size before call
tilesX, // number of kernels in a row tilesX, // number of kernels in a row
tileX, // horizontal number of kernel to extract tileX, // horizontal number of kernel to extract
...@@ -2080,11 +2081,11 @@ public class EyesisAberrations { ...@@ -2080,11 +2081,11 @@ public class EyesisAberrations {
} }
return ellipseCoeffs; return ellipseCoeffs;
} }
/* ======================================================================== */ /* ======================================================================== */
private void extractOneKernel( private void extractOneKernel(
float [] pixels, // array of combined square kernels, each float [] pixels, // array of combined square kernels, each
double [] kernel, // will be filled, should have correct size before call double [] kernel, // will be filled, should have correct size before call
int numHor, // number of kernels in a row int numHor, // number of kernels in a row
int xTile, // horizontal number of kernel to extract int xTile, // horizontal number of kernel to extract
...@@ -2104,12 +2105,12 @@ public class EyesisAberrations { ...@@ -2104,12 +2105,12 @@ public class EyesisAberrations {
for (i=0;i<size;i++) for (j=0;j<size;j++) kernel [i*size+j]=pixels[base+i*pixelsWidth+j]; for (i=0;i<size;i++) for (j=0;j<size;j++) kernel [i*size+j]=pixels[base+i*pixelsWidth+j];
} }
//======================================================= //=======================================================
public void savePartialKernelStack( public void savePartialKernelStack(
String path, String path,
ImageStack stack, ImageStack stack,
...@@ -2148,9 +2149,9 @@ public class EyesisAberrations { ...@@ -2148,9 +2149,9 @@ public class EyesisAberrations {
FileSaver fs=new FileSaver(impPsf); FileSaver fs=new FileSaver(impPsf);
fs.saveAsTiffStack(path); fs.saveAsTiffStack(path);
} }
private ImageStack mergeKernelsToStack(double [][][][] kernels) { private ImageStack mergeKernelsToStack(double [][][][] kernels) {
return mergeKernelsToStack(kernels,null); return mergeKernelsToStack(kernels,null);
...@@ -2223,7 +2224,7 @@ public class EyesisAberrations { ...@@ -2223,7 +2224,7 @@ public class EyesisAberrations {
public double [][][][] createPSFMap( public double [][][][] createPSFMap(
final MatchSimulatedPattern commonMatchSimulatedPattern, // to be cloned in threads, using common data final MatchSimulatedPattern commonMatchSimulatedPattern, // to be cloned in threads, using common data
final ImagePlus imp_sel, // linearized Bayer mosaic image from the camera, GR/BG final ImagePlus imp_sel, // linearized Bayer mosaic image from the camera, GR/BG
final int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent pdfKernelMap structure) final int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent pdfKernelMap structure)
final double overexposedAllowed, // fraction of pixels OK to be overexposed final double overexposedAllowed, // fraction of pixels OK to be overexposed
final SimulationPattern.SimulParameters simulParameters, final SimulationPattern.SimulParameters simulParameters,
final int mapFFTsize, // scanImageForPatterns:FFT size final int mapFFTsize, // scanImageForPatterns:FFT size
...@@ -2231,7 +2232,7 @@ public class EyesisAberrations { ...@@ -2231,7 +2232,7 @@ public class EyesisAberrations {
final int fft_overlap, final int fft_overlap,
final int fft_size, final int fft_size,
final ColorComponents colorComponents, final ColorComponents colorComponents,
final int PSF_subpixel, final int PSF_subpixel,
final OTFFilterParameters otfFilterParameters, final OTFFilterParameters otfFilterParameters,
final PSFParameters psfParameters, final PSFParameters psfParameters,
final double minDefinedArea, final double minDefinedArea,
...@@ -2250,7 +2251,7 @@ public class EyesisAberrations { ...@@ -2250,7 +2251,7 @@ public class EyesisAberrations {
runtime.gc(); runtime.gc();
if (globalDebugLevel>1) System.out.println("--- Free memory="+runtime.freeMemory()+" (of "+runtime.totalMemory()+")"); if (globalDebugLevel>1) System.out.println("--- Free memory="+runtime.freeMemory()+" (of "+runtime.totalMemory()+")");
// Generate hi-res pattern bitmap (one cell) // Generate hi-res pattern bitmap (one cell)
SimulationPattern simulationPattern= new SimulationPattern(); SimulationPattern simulationPattern= new SimulationPattern();
simulationPattern.debugLevel=globalDebugLevel; simulationPattern.debugLevel=globalDebugLevel;
final double [] bitmaskPattern= simulationPattern.patternGenerator(simulParameters); final double [] bitmaskPattern= simulationPattern.patternGenerator(simulParameters);
...@@ -2285,7 +2286,7 @@ public class EyesisAberrations { ...@@ -2285,7 +2286,7 @@ public class EyesisAberrations {
// globalDebugLevel=debug_level; // globalDebugLevel=debug_level;
simulationPattern.debugLevel=globalDebugLevel; simulationPattern.debugLevel=globalDebugLevel;
int ncell=0; int ncell=0;
/* Create array of coordinates of cells to process, fill result array with zeros (to be actually written by threads */ /* Create array of coordinates of cells to process, fill result array with zeros (to be actually written by threads */
final int [][] tilesToProcessXY=new int [numPatternCells][4]; final int [][] tilesToProcessXY=new int [numPatternCells][4];
for (nTileY=0;nTileY<PSFBooleanMap.length;nTileY++) for (nTileX=0;nTileX<PSFBooleanMap[0].length;nTileX++){ for (nTileY=0;nTileY<PSFBooleanMap.length;nTileY++) for (nTileX=0;nTileX<PSFBooleanMap[0].length;nTileX++){
...@@ -2309,16 +2310,17 @@ public class EyesisAberrations { ...@@ -2309,16 +2310,17 @@ public class EyesisAberrations {
final double [] overexposed=(overexposedAllowed>0)?JP4_INSTANCE.overexposedMap (imp_sel):null; final double [] overexposed=(overexposedAllowed>0)?JP4_INSTANCE.overexposedMap (imp_sel):null;
final int mapWidth=imp_sel.getWidth(); final int mapWidth=imp_sel.getWidth();
final AtomicInteger tilesFinishedAtomic = new AtomicInteger(1); // first finished will be 1 final AtomicInteger tilesFinishedAtomic = new AtomicInteger(1); // first finished will be 1
final int debugNumColors=6; final int debugNumColors=6;
for (int ithread = 0; ithread < threads.length; ithread++) { for (int ithread = 0; ithread < threads.length; ithread++) {
// Concurrently run in as many threads as CPUs // Concurrently run in as many threads as CPUs
threads[ithread] = new Thread() { threads[ithread] = new Thread() {
@Override
public void run() { public void run() {
// Each thread processes a few items in the total list // Each thread processes a few items in the total list
// Each loop iteration within the run method has a unique 'i' number to work with // Each loop iteration within the run method has a unique 'i' number to work with
// and to use as index in the results array: // and to use as index in the results array:
// double [] sum_kern_el=new double[6]; // just testing // double [] sum_kern_el=new double[6]; // just testing
int x0,y0,nTX,nTY,nChn; int x0,y0,nTX,nTY,nChn;
double [][] kernels; double [][] kernels;
// change to true (first 2 only?) to separate memory arrays for threads // change to true (first 2 only?) to separate memory arrays for threads
...@@ -2336,7 +2338,7 @@ public class EyesisAberrations { ...@@ -2336,7 +2338,7 @@ public class EyesisAberrations {
double [] windowFullFFTSize=matchSimulatedPattern.initWindowFunction(fft_size*PSF_subpixel,gaussWidth); //=initHamming( fft_size*subpixel); double [] windowFullFFTSize=matchSimulatedPattern.initWindowFunction(fft_size*PSF_subpixel,gaussWidth); //=initHamming( fft_size*subpixel);
DoubleFHT fht_instance =new DoubleFHT(); // provide DoubleFHT instance to save on initializations (or null) DoubleFHT fht_instance =new DoubleFHT(); // provide DoubleFHT instance to save on initializations (or null)
double over; double over;
// individual per-thread - will be needed when converted to doubleFHT // individual per-thread - will be needed when converted to doubleFHT
// MatchSimulatedPattern matchSimulatedPattern=new MatchSimulatedPattern(FFT_SIZE); // MatchSimulatedPattern matchSimulatedPattern=new MatchSimulatedPattern(FFT_SIZE);
for (int nTile = ai.getAndIncrement(); nTile < patternCells; nTile = ai.getAndIncrement()) { for (int nTile = ai.getAndIncrement(); nTile < patternCells; nTile = ai.getAndIncrement()) {
nTX=tilesToProcessXY[nTile][0]; nTX=tilesToProcessXY[nTile][0];
...@@ -2360,7 +2362,7 @@ public class EyesisAberrations { ...@@ -2360,7 +2362,7 @@ public class EyesisAberrations {
} else { } else {
if (debugLateralShifts) { if (debugLateralShifts) {
debugLateral[nTY][nTX]= new double [debugNumColors][]; // X/Y shift of the PSF array, in Bayer component pixel coordinates (same as PSF arrays) debugLateral[nTY][nTX]= new double [debugNumColors][]; // X/Y shift of the PSF array, in Bayer component pixel coordinates (same as PSF arrays)
} }
kernels=getPSFKernels(imp_sel, kernels=getPSFKernels(imp_sel,
simArray, //simulation image, scaled PSF_subpixel/2 simArray, //simulation image, scaled PSF_subpixel/2
2*fft_size, // size in pixels (twice fft_size) 2*fft_size, // size in pixels (twice fft_size)
...@@ -2371,7 +2373,7 @@ public class EyesisAberrations { ...@@ -2371,7 +2373,7 @@ public class EyesisAberrations {
patternDetectParameters, patternDetectParameters,
windowFFTSize, //=initHamming( fft_size) calculate once windowFFTSize, //=initHamming( fft_size) calculate once
windowFullFFTSize,//=initHamming( fft_size*subpixel); windowFullFFTSize,//=initHamming( fft_size*subpixel);
PSF_subpixel, // use finer grid than actual pixels PSF_subpixel, // use finer grid than actual pixels
simulParameters, simulParameters,
colorComponents, // color channels to process, equalizeGreens colorComponents, // color channels to process, equalizeGreens
otfFilterParameters, otfFilterParameters,
...@@ -2399,7 +2401,8 @@ public class EyesisAberrations { ...@@ -2399,7 +2401,8 @@ public class EyesisAberrations {
} }
final int numFinished=tilesFinishedAtomic.getAndIncrement(); final int numFinished=tilesFinishedAtomic.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
public void run() { @Override
public void run() {
IJ.showProgress(numFinished,patternCells); IJ.showProgress(numFinished,patternCells);
} }
}); });
...@@ -2436,7 +2439,7 @@ public class EyesisAberrations { ...@@ -2436,7 +2439,7 @@ public class EyesisAberrations {
for (nTileY=0;nTileY<debugLateral.length;nTileY++) for (nTileX=0;nTileX<debugLateral[0].length;nTileX++) if (debugLateral[nTileY][nTileX]!=null){ for (nTileY=0;nTileY<debugLateral.length;nTileY++) for (nTileX=0;nTileX<debugLateral[0].length;nTileX++) if (debugLateral[nTileY][nTileX]!=null){
if (debugLateral[nTileY][nTileX][cIndex[j]]!=null) dbgLat[layer][nTileY*debugLateral[0].length+nTileX]=debugLateral[nTileY][nTileX][cIndex[j]][i]; if (debugLateral[nTileY][nTileX][cIndex[j]]!=null) dbgLat[layer][nTileY*debugLateral[0].length+nTileX]=debugLateral[nTileY][nTileX][cIndex[j]][i];
} layer++; } layer++;
} }
SDFA_INSTANCE.showArrays(dbgLat, debugLateral[0].length, debugLateral.length, true, "lateral"+imp_sel.getTitle(), debugTitles); SDFA_INSTANCE.showArrays(dbgLat, debugLateral[0].length, debugLateral.length, true, "lateral"+imp_sel.getTitle(), debugTitles);
/* /*
debugLateralTile[i][0]=lateralChromatic[i][0]; debugLateralTile[i][0]=lateralChromatic[i][0];
...@@ -2485,7 +2488,7 @@ public class EyesisAberrations { ...@@ -2485,7 +2488,7 @@ public class EyesisAberrations {
} }
return pixels; return pixels;
} }
/* /*
private double [] combineDiagonalGreens (double [] green0, double []green3, int half_width, int half_height) { private double [] combineDiagonalGreens (double [] green0, double []green3, int half_width, int half_height) {
int y,x,base; int y,x,base;
int base_b=0; int base_b=0;
...@@ -2534,7 +2537,7 @@ public class EyesisAberrations { ...@@ -2534,7 +2537,7 @@ public class EyesisAberrations {
return pixels; return pixels;
} }
/* inserts zeros between pixels */ /* inserts zeros between pixels */
private double [][] oversampleFFTInput (double[][] input_pixels, private double [][] oversampleFFTInput (double[][] input_pixels,
int ratio) { int ratio) {
double [][] pixels=new double[input_pixels.length][]; double [][] pixels=new double[input_pixels.length][];
...@@ -2640,7 +2643,7 @@ public class EyesisAberrations { ...@@ -2640,7 +2643,7 @@ public class EyesisAberrations {
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
double [] Hamming, //=initHamming( fft_size) calculate once double [] Hamming, //=initHamming( fft_size) calculate once
double [] fullHamming, //=initHamming( fft_size*subpixel); double [] fullHamming, //=initHamming( fft_size*subpixel);
int subpixel, // use finer grid than actual pixels int subpixel, // use finer grid than actual pixels
SimulationPattern.SimulParameters simulParameters, SimulationPattern.SimulParameters simulParameters,
EyesisAberrations.ColorComponents colorComponents, EyesisAberrations.ColorComponents colorComponents,
EyesisAberrations.OTFFilterParameters otfFilterParameters, EyesisAberrations.OTFFilterParameters otfFilterParameters,
...@@ -2654,7 +2657,7 @@ public class EyesisAberrations { ...@@ -2654,7 +2657,7 @@ public class EyesisAberrations {
){ ){
boolean debugThis=false; //(y0==384) && ((x0==448) || (x0==512)); boolean debugThis=false; //(y0==384) && ((x0==448) || (x0==512));
if (globalDebugLevel>1){ if (globalDebugLevel>1){
System.out.println("getPSFKernels(), simArray is "+((simArray==null)?"":"not ")+"null"); System.out.println("getPSFKernels(), simArray is "+((simArray==null)?"":"not ")+"null");
} }
if (imp==null) return null; // Maybe convert to double pixel array once to make it faster? if (imp==null) return null; // Maybe convert to double pixel array once to make it faster?
...@@ -2669,16 +2672,18 @@ public class EyesisAberrations { ...@@ -2669,16 +2672,18 @@ public class EyesisAberrations {
double [][] simul_pixels; double [][] simul_pixels;
double [][]wVectors=new double[2][2]; double [][]wVectors=new double[2][2];
int imgWidth=imp.getWidth(); int imgWidth=imp.getWidth();
double [][] dbgSimPix=null; double [][] dbgSimPix=null;
double [] localBarray; double [] localBarray;
if ((simArray==null) || (psfParameters.approximateGrid)){ // just for testing if ((simArray==null) || (psfParameters.approximateGrid)){ // just for testing
/* Calculate pattern parameters, including distortion */ /* Calculate pattern parameters, including distortion */
if (matchSimulatedPattern.PATTERN_GRID==null) { if (matchSimulatedPattern.PATTERN_GRID==null) {
double[][] distortedPattern= matchSimulatedPattern.findPatternDistorted(input_bayer, // pixel array to process (no windowing!) double[][] distortedPattern= matchSimulatedPattern.findPatternDistorted(input_bayer, // pixel array to process (no windowing!)
patternDetectParameters, patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
true, //(greensToProcess==4), // boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly true, //(greensToProcess==4), // boolean greens, // this is a pattern for combined greens (diagonal), adjust results accordingly
title); // title prefix to use for debug images title); // title prefix to use for debug images
...@@ -2765,10 +2770,10 @@ public class EyesisAberrations { ...@@ -2765,10 +2770,10 @@ public class EyesisAberrations {
if (!colorComponents.colorsToCorrect[i]) simul_pixels[i]=null; // removed unused if (!colorComponents.colorsToCorrect[i]) simul_pixels[i]=null; // removed unused
} }
simul_pixels= normalizeAndWindow (simul_pixels, fullHamming); simul_pixels= normalizeAndWindow (simul_pixels, fullHamming);
} else { } else {
Rectangle PSFCellSim=new Rectangle (x0*subpixel/2,y0*subpixel/2,size*subpixel/2,size*subpixel/2); Rectangle PSFCellSim=new Rectangle (x0*subpixel/2,y0*subpixel/2,size*subpixel/2,size*subpixel/2);
simul_pixels=new double[6][]; simul_pixels=new double[6][];
// simulationPattern.debugLevel=globalDebugLevel; // simulationPattern.debugLevel=globalDebugLevel;
for (i=0;i<simul_pixels.length; i++) { for (i=0;i<simul_pixels.length; i++) {
...@@ -2783,7 +2788,7 @@ public class EyesisAberrations { ...@@ -2783,7 +2788,7 @@ public class EyesisAberrations {
//System.out.println("PSFCell.y="+PSFCell.y+" PSFCell.height="+PSFCell.height+" imgWidth="+imgWidth+" PSFCell.x="+PSFCell.x+" PSFCell.width="+PSFCell.width+" matchSimulatedPattern.UV_INDEX.length="+matchSimulatedPattern.UV_INDEX.length); //System.out.println("PSFCell.y="+PSFCell.y+" PSFCell.height="+PSFCell.height+" imgWidth="+imgWidth+" PSFCell.x="+PSFCell.x+" PSFCell.width="+PSFCell.width+" matchSimulatedPattern.UV_INDEX.length="+matchSimulatedPattern.UV_INDEX.length);
int index=matchSimulatedPattern.getUVIndex((PSFCell.y+PSFCell.height/2)*imgWidth+(PSFCell.x+PSFCell.width/2)); int index=matchSimulatedPattern.getUVIndex((PSFCell.y+PSFCell.height/2)*imgWidth+(PSFCell.x+PSFCell.width/2));
// int index=matchSimulatedPattern.getUVIndex((PSFCell.y+PSFCell.height/2)*matchSimulatedPattern.getWOI().width+(PSFCell.x+PSFCell.width/2)); // int index=matchSimulatedPattern.getUVIndex((PSFCell.y+PSFCell.height/2)*matchSimulatedPattern.getWOI().width+(PSFCell.x+PSFCell.width/2));
if (index<0) { if (index<0) {
System.out.println ("Error, No UV pattern @ x="+(PSFCell.x+PSFCell.width/2)+", y="+(PSFCell.y+PSFCell.height/2)); System.out.println ("Error, No UV pattern @ x="+(PSFCell.x+PSFCell.width/2)+", y="+(PSFCell.y+PSFCell.height/2));
return null; return null;
...@@ -2806,7 +2811,7 @@ public class EyesisAberrations { ...@@ -2806,7 +2811,7 @@ public class EyesisAberrations {
//TODO: Need to define wave vectors here - how? //TODO: Need to define wave vectors here - how?
wVectors[0]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],1); //null pointer wVectors[0]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],1); //null pointer
wVectors[1]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],2); wVectors[1]=matchSimulatedPattern.getDArray(iUV[1],iUV[0],2);
// should it be averaged WV? // should it be averaged WV?
if (globalDebugLevel>2) System.out.println ( " x0="+x0+" y0="+y0); if (globalDebugLevel>2) System.out.println ( " x0="+x0+" y0="+y0);
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(input_bayer, true, title+"-in"); if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(input_bayer, true, title+"-in");
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-S"); if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simul_pixels, true, title+"-S");
...@@ -2820,7 +2825,7 @@ public class EyesisAberrations { ...@@ -2820,7 +2825,7 @@ public class EyesisAberrations {
} }
simul_pixels= normalizeAndWindow (simul_pixels, fullHamming); simul_pixels= normalizeAndWindow (simul_pixels, fullHamming);
} }
input_bayer= normalizeAndWindow (input_bayer, Hamming); input_bayer= normalizeAndWindow (input_bayer, Hamming);
if (subpixel>1) { if (subpixel>1) {
input_bayer= oversampleFFTInput (input_bayer,subpixel); input_bayer= oversampleFFTInput (input_bayer,subpixel);
...@@ -2902,7 +2907,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -2902,7 +2907,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
System.out.println(x0+":"+y0+"1-PSF_shifts.length= "+PSF_shifts.length+" i="+i+" input_bayer.length="+input_bayer.length); System.out.println(x0+":"+y0+"1-PSF_shifts.length= "+PSF_shifts.length+" i="+i+" input_bayer.length="+input_bayer.length);
System.out.println("Before: color Component "+i+" PSF_shifts["+i+"][0]="+IJ.d2s(PSF_shifts[i][0],3)+ System.out.println("Before: color Component "+i+" PSF_shifts["+i+"][0]="+IJ.d2s(PSF_shifts[i][0],3)+
" PSF_shifts["+i+"][1]="+IJ.d2s(PSF_shifts[i][1],3)); " PSF_shifts["+i+"][1]="+IJ.d2s(PSF_shifts[i][1],3));
} }
kernels[i]=combinePSF (inverted[i], // Square array of pixels with multiple repeated PSF (alternating sign) kernels[i]=combinePSF (inverted[i], // Square array of pixels with multiple repeated PSF (alternating sign)
...@@ -2938,7 +2943,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -2938,7 +2943,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
System.out.println(x0+":"+y0+"Before: color Component "+i+" PSF_shifts["+i+"][0]="+IJ.d2s(PSF_shifts[i][0],3)+ System.out.println(x0+":"+y0+"Before: color Component "+i+" PSF_shifts["+i+"][0]="+IJ.d2s(PSF_shifts[i][0],3)+
" PSF_shifts["+i+"][1]="+IJ.d2s(PSF_shifts[i][1],3)); " PSF_shifts["+i+"][1]="+IJ.d2s(PSF_shifts[i][1],3));
} }
kernels[i]=combinePSF (inverted[i], // Square array of pixels with multiple repeated PSF (alternating sign) kernels[i]=combinePSF (inverted[i], // Square array of pixels with multiple repeated PSF (alternating sign)
false, // !master, use ignoreChromatic false, // !master, use ignoreChromatic
PSF_shifts[i], // centerXY[] - will be modified inside combinePSF() if psfParameters.ignoreChromatic is true PSF_shifts[i], // centerXY[] - will be modified inside combinePSF() if psfParameters.ignoreChromatic is true
...@@ -2992,8 +2997,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -2992,8 +2997,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} else { } else {
debugLateralTile[i]=null; debugLateralTile[i]=null;
} }
} }
if (debugThis && (kernels!=null)){ if (debugThis && (kernels!=null)){
int debugSize=0; int debugSize=0;
...@@ -3116,7 +3121,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3116,7 +3121,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
int debug, int debug,
int globalDebugLevel, int globalDebugLevel,
String title){ String title){
double [] denominatorPixels= forward_OTF? modelPixels.clone(): measuredPixels.clone(); double [] denominatorPixels= forward_OTF? modelPixels.clone(): measuredPixels.clone();
double [] nominatorPixels= forward_OTF? measuredPixels.clone(): modelPixels.clone(); double [] nominatorPixels= forward_OTF? measuredPixels.clone(): modelPixels.clone();
if (fht_instance==null) fht_instance=new DoubleFHT(); // move upstream to reduce number of initializations if (fht_instance==null) fht_instance=new DoubleFHT(); // move upstream to reduce number of initializations
...@@ -3170,7 +3175,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3170,7 +3175,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
SDFA_INSTANCE.showArrays(mask1, "M1A-"+title); SDFA_INSTANCE.showArrays(mask1, "M1A-"+title);
} }
} }
/* Mask already includes zeros on ps, so we can just use divisions of FHT*/ /* Mask already includes zeros on ps, so we can just use divisions of FHT*/
//Swapping quadrants of the nominator, so the center will be 0,0 //Swapping quadrants of the nominator, so the center will be 0,0
fht_instance.swapQuadrants(nominatorPixels); fht_instance.swapQuadrants(nominatorPixels);
//get to frequency domain //get to frequency domain
...@@ -3178,11 +3183,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3178,11 +3183,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
if ((debug>2) ||((globalDebugLevel>2) && (title!=""))) { /* Increase debug evel later */ // was 3 if ((debug>2) ||((globalDebugLevel>2) && (title!=""))) { /* Increase debug evel later */ // was 3
SDFA_INSTANCE.showArrays(nominatorPixels, title+"-NOM-FHT"); SDFA_INSTANCE.showArrays(nominatorPixels, title+"-NOM-FHT");
SDFA_INSTANCE.showArrays(denominatorPixels, title+"-DENOM-FHT"); SDFA_INSTANCE.showArrays(denominatorPixels, title+"-DENOM-FHT");
} }
double [] pixels=fht_instance.divide(nominatorPixels,denominatorPixels); double [] pixels=fht_instance.divide(nominatorPixels,denominatorPixels);
if ((debug>2) ||((globalDebugLevel>2) && (title!=""))) { /* Increase debug evel later */ // was 3 if ((debug>2) ||((globalDebugLevel>2) && (title!=""))) { /* Increase debug evel later */ // was 3
SDFA_INSTANCE.showArrays(pixels, title+"-DECONV"); SDFA_INSTANCE.showArrays(pixels, title+"-DECONV");
} }
for (i=0;i<pixels.length;i++) { for (i=0;i<pixels.length;i++) {
if (mask[i]==0.0) pixels[i]=0.0; // preventing NaN*0.0 if (mask[i]==0.0) pixels[i]=0.0; // preventing NaN*0.0
else pixels[i]*=mask[i]; else pixels[i]*=mask[i];
...@@ -3191,7 +3196,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3191,7 +3196,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
SDFA_INSTANCE.showArrays(pixels, title+"-MASKED"); SDFA_INSTANCE.showArrays(pixels, title+"-MASKED");
double [][] aphase=fht_instance.fht2AmpHase(pixels,true); double [][] aphase=fht_instance.fht2AmpHase(pixels,true);
SDFA_INSTANCE.showArrays(aphase, true,"AP="+title+"-MASKED"); SDFA_INSTANCE.showArrays(aphase, true,"AP="+title+"-MASKED");
} }
if (gaps_sigma>0.0){ if (gaps_sigma>0.0){
double [][] fft_reIm_centered=fht_instance.fht2ReIm(pixels, true); //0 in the center, full square double [][] fft_reIm_centered=fht_instance.fht2ReIm(pixels, true); //0 in the center, full square
...@@ -3210,7 +3215,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3210,7 +3215,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
fht_instance.swapQuadrants(fft_reIm_centered[0]); // zero in the corner fht_instance.swapQuadrants(fft_reIm_centered[0]); // zero in the corner
fht_instance.swapQuadrants(fft_reIm_centered[1]); // zero in the corner fht_instance.swapQuadrants(fft_reIm_centered[1]); // zero in the corner
pixels=fht_instance.FFTHalf2FHT(fft_reIm_centered, size); pixels=fht_instance.FFTHalf2FHT(fft_reIm_centered, size);
//mask_denoise //mask_denoise
} }
/// transform to space /// transform to space
fht_instance.inverseTransform(pixels); fht_instance.inverseTransform(pixels);
...@@ -3278,7 +3283,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3278,7 +3283,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
cloneY=(iy+cloneNy*cloneStep)%size; cloneY=(iy+cloneNy*cloneStep)%size;
cloneX=(ix+cloneNx*cloneStep)%size; cloneX=(ix+cloneNx*cloneStep)%size;
mask[cloneY*size+cloneX]+=psWithZero[iy*size+ix]; mask[cloneY*size+cloneX]+=psWithZero[iy*size+ix];
} }
} }
/* debug show the mask */ /* debug show the mask */
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(mask, "PS-cloned"); if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(mask, "PS-cloned");
...@@ -3300,14 +3305,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3300,14 +3305,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
a=(2.0 * mask[i] - th - tl)/(th - tl); a=(2.0 * mask[i] - th - tl)/(th - tl);
mask[i]=0.5*(1.0-a*a*a); mask[i]=0.5*(1.0-a*a*a);
} }
// now mask out zeros on the ps // now mask out zeros on the ps
if (ps[i]<min) mask[i]=0.0; if (ps[i]<min) mask[i]=0.0;
else { else {
mask[i]*=ps[i]/(ps[i]+k2); mask[i]*=ps[i]/(ps[i]+k2);
} }
} }
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(mask, "mask-all"); if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(mask, "mask-all");
/* zeros are now for FHT - in the top left corner */ /* zeros are now for FHT - in the top left corner */
fht_instance.swapQuadrants(mask); fht_instance.swapQuadrants(mask);
return mask; return mask;
} }
...@@ -3335,7 +3340,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3335,7 +3340,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
for (index=0;index<len;index++) absThresh+=windowFunction[index]; for (index=0;index<len;index++) absThresh+=windowFunction[index];
absThresh*=threshold; absThresh*=threshold;
if (debugLevel>1) System.out.println(" threshold="+threshold+" absThresh="+absThresh); if (debugLevel>1) System.out.println(" threshold="+threshold+" absThresh="+absThresh);
int y,x,y0,x0; int y,x,y0,x0;
for (int tileY=0;tileY<tileHeight;tileY++) for (int tileX=0;tileX<tileWidth;tileX++) { for (int tileY=0;tileY<tileHeight;tileY++) for (int tileX=0;tileX<tileWidth;tileX++) {
y0=-tileSize/2+margin+tileStep*tileY; y0=-tileSize/2+margin+tileStep*tileY;
...@@ -3353,19 +3358,19 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3353,19 +3358,19 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} }
return result; return result;
} }
/* ======================================================================== /* ========================================================================
/** /**
* Mostly done, need to move where szis\ * Mostly done, need to move where szis\
* TODO: currently the shift of the PSF during binning is done with the integer steps. If ignoreChromatic - to all colors * TODO: currently the shift of the PSF during binning is done with the integer steps. If ignoreChromatic - to all colors
* independently, if it is false - all components are moved in sync, but again - with integer steps. That causes * independently, if it is false - all components are moved in sync, but again - with integer steps. That causes
* mis-match between the PSF calculated in nearly identical runs (i.e. use the data shifted by 2 pixels) caused by 1 pixel shift. * mis-match between the PSF calculated in nearly identical runs (i.e. use the data shifted by 2 pixels) caused by 1 pixel shift.
* That can be improved if PSF are shifted smoothly (not so easy though). It is probably already handled when averaging PSF - * That can be improved if PSF are shifted smoothly (not so easy though). It is probably already handled when averaging PSF -
* amplitude and phase is handled separately so shift should be OK. * amplitude and phase is handled separately so shift should be OK.
* *
*/ */
double [] combinePSF (double []pixels, // Square array of pixels with multiple repeated PSF (alternating sign) double [] combinePSF (double []pixels, // Square array of pixels with multiple repeated PSF (alternating sign)
boolean master, // force ignoreChromatic boolean master, // force ignoreChromatic
double[] centerXY, // coordinates (x,y) of the center point (will update if ignoreChromatic is true) double[] centerXY, // coordinates (x,y) of the center point (will update if ignoreChromatic is true)
...@@ -3439,17 +3444,17 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3439,17 +3444,17 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
debug, debug,
debugLevel); debugLevel);
// true); // true);
if (!master && !psfParameters.ignoreChromatic && !psfParameters.absoluteCenter && psfParameters.centerPSF && (centerXY!=null)){ if (!master && !psfParameters.ignoreChromatic && !psfParameters.absoluteCenter && psfParameters.centerPSF && (centerXY!=null)){
// System.out.println("1:pixelsPSF.length="+pixelsPSF.length+" outSize+"+outSize); // System.out.println("1:pixelsPSF.length="+pixelsPSF.length+" outSize+"+outSize);
// TODO: Shift +/- 0.5 Pix here {centerXY[0]-Math.round(centerXY[0]),centerXY[1]-Math.round(centerXY[1])} // TODO: Shift +/- 0.5 Pix here {centerXY[0]-Math.round(centerXY[0]),centerXY[1]-Math.round(centerXY[1])}
if (fht_instance==null) fht_instance=new DoubleFHT(); if (fht_instance==null) fht_instance=new DoubleFHT();
// fht_instance.debug=(centerXY[0]-Math.round(centerXY[0]))<-0.4; // just reducing number // fht_instance.debug=(centerXY[0]-Math.round(centerXY[0]))<-0.4; // just reducing number
// double dx=centerXY[0]-Math.round(centerXY[0]); // double dx=centerXY[0]-Math.round(centerXY[0]);
// double dy=centerXY[1]-Math.round(centerXY[1]); // double dy=centerXY[1]-Math.round(centerXY[1]);
// if (dx<-0.4) SDFA_INSTANCE.showArrays(pixelsPSF.clone(), "before:"+dx+":"+dy); // if (dx<-0.4) SDFA_INSTANCE.showArrays(pixelsPSF.clone(), "before:"+dx+":"+dy);
pixelsPSF=fht_instance.translateSubPixel ( pixelsPSF=fht_instance.translateSubPixel (
pixelsPSF, pixelsPSF,
-(centerXY[0]-Math.round(centerXY[0])), -(centerXY[0]-Math.round(centerXY[0])),
...@@ -3515,7 +3520,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3515,7 +3520,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
debugLevel); debugLevel);
if (psfParameters.centerPSF && (centerXY!=null)){ if (psfParameters.centerPSF && (centerXY!=null)){
// System.out.println("2:pixelsPSF.length="+pixelsPSF.length+" outSize+"+outSize); // System.out.println("2:pixelsPSF.length="+pixelsPSF.length+" outSize+"+outSize);
// TODO: Shift +/- 0.5 Pix here {centerXY[0]-Math.round(centerXY[0]),centerXY[1]-Math.round(centerXY[1])} // TODO: Shift +/- 0.5 Pix here {centerXY[0]-Math.round(centerXY[0]),centerXY[1]-Math.round(centerXY[1])}
if (fht_instance==null) fht_instance=new DoubleFHT(); if (fht_instance==null) fht_instance=new DoubleFHT();
// fht_instance.debug=(centerXY[0]-Math.round(centerXY[0]))<-0.4; // just reducing number // fht_instance.debug=(centerXY[0]-Math.round(centerXY[0]))<-0.4; // just reducing number
pixelsPSF=fht_instance.translateSubPixel ( pixelsPSF=fht_instance.translateSubPixel (
...@@ -3549,14 +3554,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3549,14 +3554,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
if (debugLevel>2) System.out.println("Centroid after second binPSF: x="+IJ.d2s(centroidXY[0],3)+" y="+IJ.d2s(centroidXY[1],3)+" center was at x="+IJ.d2s(centerXY[0],3)+" y="+IJ.d2s(centerXY[1],3)); if (debugLevel>2) System.out.println("Centroid after second binPSF: x="+IJ.d2s(centroidXY[0],3)+" y="+IJ.d2s(centroidXY[1],3)+" center was at x="+IJ.d2s(centerXY[0],3)+" y="+IJ.d2s(centerXY[1],3));
} }
/* compensate center point and/or add center-symmetrical points if enabled */ /* compensate center point and/or add center-symmetrical points if enabled */
double [] rejectedClonesPixels=null; double [] rejectedClonesPixels=null;
double [][] modelPSFVectors={{0.5*(g[0][0]+g[1][0]),0.5*(g[0][1]+g[1][1])}, double [][] modelPSFVectors={{0.5*(g[0][0]+g[1][0]),0.5*(g[0][1]+g[1][1])},
{0.5*(g[0][0]-g[1][0]),0.5*(g[0][1]-g[1][1])}}; {0.5*(g[0][0]-g[1][0]),0.5*(g[0][1]-g[1][1])}};
/********* removed subtraction of clones *****************************************************************/ /********* removed subtraction of clones *****************************************************************/
rejectedClonesPixels=pixelsPSF; // Maybe fo the opposite? rejectedClonesPixels=pixelsPSF; // Maybe fo the opposite?
maskClonesPSF(rejectedClonesPixels, // square pixel array where the model PSF is added maskClonesPSF(rejectedClonesPixels, // square pixel array where the model PSF is added
psfParameters.windowFrac, // multiply window by this value psfParameters.windowFrac, // multiply window by this value
...@@ -3578,7 +3583,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3578,7 +3583,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
centroidXY[0], // model PSF center X-coordinate (in pixels[] units, from the center of the array ) centroidXY[0], // model PSF center X-coordinate (in pixels[] units, from the center of the array )
centroidXY[1], // same for Y centroidXY[1], // same for Y
0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it 0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it
0, // int WOICenterY, // 0, // int WOICenterY, //
outSize, //int WOIWidth, reduce later outSize, //int WOIWidth, reduce later
outSize); //int WOIHeight) outSize); //int WOIHeight)
...@@ -3590,14 +3595,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3590,14 +3595,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
for (i=0;i<sigmas.length;i++) { for (i=0;i<sigmas.length;i++) {
kk=smoothPixelsPSF[i]/max1; kk=smoothPixelsPSF[i]/max1;
if (kk>varSigmaTop) sigmas[i]=minSigma; if (kk>varSigmaTop) sigmas[i]=minSigma;
else sigmas[i] = minSigma+ sigmas[i]*((varSigmaTop-kk)*(varSigmaTop-kk)/varSigmaTop/varSigmaTop); else sigmas[i] = minSigma+ sigmas[i]*((varSigmaTop-kk)*(varSigmaTop-kk)/varSigmaTop/varSigmaTop);
} }
double [] varFilteredPSF=variableGaussBlurr(rejectedClonesPixels, // input square pixel array, preferrably having many exact zeros (they will be skipped) double [] varFilteredPSF=variableGaussBlurr(rejectedClonesPixels, // input square pixel array, preferrably having many exact zeros (they will be skipped)
sigmas, // array of sigmas to be used for each pixel, matches pixels[] sigmas, // array of sigmas to be used for each pixel, matches pixels[]
3.5, // drop calculatin if farther then nSigma 3.5, // drop calculatin if farther then nSigma
0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it 0, // int WOICenterX, // window of interest in pixels[] array - do not generate data outside it
0, // int WOICenterY, // 0, // int WOICenterY, //
outSize, //int WOIWidth, reduce later outSize, //int WOIWidth, reduce later
outSize, outSize,
debugLevel); //int WOIHeight) debugLevel); //int WOIHeight)
...@@ -3655,13 +3660,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3655,13 +3660,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
double [] rslt={a[0]+b[0], a[1]+b[1]}; double [] rslt={a[0]+b[0], a[1]+b[1]};
return rslt; return rslt;
} }
public double [][] matrix2x2_transp(double [][] m ){ public double [][] matrix2x2_transp(double [][] m ){
double [][] rslt= {{ m[0][0], m[1][0]}, double [][] rslt= {{ m[0][0], m[1][0]},
{ m[0][1], m[1][1]}}; { m[0][1], m[1][1]}};
return rslt; return rslt;
} }
/* ======================================================================== */ /* ======================================================================== */
/* zeroes out area outside of the area bound by 4 negative clones (or a fraction of it), either sharp or with Hamming */ /* zeroes out area outside of the area bound by 4 negative clones (or a fraction of it), either sharp or with Hamming */
private double [] maskClonesPSF(double [] pixels, // square pixel array where the model PSF is added private double [] maskClonesPSF(double [] pixels, // square pixel array where the model PSF is added
...@@ -3697,7 +3702,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3697,7 +3702,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
double []sigmas, // array of sigmas to be used for each pixel, matches pixels[] double []sigmas, // array of sigmas to be used for each pixel, matches pixels[]
double nSigma, // drop calculatin if farther then nSigma double nSigma, // drop calculatin if farther then nSigma
int WOICenterX, // window of interest in pixels[] array - do not generate data outside it int WOICenterX, // window of interest in pixels[] array - do not generate data outside it
int WOICenterY, // int WOICenterY, //
int WOIWidth, // int WOIWidth, //
int WOIHeight, int WOIHeight,
int globalDebugLevel){ // int globalDebugLevel){ //
...@@ -3760,9 +3765,9 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3760,9 +3765,9 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} }
return result; return result;
} }
/* ======================================================================== */ /* ======================================================================== */
/* find ellipse approximating section of the PSF, scale ellipse and use it as a mask to remove PSF far wings */ /* find ellipse approximating section of the PSF, scale ellipse and use it as a mask to remove PSF far wings */
private double [] cutPSFWings (double [] psf_pixels, // direct PSF function, square array, may be proportionally larger than reversed private double [] cutPSFWings (double [] psf_pixels, // direct PSF function, square array, may be proportionally larger than reversed
...@@ -3866,7 +3871,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3866,7 +3871,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
double xc, // model PSF center X-coordinate (in pixels[] units, from the center of the array ) double xc, // model PSF center X-coordinate (in pixels[] units, from the center of the array )
double yc, // same for Y double yc, // same for Y
int WOICenterX, // window of interest in pixels[] array - do not generate data outside it int WOICenterX, // window of interest in pixels[] array - do not generate data outside it
int WOICenterY, // int WOICenterY, //
int WOIWidth, // int WOIWidth, //
int WOIHeight) { int WOIHeight) {
int size = (int) Math.sqrt(pixels.length); int size = (int) Math.sqrt(pixels.length);
...@@ -4000,11 +4005,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4000,11 +4005,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
return result; return result;
} }
/* ======================================================================== */ /* ======================================================================== */
/* finds cluster on the PSF (with the center at specidfied point) by flooding from the specified center, so total energy is cutoff_energy fraction /* finds cluster on the PSF (with the center at specidfied point) by flooding from the specified center, so total energy is cutoff_energy fraction
returns integer array (same dimensions as input) with 1 - selected, 0 - not selected returns integer array (same dimensions as input) with 1 - selected, 0 - not selected
cutoff_energy: if positive - specifies fraction of total energy, if negative -cutoff_energy is the minimal value of the pixel to be included cutoff_energy: if positive - specifies fraction of total energy, if negative -cutoff_energy is the minimal value of the pixel to be included
UPDATE: follows gradient from the start point to a local maximum if "cutoff_energy" is negative" */ UPDATE: follows gradient from the start point to a local maximum if "cutoff_energy" is negative" */
private int [][] findClusterOnPSF( private int [][] findClusterOnPSF(
double [] psf, // PSF function, square array double [] psf, // PSF function, square array
...@@ -4148,7 +4153,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4148,7 +4153,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
ImageProcessor ip = new FloatProcessor(size,size); ImageProcessor ip = new FloatProcessor(size,size);
float [] floatPixels = new float [size*size]; float [] floatPixels = new float [size*size];
for (i=0;i<floatPixels.length;i++) { for (i=0;i<floatPixels.length;i++) {
floatPixels[i]=(float) clusterMap[i/size][i%size]; floatPixels[i]=clusterMap[i/size][i%size];
} }
ip.setPixels(floatPixels); ip.setPixels(floatPixels);
ip.resetMinAndMax(); ip.resetMinAndMax();
...@@ -4219,7 +4224,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4219,7 +4224,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
private double [] binPSF(double [] pixels, private double [] binPSF(double [] pixels,
double [][] g, double [][] g,
int outSize, int outSize,
// int decimate, // sub-pixel decimation // int decimate, // sub-pixel decimation
double minContrast, double minContrast,
double [] centerXY, // coordinates (x,y) of the center point (will be alway subtracted) double [] centerXY, // coordinates (x,y) of the center point (will be alway subtracted)
double[] symmXY, // coordinates (x,y) of the center of symmetry (to combine with 180 if enabled by symm180) double[] symmXY, // coordinates (x,y) of the center of symmetry (to combine with 180 if enabled by symm180)
...@@ -4242,9 +4247,9 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4242,9 +4247,9 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
double [][] xy2uv= {{-2.0*g[0][1]/det_g, 2.0*g[0][0]/det_g}, double [][] xy2uv= {{-2.0*g[0][1]/det_g, 2.0*g[0][0]/det_g},
{-2.0*g[1][1]/det_g, 2.0*g[1][0]/det_g}}; {-2.0*g[1][1]/det_g, 2.0*g[1][0]/det_g}};
double [][] uv2xy= matrix2x2_scale(matrix2x2_invert(xy2uv),2); // real pixels are twice double [][] uv2xy= matrix2x2_scale(matrix2x2_invert(xy2uv),2); // real pixels are twice
double [] pixelsPSF =new double [outSize*outSize]; double [] pixelsPSF =new double [outSize*outSize];
int [] pixelsPSFCount =new int [outSize*outSize]; int [] pixelsPSFCount =new int [outSize*outSize];
double [] pixelsPSFWeight =new double [outSize*outSize]; double [] pixelsPSFWeight =new double [outSize*outSize];
double [] center=centerXY; double [] center=centerXY;
for (i=0;i<contrastCache.length;i++) { for (i=0;i<contrastCache.length;i++) {
contrastCache[i]=-1.0; contrastCache[i]=-1.0;
...@@ -4305,7 +4310,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4305,7 +4310,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
/* Do binning itself here */ /* Do binning itself here */
d=PSF_sign*PSFAtXY(pixels, pixelSize, x,y); d=PSF_sign*PSFAtXY(pixels, pixelSize, x,y);
/* map to the segment around 0,0 */ /* map to the segment around 0,0 */
dp=p/2-Math.round(p/2); dp=p/2-Math.round(p/2);
dq=q/2-Math.round(q/2); dq=q/2-Math.round(q/2);
/* dp, dq are between +/- 0.5 - use them for Hamming windowing -NOT HERE, moved later*/ /* dp, dq are between +/- 0.5 - use them for Hamming windowing -NOT HERE, moved later*/
...@@ -4404,20 +4409,20 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4404,20 +4409,20 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
if (debug) { if (debug) {
SDFA_INSTANCE.showArrays(debugPixels, title+"_mask_PSF"); SDFA_INSTANCE.showArrays(debugPixels, title+"_mask_PSF");
double [] doublePixelsPSFCount=new double [pixelsPSF.length]; double [] doublePixelsPSFCount=new double [pixelsPSF.length];
for (j=0;j<doublePixelsPSFCount.length;j++) doublePixelsPSFCount[j]=(double)pixelsPSFCount[j]; for (j=0;j<doublePixelsPSFCount.length;j++) doublePixelsPSFCount[j]=pixelsPSFCount[j];
SDFA_INSTANCE.showArrays(doublePixelsPSFCount, title+"_PSF_bin_count"); SDFA_INSTANCE.showArrays(doublePixelsPSFCount, title+"_PSF_bin_count");
SDFA_INSTANCE.showArrays(pixelsPSFWeight, title+"_PSF_bin_weight"); SDFA_INSTANCE.showArrays(pixelsPSFWeight, title+"_PSF_bin_weight");
double [] doubleContrastCache=new double [contrastCache.length]; double [] doubleContrastCache=new double [contrastCache.length];
for (j=0;j<doubleContrastCache.length;j++) doubleContrastCache[j]=(double)((contrastCache[j]>=0.0)?contrastCache[j]:-0.00001); for (j=0;j<doubleContrastCache.length;j++) doubleContrastCache[j]=(contrastCache[j]>=0.0)?contrastCache[j]:-0.00001;
SDFA_INSTANCE.showArrays(doubleContrastCache, title+"_ContrastCache"); SDFA_INSTANCE.showArrays(doubleContrastCache, title+"_ContrastCache");
} }
return pixelsPSF; return pixelsPSF;
} }
/* ======================================================================== */ /* ======================================================================== */
/* Create a Thread[] array as large as the number of processors available. /* Create a Thread[] array as large as the number of processors available.
* From Stephan Preibisch's Multithreading.java class. See: * From Stephan Preibisch's Multithreading.java class. See:
...@@ -4441,7 +4446,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4441,7 +4446,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} }
try try
{ {
for (int ithread = 0; ithread < threads.length; ++ithread) for (int ithread = 0; ithread < threads.length; ++ithread)
threads[ithread].join(); threads[ithread].join();
} catch (InterruptedException ie) } catch (InterruptedException ie)
...@@ -4466,7 +4471,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4466,7 +4471,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public boolean fillMissing; // replace missing kernels with neighbors public boolean fillMissing; // replace missing kernels with neighbors
public MultiFilePSF ( public MultiFilePSF (
double overexposedMaxFraction, double overexposedMaxFraction,
double weightOnBorder, double weightOnBorder,
double radiusDiffLow, // do not remove partial kernel cell if radius differs from average less than by this fraction double radiusDiffLow, // do not remove partial kernel cell if radius differs from average less than by this fraction
double radiusDiffHigh, // remove this cell even if it is the only one double radiusDiffHigh, // remove this cell even if it is the only one
double shiftToRadiusContrib, // Center shift (in pixels) addition to the difference relative to radius difference (in pixels) double shiftToRadiusContrib, // Center shift (in pixels) addition to the difference relative to radius difference (in pixels)
...@@ -4480,7 +4485,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4480,7 +4485,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
boolean fillMissing boolean fillMissing
) { ) {
this.overexposedMaxFraction=overexposedMaxFraction; this.overexposedMaxFraction=overexposedMaxFraction;
this.weightOnBorder=weightOnBorder; this.weightOnBorder=weightOnBorder;
this.radiusDiffLow=radiusDiffLow; // do not remove partial kernel cell if radius differs from average less than by this fraction this.radiusDiffLow=radiusDiffLow; // do not remove partial kernel cell if radius differs from average less than by this fraction
this.radiusDiffHigh=radiusDiffHigh; // remove this cell even if it is the only one this.radiusDiffHigh=radiusDiffHigh; // remove this cell even if it is the only one
this.shiftToRadiusContrib=shiftToRadiusContrib; // Center shift (in pixels) addition to the difference relative to radius difference (in pixels) this.shiftToRadiusContrib=shiftToRadiusContrib; // Center shift (in pixels) addition to the difference relative to radius difference (in pixels)
...@@ -4525,7 +4530,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4525,7 +4530,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
properties.setProperty(prefix+"showWeights",this.showWeights+""); properties.setProperty(prefix+"showWeights",this.showWeights+"");
properties.setProperty(prefix+"fillMissing",this.fillMissing+""); properties.setProperty(prefix+"fillMissing",this.fillMissing+"");
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"overexposedMaxFraction")!=null) this.overexposedMaxFraction=Double.parseDouble(properties.getProperty(prefix+"overexposedMaxFraction")); if (properties.getProperty(prefix+"overexposedMaxFraction")!=null) this.overexposedMaxFraction=Double.parseDouble(properties.getProperty(prefix+"overexposedMaxFraction"));
if (properties.getProperty(prefix+"weightOnBorder")!=null) this.weightOnBorder=Double.parseDouble(properties.getProperty(prefix+"weightOnBorder")); if (properties.getProperty(prefix+"weightOnBorder")!=null) this.weightOnBorder=Double.parseDouble(properties.getProperty(prefix+"weightOnBorder"));
...@@ -4544,7 +4549,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4544,7 +4549,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
if (properties.getProperty(prefix+"validateShowEllipse")!=null)this.validateShowEllipse=Boolean.parseBoolean(properties.getProperty(prefix+"validateShowEllipse")); if (properties.getProperty(prefix+"validateShowEllipse")!=null)this.validateShowEllipse=Boolean.parseBoolean(properties.getProperty(prefix+"validateShowEllipse"));
if (properties.getProperty(prefix+"showWeights")!=null)this.showWeights=Boolean.parseBoolean(properties.getProperty(prefix+"showWeights")); if (properties.getProperty(prefix+"showWeights")!=null)this.showWeights=Boolean.parseBoolean(properties.getProperty(prefix+"showWeights"));
if (properties.getProperty(prefix+"fillMissing")!=null)this.fillMissing=Boolean.parseBoolean(properties.getProperty(prefix+"fillMissing")); if (properties.getProperty(prefix+"fillMissing")!=null)this.fillMissing=Boolean.parseBoolean(properties.getProperty(prefix+"fillMissing"));
} }
} }
...@@ -4582,15 +4587,15 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4582,15 +4587,15 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public String aberrationsPrefix="kernel-"; public String aberrationsPrefix="kernel-";
public String aberrationsSuffix=".kernel-tiff"; public String aberrationsSuffix=".kernel-tiff";
public boolean [] selectedChannels=null; public boolean [] selectedChannels=null;
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"sourceDirectory",this.sourceDirectory); properties.setProperty(prefix+"sourceDirectory",this.sourceDirectory);
properties.setProperty(prefix+"partialKernelDirectory",this.partialKernelDirectory); properties.setProperty(prefix+"partialKernelDirectory",this.partialKernelDirectory);
properties.setProperty(prefix+"psfKernelDirectory",this.psfKernelDirectory); properties.setProperty(prefix+"psfKernelDirectory",this.psfKernelDirectory);
properties.setProperty(prefix+"aberrationsKernelDirectory",this.aberrationsKernelDirectory); properties.setProperty(prefix+"aberrationsKernelDirectory",this.aberrationsKernelDirectory);
properties.setProperty(prefix+"autoRestore",this.autoRestore+""); properties.setProperty(prefix+"autoRestore",this.autoRestore+"");
properties.setProperty(prefix+"calibrationPath",this.calibrationPath); properties.setProperty(prefix+"calibrationPath",this.calibrationPath);
properties.setProperty(prefix+"strategyPath",this.strategyPath); properties.setProperty(prefix+"strategyPath",this.strategyPath);
...@@ -4606,8 +4611,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4606,8 +4611,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
properties.setProperty(prefix+"overwriteResultFiles",this.overwriteResultFiles+""); properties.setProperty(prefix+"overwriteResultFiles",this.overwriteResultFiles+"");
properties.setProperty(prefix+"partialToReprojected",this.partialToReprojected+""); properties.setProperty(prefix+"partialToReprojected",this.partialToReprojected+"");
properties.setProperty(prefix+"partialCorrectSensor",this.partialCorrectSensor+""); properties.setProperty(prefix+"partialCorrectSensor",this.partialCorrectSensor+"");
properties.setProperty(prefix+"seriesNumber",this.seriesNumber+""); properties.setProperty(prefix+"seriesNumber",this.seriesNumber+"");
properties.setProperty(prefix+"allImages",this.allImages+""); properties.setProperty(prefix+"allImages",this.allImages+"");
...@@ -4627,14 +4632,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4627,14 +4632,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
properties.setProperty(prefix+"selectedChannels",sSelectedChannels); properties.setProperty(prefix+"selectedChannels",sSelectedChannels);
} }
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"sourceDirectory")!=null) this.sourceDirectory=properties.getProperty(prefix+"sourceDirectory"); if (properties.getProperty(prefix+"sourceDirectory")!=null) this.sourceDirectory=properties.getProperty(prefix+"sourceDirectory");
if (properties.getProperty(prefix+"partialKernelDirectory")!=null) this.partialKernelDirectory=properties.getProperty(prefix+"partialKernelDirectory"); if (properties.getProperty(prefix+"partialKernelDirectory")!=null) this.partialKernelDirectory=properties.getProperty(prefix+"partialKernelDirectory");
if (properties.getProperty(prefix+"psfKernelDirectory")!=null) this.psfKernelDirectory=properties.getProperty(prefix+"psfKernelDirectory"); if (properties.getProperty(prefix+"psfKernelDirectory")!=null) this.psfKernelDirectory=properties.getProperty(prefix+"psfKernelDirectory");
if (properties.getProperty(prefix+"aberrationsKernelDirectory")!=null) this.aberrationsKernelDirectory=properties.getProperty(prefix+"aberrationsKernelDirectory"); if (properties.getProperty(prefix+"aberrationsKernelDirectory")!=null) this.aberrationsKernelDirectory=properties.getProperty(prefix+"aberrationsKernelDirectory");
if (properties.getProperty(prefix+"autoRestore")!=null) this.autoRestore=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestore")); if (properties.getProperty(prefix+"autoRestore")!=null) this.autoRestore=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestore"));
if (properties.getProperty(prefix+"calibrationPath")!=null) this.calibrationPath=properties.getProperty(prefix+"calibrationPath"); if (properties.getProperty(prefix+"calibrationPath")!=null) this.calibrationPath=properties.getProperty(prefix+"calibrationPath");
if (properties.getProperty(prefix+"strategyPath")!=null) this.strategyPath=properties.getProperty(prefix+"strategyPath"); if (properties.getProperty(prefix+"strategyPath")!=null) this.strategyPath=properties.getProperty(prefix+"strategyPath");
...@@ -4644,7 +4649,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4644,7 +4649,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.autoRestoreSensorOverwriteOrientation=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestoreSensorOverwriteOrientation")); this.autoRestoreSensorOverwriteOrientation=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestoreSensorOverwriteOrientation"));
if (properties.getProperty(prefix+"autoRestoreSensorOverwriteDistortion")!=null) if (properties.getProperty(prefix+"autoRestoreSensorOverwriteDistortion")!=null)
this.autoRestoreSensorOverwriteDistortion=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestoreSensorOverwriteDistortion")); this.autoRestoreSensorOverwriteDistortion=Boolean.parseBoolean(properties.getProperty(prefix+"autoRestoreSensorOverwriteDistortion"));
if (properties.getProperty(prefix+"autoReCalibrate")!=null) this.autoReCalibrate=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrate")); if (properties.getProperty(prefix+"autoReCalibrate")!=null) this.autoReCalibrate=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrate"));
if (properties.getProperty(prefix+"autoReCalibrateIgnoreLaser")!=null) this.autoReCalibrateIgnoreLaser=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrateIgnoreLaser")); if (properties.getProperty(prefix+"autoReCalibrateIgnoreLaser")!=null) this.autoReCalibrateIgnoreLaser=Boolean.parseBoolean(properties.getProperty(prefix+"autoReCalibrateIgnoreLaser"));
if (properties.getProperty(prefix+"autoFilter")!=null) this.autoFilter=Boolean.parseBoolean(properties.getProperty(prefix+"autoFilter")); if (properties.getProperty(prefix+"autoFilter")!=null) this.autoFilter=Boolean.parseBoolean(properties.getProperty(prefix+"autoFilter"));
...@@ -4653,8 +4658,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4653,8 +4658,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
if (properties.getProperty(prefix+"overwriteResultFiles")!=null) this.overwriteResultFiles=Boolean.parseBoolean(properties.getProperty(prefix+"overwriteResultFiles")); if (properties.getProperty(prefix+"overwriteResultFiles")!=null) this.overwriteResultFiles=Boolean.parseBoolean(properties.getProperty(prefix+"overwriteResultFiles"));
if (properties.getProperty(prefix+"partialToReprojected")!=null) this.partialToReprojected=Boolean.parseBoolean(properties.getProperty(prefix+"partialToReprojected")); if (properties.getProperty(prefix+"partialToReprojected")!=null) this.partialToReprojected=Boolean.parseBoolean(properties.getProperty(prefix+"partialToReprojected"));
if (properties.getProperty(prefix+"partialCorrectSensor")!=null) this.partialCorrectSensor=Boolean.parseBoolean(properties.getProperty(prefix+"partialCorrectSensor")); if (properties.getProperty(prefix+"partialCorrectSensor")!=null) this.partialCorrectSensor=Boolean.parseBoolean(properties.getProperty(prefix+"partialCorrectSensor"));
if (properties.getProperty(prefix+"seriesNumber")!=null) this.seriesNumber=Integer.parseInt(properties.getProperty(prefix+"seriesNumber")); if (properties.getProperty(prefix+"seriesNumber")!=null) this.seriesNumber=Integer.parseInt(properties.getProperty(prefix+"seriesNumber"));
if (properties.getProperty(prefix+"allImages")!=null) this.allImages=Boolean.parseBoolean(properties.getProperty(prefix+"allImages")); if (properties.getProperty(prefix+"allImages")!=null) this.allImages=Boolean.parseBoolean(properties.getProperty(prefix+"allImages"));
if (properties.getProperty(prefix+"sourcePrefix")!=null) this.sourcePrefix=properties.getProperty(prefix+"sourcePrefix"); if (properties.getProperty(prefix+"sourcePrefix")!=null) this.sourcePrefix=properties.getProperty(prefix+"sourcePrefix");
...@@ -4667,8 +4672,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4667,8 +4672,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
if (properties.getProperty(prefix+"interpolatedPSFSuffix")!=null) this.interpolatedPSFSuffix=properties.getProperty(prefix+"interpolatedPSFSuffix"); if (properties.getProperty(prefix+"interpolatedPSFSuffix")!=null) this.interpolatedPSFSuffix=properties.getProperty(prefix+"interpolatedPSFSuffix");
if (properties.getProperty(prefix+"aberrationsPrefix")!=null) this.aberrationsPrefix=properties.getProperty(prefix+"aberrationsPrefix"); if (properties.getProperty(prefix+"aberrationsPrefix")!=null) this.aberrationsPrefix=properties.getProperty(prefix+"aberrationsPrefix");
if (properties.getProperty(prefix+"aberrationsSuffix")!=null) this.aberrationsSuffix=properties.getProperty(prefix+"aberrationsSuffix"); if (properties.getProperty(prefix+"aberrationsSuffix")!=null) this.aberrationsSuffix=properties.getProperty(prefix+"aberrationsSuffix");
if (properties.getProperty(prefix+"selectedChannels")!=null){ if (properties.getProperty(prefix+"selectedChannels")!=null){
String sSelectedChannels=properties.getProperty(prefix+"selectedChannels"); String sSelectedChannels=properties.getProperty(prefix+"selectedChannels");
this.selectedChannels=new boolean[sSelectedChannels.length()]; this.selectedChannels=new boolean[sSelectedChannels.length()];
...@@ -4682,7 +4687,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4682,7 +4687,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
* for the paths that are not set or did not change from configured * for the paths that are not set or did not change from configured
* @return array of 4 paths * @return array of 4 paths
*/ */
public String [] currentConfigPaths(Distortions distortions, boolean combine){ public String [] currentConfigPaths(Distortions distortions, boolean combine){
String currentCalibrationPath=null; String currentCalibrationPath=null;
String currentStrategyPath=null; String currentStrategyPath=null;
...@@ -4699,7 +4704,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4699,7 +4704,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} }
} else { } else {
// System.out.println("currentConfigPaths():distortions.fittingStrategy==null"); // System.out.println("currentConfigPaths():distortions.fittingStrategy==null");
} }
currentGridPath=distortions.patternParameters.pathName; currentGridPath=distortions.patternParameters.pathName;
// System.out.println("currentConfigPaths():currentGridPath="+((currentGridPath==null)?"null":currentGridPath)); // System.out.println("currentConfigPaths():currentGridPath="+((currentGridPath==null)?"null":currentGridPath));
...@@ -4748,7 +4753,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4748,7 +4753,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} }
} }
return this.selectedChannels; return this.selectedChannels;
} }
public boolean selectChannelsToProcess(String title, Distortions distortions) { public boolean selectChannelsToProcess(String title, Distortions distortions) {
boolean [] newSelecttion=getChannelSelection(distortions).clone(); //java.lang.NullPointerException boolean [] newSelecttion=getChannelSelection(distortions).clone(); //java.lang.NullPointerException
...@@ -4771,7 +4776,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4771,7 +4776,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} }
} }
public boolean showDialog(String title, Distortions distortions) { public boolean showDialog(String title, Distortions distortions) {
String [] currentConfigs; String [] currentConfigs;
String []nulls={null,null,null,null}; String []nulls={null,null,null,null};
currentConfigs=(distortions!=null)?currentConfigPaths(distortions, false):nulls; currentConfigs=(distortions!=null)?currentConfigPaths(distortions, false):nulls;
...@@ -4788,19 +4793,19 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4788,19 +4793,19 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
gd.addCheckbox("Overwrite result files if they exist", this.overwriteResultFiles); gd.addCheckbox("Overwrite result files if they exist", this.overwriteResultFiles);
gd.addCheckbox("Use reprojected grids for partial kernel calculation (false - extracted grids)", this.partialToReprojected); gd.addCheckbox("Use reprojected grids for partial kernel calculation (false - extracted grids)", this.partialToReprojected);
gd.addCheckbox("Apply sensor correction during for partial kernel calculation", this.partialCorrectSensor); gd.addCheckbox("Apply sensor correction during for partial kernel calculation", this.partialCorrectSensor);
gd.addNumericField("Fitting series number to use for image selection", this.seriesNumber,0); gd.addNumericField("Fitting series number to use for image selection", this.seriesNumber,0);
gd.addCheckbox("Process all enabled image files (false - use selected fitting series)", this.allImages); gd.addCheckbox("Process all enabled image files (false - use selected fitting series)", this.allImages);
gd.addMessage("===== Autoload options (when restoring configuration) ====="); gd.addMessage("===== Autoload options (when restoring configuration) =====");
gd.addCheckbox("Autoload additional files on \"Restore\"", this.autoRestore); gd.addCheckbox("Autoload additional files on \"Restore\"", this.autoRestore);
gd.addCheckbox("Overwrite all (including position/orientation) SFE parameters from the sensor calibration files (at auto-load) DANGEROUS!", this.autoRestoreSensorOverwriteOrientation); gd.addCheckbox("Overwrite all (including position/orientation) SFE parameters from the sensor calibration files (at auto-load) DANGEROUS!", this.autoRestoreSensorOverwriteOrientation);
gd.addCheckbox("Overwrite SFE distortion parameters from the sensor calibration files (at auto-load) DANGEROUS!", this.autoRestoreSensorOverwriteDistortion); gd.addCheckbox("Overwrite SFE distortion parameters from the sensor calibration files (at auto-load) DANGEROUS!", this.autoRestoreSensorOverwriteDistortion);
gd.addCheckbox("Re-calibrate grids on autoload", this.autoReCalibrate); gd.addCheckbox("Re-calibrate grids on autoload", this.autoReCalibrate);
gd.addCheckbox("Ignore laser pointers on recalibrate", this.autoReCalibrateIgnoreLaser); gd.addCheckbox("Ignore laser pointers on recalibrate", this.autoReCalibrateIgnoreLaser);
gd.addCheckbox("Filter grids after restore", this.autoFilter); gd.addCheckbox("Filter grids after restore", this.autoFilter);
gd.addCheckbox("Trust enabled images on input (mark as hintedGrid=2)", this.trustEnabled); gd.addCheckbox("Trust enabled images on input (mark as hintedGrid=2)", this.trustEnabled);
gd.addMessage("Calibration: "+(((this.calibrationPath==null) || (this.calibrationPath.length()==0))?"not configured ":(this.calibrationPath+" "))+ gd.addMessage("Calibration: "+(((this.calibrationPath==null) || (this.calibrationPath.length()==0))?"not configured ":(this.calibrationPath+" "))+
((currentConfigs[0]!=null)?("(current: "+currentConfigs[0]+")"):("") )); ((currentConfigs[0]!=null)?("(current: "+currentConfigs[0]+")"):("") ));
gd.addMessage("Strategy: "+(((this.strategyPath==null) || (this.strategyPath.length()==0))?"not configured ":(this.strategyPath+" "))+ gd.addMessage("Strategy: "+(((this.strategyPath==null) || (this.strategyPath.length()==0))?"not configured ":(this.strategyPath+" "))+
...@@ -4821,18 +4826,18 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4821,18 +4826,18 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
gd.addStringField("Interpolated kernels suffix", this.interpolatedPSFSuffix, 40); gd.addStringField("Interpolated kernels suffix", this.interpolatedPSFSuffix, 40);
gd.addStringField("Inverted (final) kernels prefix", this.aberrationsPrefix, 40); gd.addStringField("Inverted (final) kernels prefix", this.aberrationsPrefix, 40);
gd.addStringField("Inverted (final) kernels suffix", this.aberrationsSuffix, 40); gd.addStringField("Inverted (final) kernels suffix", this.aberrationsSuffix, 40);
gd.addCheckbox("Select channels to process", true); gd.addCheckbox("Select channels to process", true);
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
this.sourceDirectory= gd.getNextString(); this.sourceDirectory= gd.getNextString();
if (gd.getNextBoolean()) selectSourceDirectory(false, this.sourceDirectory, false); if (gd.getNextBoolean()) selectSourceDirectory(false, this.sourceDirectory, false);
this.partialKernelDirectory=gd.getNextString(); this.partialKernelDirectory=gd.getNextString();
if (gd.getNextBoolean()) selectPartialKernelDirectory(false, this.partialKernelDirectory, false); if (gd.getNextBoolean()) selectPartialKernelDirectory(false, this.partialKernelDirectory, false);
this.psfKernelDirectory=gd.getNextString(); this.psfKernelDirectory=gd.getNextString();
if (gd.getNextBoolean()) selectPSFKernelDirectory(false, this.psfKernelDirectory, false); if (gd.getNextBoolean()) selectPSFKernelDirectory(false, this.psfKernelDirectory, false);
this.aberrationsKernelDirectory=gd.getNextString(); this.aberrationsKernelDirectory=gd.getNextString();
if (gd.getNextBoolean()) selectAberrationsKernelDirectory(false, this.aberrationsKernelDirectory, false); if (gd.getNextBoolean()) selectAberrationsKernelDirectory(false, this.aberrationsKernelDirectory, false);
this.noMessageBoxes= gd.getNextBoolean(); this.noMessageBoxes= gd.getNextBoolean();
...@@ -4848,14 +4853,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4848,14 +4853,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.autoReCalibrateIgnoreLaser=gd.getNextBoolean(); this.autoReCalibrateIgnoreLaser=gd.getNextBoolean();
this.autoFilter= gd.getNextBoolean(); this.autoFilter= gd.getNextBoolean();
this.trustEnabled= gd.getNextBoolean(); this.trustEnabled= gd.getNextBoolean();
if (gd.getNextBoolean()) { if (gd.getNextBoolean()) {
if (currentConfigs[0]!=null) this.calibrationPath=currentConfigs[0]; if (currentConfigs[0]!=null) this.calibrationPath=currentConfigs[0];
if (currentConfigs[1]!=null) this.strategyPath= currentConfigs[1]; if (currentConfigs[1]!=null) this.strategyPath= currentConfigs[1];
if (currentConfigs[2]!=null) this.gridPath= currentConfigs[2]; if (currentConfigs[2]!=null) this.gridPath= currentConfigs[2];
if (currentConfigs[3]!=null) this.sensorsPath= currentConfigs[3]; if (currentConfigs[3]!=null) this.sensorsPath= currentConfigs[3];
} }
this.sourcePrefix= gd.getNextString(); this.sourcePrefix= gd.getNextString();
this.sourceSuffix= gd.getNextString(); this.sourceSuffix= gd.getNextString();
this.partialPrefix= gd.getNextString(); this.partialPrefix= gd.getNextString();
...@@ -4872,7 +4877,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4872,7 +4877,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public String selectSourceDirectory(boolean smart, String defaultPath, boolean newAllowed) { // normally newAllowed=false public String selectSourceDirectory(boolean smart, String defaultPath, boolean newAllowed) { // normally newAllowed=false
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Source (acquired from the camera) image directory", // title "Source (acquired from the camera) image directory", // title
"Select source directory", // button "Select source directory", // button
null, // filter null, // filter
...@@ -4883,7 +4888,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4883,7 +4888,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public String selectPartialKernelDirectory(boolean smart, String defaultPath, boolean newAllowed) { public String selectPartialKernelDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Partial PSF directory", // title "Partial PSF directory", // title
"Select partial PSF files directory", // button "Select partial PSF files directory", // button
null, // filter null, // filter
...@@ -4894,7 +4899,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4894,7 +4899,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public String selectPSFKernelDirectory(boolean smart, String defaultPath, boolean newAllowed) { public String selectPSFKernelDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Combined direct PSF kernel directory", // title "Combined direct PSF kernel directory", // title
"Select combined kernel directory", // button "Select combined kernel directory", // button
null, // filter null, // filter
...@@ -4905,7 +4910,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4905,7 +4910,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public String selectAberrationsKernelDirectory(boolean smart, String defaultPath, boolean newAllowed) { public String selectAberrationsKernelDirectory(boolean smart, String defaultPath, boolean newAllowed) {
String dir= CalibrationFileManagement.selectDirectory( String dir= CalibrationFileManagement.selectDirectory(
smart, smart,
newAllowed, // save newAllowed, // save
"Aberrations kernel directory", // title "Aberrations kernel directory", // title
"Select aberrations kernel directory", // button "Select aberrations kernel directory", // button
null, // filter null, // filter
...@@ -4914,11 +4919,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4914,11 +4919,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
return dir; return dir;
} }
} }
public static class ColorComponents { public static class ColorComponents {
public boolean [] colorsToCorrect= new boolean[6]; public boolean [] colorsToCorrect= new boolean[6];
public int referenceComponent; // component to calculate lateral chromatic from (0 - G1, 1 - R, 2 - B, 3 - G2,4 - diagonal greens, 5 - checker greens) public int referenceComponent; // component to calculate lateral chromatic from (0 - G1, 1 - R, 2 - B, 3 - G2,4 - diagonal greens, 5 - checker greens)
...@@ -4933,7 +4938,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4933,7 +4938,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
boolean red, boolean red,
boolean blue, boolean blue,
boolean green2, boolean green2,
boolean diagonal, // both greens combined in a 45-degree rotated array boolean diagonal, // both greens combined in a 45-degree rotated array
boolean checker, // both greens combined in a checkerboard pattern boolean checker, // both greens combined in a checkerboard pattern
int referenceComponent, int referenceComponent,
boolean equalizeGreens boolean equalizeGreens
...@@ -4988,7 +4993,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4988,7 +4993,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.thresholdHigh = thresholdHigh; this.thresholdHigh = thresholdHigh;
this.thresholdLow = thresholdLow; this.thresholdLow = thresholdLow;
} }
public OTFFilterParameters clone() { @Override
public OTFFilterParameters clone() {
return new OTFFilterParameters( return new OTFFilterParameters(
this.deconvInvert, this.deconvInvert,
this.zerofreqSize, this.zerofreqSize,
...@@ -5027,13 +5033,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5027,13 +5033,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
public double wingsEnergy; public double wingsEnergy;
public double wingsEllipseScale; public double wingsEllipseScale;
public double minDefinedArea; // minimal (weighted) fraction of the defined patter pixels in the FFT area public double minDefinedArea; // minimal (weighted) fraction of the defined patter pixels in the FFT area
public boolean approximateGrid; // approximate grid with polynomial public boolean approximateGrid; // approximate grid with polynomial
public boolean centerPSF; // Center PSF by modifying phase public boolean centerPSF; // Center PSF by modifying phase
public double mask1_sigma; public double mask1_sigma;
public double mask1_threshold; public double mask1_threshold;
public double gaps_sigma; public double gaps_sigma;
public double mask_denoise; public double mask_denoise;
public PSFParameters(double minContrast, public PSFParameters(double minContrast,
double windowFrac, double windowFrac,
...@@ -5067,8 +5073,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5067,8 +5073,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.wingsEnergy = wingsEnergy; this.wingsEnergy = wingsEnergy;
this.wingsEllipseScale = wingsEllipseScale; this.wingsEllipseScale = wingsEllipseScale;
this.minDefinedArea = minDefinedArea; // minimal (weighted) fraction of the defined patter pixels in the FFT area this.minDefinedArea = minDefinedArea; // minimal (weighted) fraction of the defined patter pixels in the FFT area
this.approximateGrid = approximateGrid; // approximate grid with polynomial this.approximateGrid = approximateGrid; // approximate grid with polynomial
this.centerPSF = centerPSF; // approximate grid with polynomial this.centerPSF = centerPSF; // approximate grid with polynomial
this.mask1_sigma = mask1_sigma; this.mask1_sigma = mask1_sigma;
this.mask1_threshold = mask1_threshold; this.mask1_threshold = mask1_threshold;
this.gaps_sigma=gaps_sigma; this.gaps_sigma=gaps_sigma;
...@@ -5076,7 +5082,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5076,7 +5082,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
} }
public PSFParameters clone(){ @Override
public PSFParameters clone(){
return new PSFParameters( return new PSFParameters(
this.minContrast, this.minContrast,
this.windowFrac, this.windowFrac,
...@@ -5288,8 +5295,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5288,8 +5295,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.sigmaToRadiusDirect=Double.parseDouble(properties.getProperty(prefix+"sigmaToRadiusDirect")); this.sigmaToRadiusDirect=Double.parseDouble(properties.getProperty(prefix+"sigmaToRadiusDirect"));
} }
} }
public static class InterpolateParameters { public static class InterpolateParameters {
public int size; // size of each kernel (should be square) public int size; // size of each kernel (should be square)
public int step; // number of subdivisions from input to output public int step; // number of subdivisions from input to output
...@@ -5334,7 +5341,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5334,7 +5341,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
properties.setProperty(prefix+"add_bottom",this.add_bottom+""); properties.setProperty(prefix+"add_bottom",this.add_bottom+"");
properties.setProperty(prefix+"extrapolate",this.extrapolate+""); properties.setProperty(prefix+"extrapolate",this.extrapolate+"");
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
this.size=Integer.parseInt(properties.getProperty(prefix+"size")); this.size=Integer.parseInt(properties.getProperty(prefix+"size"));
this.step=Integer.parseInt(properties.getProperty(prefix+"step")); this.step=Integer.parseInt(properties.getProperty(prefix+"step"));
...@@ -5344,10 +5351,10 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5344,10 +5351,10 @@ if (globalDebugLevel>2)globalDebugLevel=0; //***********************************
this.add_bottom=Integer.parseInt(properties.getProperty(prefix+"add_bottom")); this.add_bottom=Integer.parseInt(properties.getProperty(prefix+"add_bottom"));
this.extrapolate=Double.parseDouble(properties.getProperty(prefix+"extrapolate")); this.extrapolate=Double.parseDouble(properties.getProperty(prefix+"extrapolate"));
} }
} }
} }
...@@ -668,6 +668,8 @@ horizontal axis: ...@@ -668,6 +668,8 @@ horizontal axis:
// allow more of grid around pointers? // allow more of grid around pointers?
distortionParameters, // distortionParameters, //
this.patternDetectParameters, this.patternDetectParameters,
this.patternDetectParameters.minGridPeriod/2,
this.patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
equalizeGreens, imp_eq, equalizeGreens, imp_eq,
this.laserPointers, // null, //LASER_POINTERS, // this.laserPointers, // null, //LASER_POINTERS, //
...@@ -841,6 +843,8 @@ horizontal axis: ...@@ -841,6 +843,8 @@ horizontal axis:
// allow more of grid around pointers? // allow more of grid around pointers?
distortionParameters, // distortionParameters, //
this.patternDetectParameters, this.patternDetectParameters,
this.patternDetectParameters.minGridPeriod/2,
this.patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
equalizeGreens, imp_eq, equalizeGreens, imp_eq,
this.laserPointers, // null, //LASER_POINTERS, // this.laserPointers, // null, //LASER_POINTERS, //
......
package com.elphel.imagej.calibration; package com.elphel.imagej.calibration;
/** /**
** **
** LensAdjustment.jave - processing related to focus measurement/adjustment machine ** LensAdjustment.jave - processing related to focus measurement/adjustment machine
** **
** Copyright (C) 2011 Elphel, Inc. ** Copyright (C) 2011 Elphel, Inc.
** **
** -----------------------------------------------------------------------------** ** -----------------------------------------------------------------------------**
** **
** LensAdjustment.java is free software: you can redistribute it and/or modify ** LensAdjustment.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by ** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or ** the Free Software Foundation, either version 3 of the License, or
...@@ -25,7 +25,6 @@ package com.elphel.imagej.calibration; ...@@ -25,7 +25,6 @@ package com.elphel.imagej.calibration;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.Properties; import java.util.Properties;
import com.elphel.imagej.calibration.SimulationPattern.SimulParameters;
import com.elphel.imagej.common.ShowDoubleFloatArrays; import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.common.WindowTools; import com.elphel.imagej.common.WindowTools;
...@@ -37,7 +36,7 @@ import ij.gui.GenericDialog; ...@@ -37,7 +36,7 @@ import ij.gui.GenericDialog;
public class LensAdjustment { public class LensAdjustment {
private ShowDoubleFloatArrays sdfaInstance =new ShowDoubleFloatArrays(); // just for debugging? private ShowDoubleFloatArrays sdfaInstance =new ShowDoubleFloatArrays(); // just for debugging?
// public int debugLevel=2; // public int debugLevel=2;
public int updateFocusGrid( public int updateFocusGrid(
double x0, // lens center on the sensor double x0, // lens center on the sensor
double y0, // lens center on the sensor double y0, // lens center on the sensor
...@@ -75,18 +74,18 @@ public class LensAdjustment { ...@@ -75,18 +74,18 @@ public class LensAdjustment {
distortionParameters.minUVSpan=focusMeasurementParameters.minUVSpan; distortionParameters.minUVSpan=focusMeasurementParameters.minUVSpan;
distortionParameters.flatFieldCorrection=focusMeasurementParameters.flatFieldCorrection; distortionParameters.flatFieldCorrection=focusMeasurementParameters.flatFieldCorrection;
distortionParameters.flatFieldExpand=focusMeasurementParameters.flatFieldExpand; distortionParameters.flatFieldExpand=focusMeasurementParameters.flatFieldExpand;
distortionParameters.correlationMinContrast=focusMeasurementParameters.correlationMinContrast; distortionParameters.correlationMinContrast=focusMeasurementParameters.correlationMinContrast;
distortionParameters.correlationMinInitialContrast=focusMeasurementParameters.correlationMinInitialContrast; distortionParameters.correlationMinInitialContrast=focusMeasurementParameters.correlationMinInitialContrast;
distortionParameters.correlationMinAbsoluteContrast=focusMeasurementParameters.correlationMinAbsoluteContrast; distortionParameters.correlationMinAbsoluteContrast=focusMeasurementParameters.correlationMinAbsoluteContrast;
distortionParameters.correlationMinAbsoluteInitialContrast=focusMeasurementParameters.correlationMinAbsoluteInitialContrast; distortionParameters.correlationMinAbsoluteInitialContrast=focusMeasurementParameters.correlationMinAbsoluteInitialContrast;
if (maskNonPSF) { if (maskNonPSF) {
distortionParameters.numberExtrapolated=0; //1; //3; // measuring PSF - extrapolate distortionParameters.numberExtrapolated=0; //1; //3; // measuring PSF - extrapolate
} else { } else {
distortionParameters.numberExtrapolated=1; // measuring distortions - do not extrapolate distortionParameters.numberExtrapolated=1; // measuring distortions - do not extrapolate
} }
//System.out.println("distortionParameters.correlationSize="+distortionParameters.correlationSize); //System.out.println("distortionParameters.correlationSize="+distortionParameters.correlationSize);
// add more overwrites // add more overwrites
// boolean updating=(matchSimulatedPattern.PATTERN_GRID!=null) && // boolean updating=(matchSimulatedPattern.PATTERN_GRID!=null) &&
...@@ -118,7 +117,7 @@ public class LensAdjustment { ...@@ -118,7 +117,7 @@ public class LensAdjustment {
//Bad: NaN (no cells), maxActualCorr<0 -number of new empty nodes, >focusMeasurementParameters.maxCorr - also bad (no correction) //Bad: NaN (no cells), maxActualCorr<0 -number of new empty nodes, >focusMeasurementParameters.maxCorr - also bad (no correction)
if (!((maxActualCorr>=0) && (maxActualCorr<=focusMeasurementParameters.maxCorr))) { if (!((maxActualCorr>=0) && (maxActualCorr<=focusMeasurementParameters.maxCorr))) {
if (debug_level>0) System.out.println("updateFocusGrid() failed, refineDistortionCorrelation() ->"+maxActualCorr+ " (maxCorr="+focusMeasurementParameters.maxCorr+")"); if (debug_level>0) System.out.println("updateFocusGrid() failed, refineDistortionCorrelation() ->"+maxActualCorr+ " (maxCorr="+focusMeasurementParameters.maxCorr+")");
// Do full // Do full
updating=false; updating=false;
...@@ -127,7 +126,7 @@ public class LensAdjustment { ...@@ -127,7 +126,7 @@ public class LensAdjustment {
} }
} }
int numAbsolutePoints=0; int numAbsolutePoints=0;
if (updating) { if (updating) {
// add new nodes if the appeared after shift of the pattern // add new nodes if the appeared after shift of the pattern
if (debug_level>0) { // calculate/print number of defined nodes in the grid if (debug_level>0) { // calculate/print number of defined nodes in the grid
System.out.println("updateFocusGrid(), number of already defined grid cells (before distortions()) = "+matchSimulatedPattern.numDefinedCells()); System.out.println("updateFocusGrid(), number of already defined grid cells (before distortions()) = "+matchSimulatedPattern.numDefinedCells());
...@@ -136,6 +135,8 @@ public class LensAdjustment { ...@@ -136,6 +135,8 @@ public class LensAdjustment {
null, // is not used in update mode null, // is not used in update mode
distortionParameters, // distortionParameters, //
patternDetectParameters, patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
equalizeGreens, equalizeGreens,
imp_eq, // image to process imp_eq, // image to process
...@@ -158,6 +159,8 @@ public class LensAdjustment { ...@@ -158,6 +159,8 @@ public class LensAdjustment {
numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // allow more of grid around pointers? numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // allow more of grid around pointers?
distortionParameters, // distortionParameters, //
patternDetectParameters, patternDetectParameters,
patternDetectParameters.minGridPeriod/2,
patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
equalizeGreens, equalizeGreens,
imp_eq, imp_eq,
...@@ -201,7 +204,7 @@ public class LensAdjustment { ...@@ -201,7 +204,7 @@ public class LensAdjustment {
return numAbsolutePoints; return numAbsolutePoints;
} }
public static class FocusMeasurementParameters { public static class FocusMeasurementParameters {
public String gridGeometryFile=""; public String gridGeometryFile="";
public String initialCalibrationFile=""; public String initialCalibrationFile="";
...@@ -216,15 +219,15 @@ public class LensAdjustment { ...@@ -216,15 +219,15 @@ public class LensAdjustment {
public String serialNumber=""; // camera serial number string public String serialNumber=""; // camera serial number string
public double sensorTemperature=Double.NaN; // last measured sensor temperature public double sensorTemperature=Double.NaN; // last measured sensor temperature
//other summary results to be saved with parameters //other summary results to be saved with parameters
public double result_lastKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from last run public double result_lastKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from last run
public double result_lastFD20=Double.NaN; // focal distance for 20C, measured from last run public double result_lastFD20=Double.NaN; // focal distance for 20C, measured from last run
public double result_allHistoryKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from all the measurement histgory public double result_allHistoryKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from all the measurement histgory
public double result_allHistoryFD20=Double.NaN; // focal distance for 20C, measured from all the measurement histgory public double result_allHistoryFD20=Double.NaN; // focal distance for 20C, measured from all the measurement histgory
public double result_fDistance=Double.NaN; // last measured focal distance public double result_fDistance=Double.NaN; // last measured focal distance
public double result_tiltX=Double.NaN; // last measured tilt X public double result_tiltX=Double.NaN; // last measured tilt X
public double result_tiltY=Double.NaN; // last measured tilt Y public double result_tiltY=Double.NaN; // last measured tilt Y
public double result_R50=Double.NaN; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings) public double result_R50=Double.NaN; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings)
public double result_A50=Double.NaN; // last measured A50 (simailar, but R^2 are averaged) public double result_A50=Double.NaN; // last measured A50 (simailar, but R^2 are averaged)
public double result_B50=Double.NaN; // last measured B50 (simailar, but R^4 are averaged) public double result_B50=Double.NaN; // last measured B50 (simailar, but R^4 are averaged)
public double result_RC50=Double.NaN; // last measured RC50(R50 calculated only for the 2 center samples) public double result_RC50=Double.NaN; // last measured RC50(R50 calculated only for the 2 center samples)
public double result_PX0=Double.NaN; // lens center shift, X public double result_PX0=Double.NaN; // lens center shift, X
...@@ -237,10 +240,10 @@ public class LensAdjustment { ...@@ -237,10 +240,10 @@ public class LensAdjustment {
public int lensSerialLength=4; public int lensSerialLength=4;
public String lensSerial=""; // Lens serial number public String lensSerial=""; // Lens serial number
public boolean askLensSerial=true; // Ask lens serial on camera power cycle public boolean askLensSerial=true; // Ask lens serial on camera power cycle
public double reportTemperature=50; // temperature to report focal length public double reportTemperature=50; // temperature to report focal length
public boolean showLegacy=false; // Show old focusing parameters (most are not supported anyway) public boolean showLegacy=false; // Show old focusing parameters (most are not supported anyway)
public boolean includeLensSerial=true; // add lens serial to config filename public boolean includeLensSerial=true; // add lens serial to config filename
public double centerDeltaX=0.0; // required X-difference between lens center and sensor center public double centerDeltaX=0.0; // required X-difference between lens center and sensor center
public double centerDeltaY=0.0; // required Y-difference between lens center and sensor center public double centerDeltaY=0.0; // required Y-difference between lens center and sensor center
// with the seam in the middle - make even # of samples horizontally // with the seam in the middle - make even # of samples horizontally
// to be made private or removed // to be made private or removed
...@@ -258,34 +261,34 @@ public class LensAdjustment { ...@@ -258,34 +261,34 @@ public class LensAdjustment {
public boolean showAcquiredImages=false; public boolean showAcquiredImages=false;
public boolean showROI=true; public boolean showROI=true;
public boolean showSamples=true; public boolean showSamples=true;
public boolean showFittedParameters=true; public boolean showFittedParameters=true;
public boolean useHeadLasers=true; public boolean useHeadLasers=true;
// when approximating PSF with a second degree polynomial: // when approximating PSF with a second degree polynomial:
public double psf_cutoffEnergy=0.98; //0.5; // disregard pixels outside of this fraction of the total energy public double psf_cutoffEnergy=0.98; //0.5; // disregard pixels outside of this fraction of the total energy
public double psf_cutoffLevel= 0.2; // disregard pixels below this fraction of the maximal value public double psf_cutoffLevel= 0.2; // disregard pixels below this fraction of the maximal value
public int psf_minArea = 10; // continue increasing the selected area, even if beyond psf_cutoffEnergy and psf_cutoffLevel, public int psf_minArea = 10; // continue increasing the selected area, even if beyond psf_cutoffEnergy and psf_cutoffLevel,
// if the selected area is smaller than this (so approximation would work) // if the selected area is smaller than this (so approximation would work)
public double psf_blurSigma = 0.0; // optionally blur the calculated mask public double psf_blurSigma = 0.0; // optionally blur the calculated mask
public double weightRatioRedToGreen=0.7; // Use this data when combining defocusing data from different color PSF public double weightRatioRedToGreen=0.7; // Use this data when combining defocusing data from different color PSF
public double weightRatioBlueToGreen=0.2; public double weightRatioBlueToGreen=0.2;
public double targetFarNear=0.0; // OBSOLETE target logarithm of average tangential-to-radial resolution public double targetFarNear=0.0; // OBSOLETE target logarithm of average tangential-to-radial resolution
public boolean useRadialTangential=false; // Use targetFarNear (radial/tangential resolution) as a proxy for the distance public boolean useRadialTangential=false; // Use targetFarNear (radial/tangential resolution) as a proxy for the distance
public double targetMicrons=0.0; // target lens center distance (away from "best focus" public double targetMicrons=0.0; // target lens center distance (away from "best focus"
public double toleranceMicrons=0.5; // microns public double toleranceMicrons=0.5; // microns
public double toleranceTilt=0.02; // public double toleranceTilt=0.02; //
public double toleranceThreshold=3.0; // When each error is under scaled threshold, reduce correction step twice public double toleranceThreshold=3.0; // When each error is under scaled threshold, reduce correction step twice
// public boolean parallelAdjust=true; // move 3 motors parallel after each 3-motor focus/tilt adjustment // public boolean parallelAdjust=true; // move 3 motors parallel after each 3-motor focus/tilt adjustment
public double parallelAdjustThreshold=4.0; // adjust 3 motors parallel if focal distance error in the center exceeds this public double parallelAdjustThreshold=4.0; // adjust 3 motors parallel if focal distance error in the center exceeds this
public double motorsSigma=896.0; // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma 1/4 turn public double motorsSigma=896.0; // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma 1/4 turn
public double motorsSigma3=896.0; // all 3 motors together (focusing center) public double motorsSigma3=896.0; // all 3 motors together (focusing center)
public double motorsMinSigma=200.0;// sigma will not drop below this value when fitting walk is getting smaller public double motorsMinSigma=200.0;// sigma will not drop below this value when fitting walk is getting smaller
public double motorsVarSigmaToTravel=2.0; // when walk is getting smaller, sigma will keep going down proportionally public double motorsVarSigmaToTravel=2.0; // when walk is getting smaller, sigma will keep going down proportionally
public double motorsFadeSigma=0.3; // after each step new sigma will have this part of the calculated from the travel public double motorsFadeSigma=0.3; // after each step new sigma will have this part of the calculated from the travel
public double motorsOverShootToBalance=0.9; //For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side public double motorsOverShootToBalance=0.9; //For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side
public boolean filterGoodDistance=true; // when measuring tilt, use those with good center with higher weight public boolean filterGoodDistance=true; // when measuring tilt, use those with good center with higher weight
public double goodDistanceSigma=5.0; // sigma for the weight function of tilt measurements, depending on the center distance error public double goodDistanceSigma=5.0; // sigma for the weight function of tilt measurements, depending on the center distance error
...@@ -295,15 +298,15 @@ public class LensAdjustment { ...@@ -295,15 +298,15 @@ public class LensAdjustment {
public double probe_M1M2M3= 448.0; // how far to move average of the 3 motors: (M1+M2+M3)/3 public double probe_M1M2M3= 448.0; // how far to move average of the 3 motors: (M1+M2+M3)/3
public double probe_M3_M1M2=3584.0; // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2 public double probe_M3_M1M2=3584.0; // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2
public double probe_M2_M1= 3584.0; // how far to move M2 opposite to M1: M2-M1 public double probe_M2_M1= 3584.0; // how far to move M2 opposite to M1: M2-M1
public double sigmaToProbe=1.0; // data from far samples decay proportionally to the probe distances public double sigmaToProbe=1.0; // data from far samples decay proportionally to the probe distances
public boolean useTheBest=true; // adjust from the best known position (false - from the last) public boolean useTheBest=true; // adjust from the best known position (false - from the last)
public boolean probeSymmetrical=false; // if true, probe 6 measurements), if false - only 4 (tetrahedron) public boolean probeSymmetrical=false; // if true, probe 6 measurements), if false - only 4 (tetrahedron)
public boolean parallelBeforeProbing=true; // move 3 motors before probing around public boolean parallelBeforeProbing=true; // move 3 motors before probing around
public double reProbeDistance=4000.0; // re-run probing around in orthoganal directions, if the current position move farther from the last probing one public double reProbeDistance=4000.0; // re-run probing around in orthoganal directions, if the current position move farther from the last probing one
public double believeLast=0.0; // coefficient 0.. 1.0. When each ot the 3 parameters is linearized, add shift, so 1.0 the planes will go throug the last sample public double believeLast=0.0; // coefficient 0.. 1.0. When each ot the 3 parameters is linearized, add shift, so 1.0 the planes will go throug the last sample
public boolean compensateHysteresis=true; // move motors in the same direction to compensate for hysteresis public boolean compensateHysteresis=true; // move motors in the same direction to compensate for hysteresis
public double minCorr=100.0; // minimal correction movement to initiate final numFinalCorr moves public double minCorr=100.0; // minimal correction movement to initiate final numFinalCorr moves
public int numFinalCorr=5; // exit if this number of last corrections where below minCorr public int numFinalCorr=5; // exit if this number of last corrections where below minCorr
...@@ -312,16 +315,16 @@ public class LensAdjustment { ...@@ -312,16 +315,16 @@ public class LensAdjustment {
public int maxAutoIterations=25; // exit if history grows above this public int maxAutoIterations=25; // exit if history grows above this
public double maxAutoDistance= 10000; // Maximal allowed automatic correction, motor steps public double maxAutoDistance= 10000; // Maximal allowed automatic correction, motor steps
public boolean confirmFirstAuto=true; // ask confirmation after first automatic adjustment step (before moving) public boolean confirmFirstAuto=true; // ask confirmation after first automatic adjustment step (before moving)
public double motorsPreSigma=3584.0; // when fitting parabola for focusing sharpness in the center, far measurements decay with this sigma public double motorsPreSigma=3584.0; // when fitting parabola for focusing sharpness in the center, far measurements decay with this sigma
public double maxLinearStep= 3584.0; // If there are insufficient measurements to fit parabola - make this step public double maxLinearStep= 3584.0; // If there are insufficient measurements to fit parabola - make this step
public int scanStep=320; // 200; // motor step (all 3 motors) in scan focus mode (signed value) public int scanStep=320; // 200; // motor step (all 3 motors) in scan focus mode (signed value)
public int scanNumber=50; // number of scanStep steps to run public int scanNumber=50; // number of scanStep steps to run
public int scanNumberNegative=20; // 15; // number of scanStep steps negative from the start public int scanNumberNegative=20; // 15; // number of scanStep steps negative from the start
public boolean scanHysteresis=false; // true; // scan both ways public boolean scanHysteresis=false; // true; // scan both ways
public int scanHysteresisNumber=5; // number of test points for the Hysteresis measurement public int scanHysteresisNumber=5; // number of test points for the Hysteresis measurement
public boolean scanTiltEnable=false; //true; // enable scanning tilt public boolean scanTiltEnable=false; //true; // enable scanning tilt
public boolean scanTiltReverse=false; // enable scanning tilt in both directions public boolean scanTiltReverse=false; // enable scanning tilt in both directions
public boolean scanMeasureLast=false; // Calculate PSF after last move (to original position) public boolean scanMeasureLast=false; // Calculate PSF after last move (to original position)
...@@ -330,45 +333,45 @@ public class LensAdjustment { ...@@ -330,45 +333,45 @@ public class LensAdjustment {
public int scanTiltRangeY=14336; // 4 periods public int scanTiltRangeY=14336; // 4 periods
public int scanTiltStepsX=24; public int scanTiltStepsX=24;
public int scanTiltStepsY=24; public int scanTiltStepsY=24;
public int motorHysteresis=300; public int motorHysteresis=300;
public double measuredHysteresis=0; // actually measured (will be saved/restored) public double measuredHysteresis=0; // actually measured (will be saved/restored)
public double motorCalm=2; // wait (seconds) after motors reached final position (for the first time) before acquiring image public double motorCalm=2; // wait (seconds) after motors reached final position (for the first time) before acquiring image
public double linearReductionRatio=4.0/38.0; // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105 public double linearReductionRatio=4.0/38.0; // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105
public int motorDebug=0; // 1 show motor moves, 2 - show hysteresis back-ups too public int motorDebug=0; // 1 show motor moves, 2 - show hysteresis back-ups too
// parameters for appoximating sensor center position // parameters for appoximating sensor center position
public int lensDistanceNumPoints=1000; // number of points to tabulate center focus parameters vs. focal distance public int lensDistanceNumPoints=1000; // number of points to tabulate center focus parameters vs. focal distance
public int lensDistancePolynomialDegree=8; // polynomial degree to approximate center focus parameters vs. focal distance public int lensDistancePolynomialDegree=8; // polynomial degree to approximate center focus parameters vs. focal distance
public double lensDistanceWeightY=0.5; // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones public double lensDistanceWeightY=0.5; // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones
public double lensDistanceWeightK=0.0; // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives public double lensDistanceWeightK=0.0; // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives
public boolean lensDistanceInteractive=true; // Open dialog when calibrating focal distance public boolean lensDistanceInteractive=true; // Open dialog when calibrating focal distance
public boolean lensDistanceShowResults=true; // show results window from foca public boolean lensDistanceShowResults=true; // show results window from foca
public boolean lensDistanceMoveToGoal=true; // Move to targetMicrons public boolean lensDistanceMoveToGoal=true; // Move to targetMicrons
public boolean powerControlEnable=true; public boolean powerControlEnable=true;
public double powerControlMaximalTemperature=60.0; public double powerControlMaximalTemperature=60.0;
public double powerControlHeaterOnMinutes=10.0; public double powerControlHeaterOnMinutes=10.0;
public double powerControlNeitherOnMinutes=5.0; public double powerControlNeitherOnMinutes=5.0;
public double powerControlFanOnMinutes=15.0; public double powerControlFanOnMinutes=15.0;
public String uvLasersIP="192.168.0.236"; // IP address of the camera with UV LEDs and aiming lasers are connected public String uvLasersIP="192.168.0.236"; // IP address of the camera with UV LEDs and aiming lasers are connected
public int uvLasersBus=0; // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369 public int uvLasersBus=0; // 0 if 103641 board is connected to the sensor port (through 10-359), 1 - to 10369
public double [] uvLasersCurrents={40.0,40.0,40.0,40.0}; // default LED on currents (mA) public double [] uvLasersCurrents={40.0,40.0,40.0,40.0}; // default LED on currents (mA)
// the following 3 overwrite SimulParameters members // the following 3 overwrite SimulParameters members
public double smallestSubPix=0.3; // subdivide pixels down to that fraction when simulating public double smallestSubPix=0.3; // subdivide pixels down to that fraction when simulating
public double bitmapNonuniforityThreshold=0.1 ; // subdivide pixels until difference between the corners is below this value public double bitmapNonuniforityThreshold=0.1 ; // subdivide pixels until difference between the corners is below this value
public int subdiv=4; public int subdiv=4;
// overwrites public static class MultiFilePSF.overexposedMaxFraction // overwrites public static class MultiFilePSF.overexposedMaxFraction
public double overexposedMaxFraction=0.1; // allowed fraction of the overexposed pixels in the PSF kernel measurement area public double overexposedMaxFraction=0.1; // allowed fraction of the overexposed pixels in the PSF kernel measurement area
// overwrites public static class PSFParameters.minDefinedArea // overwrites public static class PSFParameters.minDefinedArea
public double minDefinedArea=0.75; // minimal (weighted) fraction of the defined patter pixels in the FFT area public double minDefinedArea=0.75; // minimal (weighted) fraction of the defined patter pixels in the FFT area
public int PSFKernelSize=32; // size of the detected PSF kernel public int PSFKernelSize=32; // size of the detected PSF kernel
public boolean approximateGrid=true; // approximate grid with polynomial public boolean approximateGrid=true; // approximate grid with polynomial
public boolean centerPSF=true; // Center PSF by modifying phase public boolean centerPSF=true; // Center PSF by modifying phase
public double mask1_sigma= 1.0; public double mask1_sigma= 1.0;
public double mask1_threshold=0.25; public double mask1_threshold=0.25;
public double gaps_sigma= 1.0; public double gaps_sigma= 1.0;
...@@ -384,24 +387,24 @@ public class LensAdjustment { ...@@ -384,24 +387,24 @@ public class LensAdjustment {
public double correlationMinInitialContrast=1.5; // minimal contrast for the pattern of the center (initial point) public double correlationMinInitialContrast=1.5; // minimal contrast for the pattern of the center (initial point)
public double correlationMinAbsoluteContrast=0.5; // minimal contrast for the pattern to pass, does not compensate for low ligt public double correlationMinAbsoluteContrast=0.5; // minimal contrast for the pattern to pass, does not compensate for low ligt
public double correlationMinAbsoluteInitialContrast=0.5; // minimal contrast for the pattern of the center (initial point) public double correlationMinAbsoluteInitialContrast=0.5; // minimal contrast for the pattern of the center (initial point)
public double [] postUVscrewSensitivity={-300,-300,-120}; //{-2.908571735,-3.8198374024,-2.4491867448}; public double [] postUVscrewSensitivity={-300,-300,-120}; //{-2.908571735,-3.8198374024,-2.4491867448};
public boolean flatFieldCorrection=true; public boolean flatFieldCorrection=true;
public double flatFieldExpand=4.0; public double flatFieldExpand=4.0;
public double thresholdFinish=0.001; // Stop iterations if 2 last steps had less improvement (but not worsening ) public double thresholdFinish=0.001; // Stop iterations if 2 last steps had less improvement (but not worsening )
public int numIterations= 100; // maximal number of iterations public int numIterations= 100; // maximal number of iterations
public boolean cameraIsConfigured=false; public boolean cameraIsConfigured=false;
public boolean useExtraSensor = true; public boolean useExtraSensor = true;
public boolean enRoundOff = true; // create round mask to refine lens center position (second LMA run) public boolean enRoundOff = true; // create round mask to refine lens center position (second LMA run)
public boolean keepCircularMask=false; // keep sensor 0 round mask after running LMA, false - recalculate actual mask public boolean keepCircularMask=false; // keep sensor 0 round mask after running LMA, false - recalculate actual mask
public boolean configureCamera=false; // only valid after dialog public boolean configureCamera=false; // only valid after dialog
public int [] motorPos=null; // will point to public int [] motorPos=null; // will point to
public double [] ampsSeconds={0.0,0.0,0.0,0.0}; // cumulative Amps*seconds (read only, but will be saved/restored) public double [] ampsSeconds={0.0,0.0,0.0,0.0}; // cumulative Amps*seconds (read only, but will be saved/restored)
public int manufacturingState=0; public int manufacturingState=0;
// temporary - will re-calculate according to required lens center // temporary - will re-calculate according to required lens center
public Rectangle getMargins(){ public Rectangle getMargins(){
int iXC = (int) Math.round(centerDeltaX); int iXC = (int) Math.round(centerDeltaX);
...@@ -416,10 +419,10 @@ public class LensAdjustment { ...@@ -416,10 +419,10 @@ public class LensAdjustment {
hh += (iYC < 0)?iYC:(-iYC); hh += (iYC < 0)?iYC:(-iYC);
margins=new Rectangle(ix0+iXC-hw,iy0+iYC-hh,2*hw,2*hh); margins=new Rectangle(ix0+iXC-hw,iy0+iYC-hh,2*hw,2*hh);
} }
return margins; return margins;
} }
public String [] manufacturingStateNames={ public String [] manufacturingStateNames={
"New SFE", "New SFE",
"UV cured (not released)", "UV cured (not released)",
...@@ -431,7 +434,7 @@ public class LensAdjustment { ...@@ -431,7 +434,7 @@ public class LensAdjustment {
"Epoxy, cured at room temperature", "Epoxy, cured at room temperature",
"Epoxy cured, re-testing later" "Epoxy cured, re-testing later"
}; };
public int [] manufacturingStateValues={ public int [] manufacturingStateValues={
00, // "New SFE", 00, // "New SFE",
10, //"UV cured (not released)", 10, //"UV cured (not released)",
...@@ -443,7 +446,7 @@ public class LensAdjustment { ...@@ -443,7 +446,7 @@ public class LensAdjustment {
70, //"Epoxy, cured at room temperature", 70, //"Epoxy, cured at room temperature",
80 //"Epoxy cured, re-testing later" 80 //"Epoxy cured, re-testing later"
}; };
public int [] getManufacturingIndexMod(int value){ public int [] getManufacturingIndexMod(int value){
if (value<this.manufacturingStateValues[0]) value= this.manufacturingStateValues[0]; if (value<this.manufacturingStateValues[0]) value= this.manufacturingStateValues[0];
for (int i=this.manufacturingStateValues.length-1;i>=0;i--){ for (int i=this.manufacturingStateValues.length-1;i>=0;i--){
...@@ -454,21 +457,21 @@ public class LensAdjustment { ...@@ -454,21 +457,21 @@ public class LensAdjustment {
} }
return null; // should not get here return null; // should not get here
} }
public FocusMeasurementParameters(int []motorPos){ public FocusMeasurementParameters(int []motorPos){
this.motorPos=motorPos; this.motorPos=motorPos;
} }
public void resetResults(){ public void resetResults(){
this.result_lastKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from last run this.result_lastKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from last run
this.result_lastFD20=Double.NaN; // focal distance for 20C, measured from last run this.result_lastFD20=Double.NaN; // focal distance for 20C, measured from last run
this.result_allHistoryKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from all the measurement histgory this.result_allHistoryKT=Double.NaN; // focal distance temperature coefficient (um/C), measured from all the measurement histgory
this.result_allHistoryFD20=Double.NaN; // focal distance for 20C, measured from all the measurement histgory this.result_allHistoryFD20=Double.NaN; // focal distance for 20C, measured from all the measurement histgory
this.result_fDistance=Double.NaN; // last measured focal distance this.result_fDistance=Double.NaN; // last measured focal distance
this.result_tiltX=Double.NaN; // last measured tilt X this.result_tiltX=Double.NaN; // last measured tilt X
this.result_tiltY=Double.NaN; // last measured tilt Y this.result_tiltY=Double.NaN; // last measured tilt Y
this.result_R50=Double.NaN; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings) this.result_R50=Double.NaN; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings)
this.result_A50=Double.NaN; // last measured A50 (simailar, but R^2 are averaged) this.result_A50=Double.NaN; // last measured A50 (simailar, but R^2 are averaged)
this.result_B50=Double.NaN; // last measured B50 (similar, but R^4 are averaged) this.result_B50=Double.NaN; // last measured B50 (similar, but R^4 are averaged)
this.result_RC50=Double.NaN; // last measured RC50(R50 calculated only for the 2 center samples) this.result_RC50=Double.NaN; // last measured RC50(R50 calculated only for the 2 center samples)
this.result_PX0=Double.NaN; // lens center shift, X this.result_PX0=Double.NaN; // lens center shift, X
...@@ -490,15 +493,15 @@ public class LensAdjustment { ...@@ -490,15 +493,15 @@ public class LensAdjustment {
String serialNumber, // camera serial number string String serialNumber, // camera serial number string
double sensorTemperature, // last measured sensor temperature double sensorTemperature, // last measured sensor temperature
// other summary results to be saved with parameters // other summary results to be saved with parameters
double result_lastKT, // focal distance temperature coefficient (um/C), measured from last run double result_lastKT, // focal distance temperature coefficient (um/C), measured from last run
double result_lastFD20, // focal distance for 20C, measured from last run double result_lastFD20, // focal distance for 20C, measured from last run
double result_allHistoryKT, // focal distance temperature coefficient (um/C), measured from all the measurement histgory double result_allHistoryKT, // focal distance temperature coefficient (um/C), measured from all the measurement histgory
double result_allHistoryFD20, // focal distance for 20C, measured from all the measurement histgory double result_allHistoryFD20, // focal distance for 20C, measured from all the measurement histgory
double result_fDistance, // last measured focal distance double result_fDistance, // last measured focal distance
double result_tiltX, // last measured tilt X double result_tiltX, // last measured tilt X
double result_tiltY, // last measured tilt Y double result_tiltY, // last measured tilt Y
double result_R50, // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings) double result_R50, // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings)
double result_A50, // last measured A50 (simailar, but R^2 are averaged) double result_A50, // last measured A50 (simailar, but R^2 are averaged)
double result_B50, // last measured B50 (simailar, but R^4 are averaged) double result_B50, // last measured B50 (simailar, but R^4 are averaged)
double result_RC50, // last measured RC50(R50 calculated only for the 2 center samples) double result_RC50, // last measured RC50(R50 calculated only for the 2 center samples)
double result_PX0, // lens center shift, X double result_PX0, // lens center shift, X
...@@ -511,7 +514,7 @@ public class LensAdjustment { ...@@ -511,7 +514,7 @@ public class LensAdjustment {
int manufacturingState, // SFE manufacturing state int manufacturingState, // SFE manufacturing state
boolean askLensSerial, boolean askLensSerial,
boolean includeLensSerial, // add lens serial to config filename boolean includeLensSerial, // add lens serial to config filename
double centerDeltaX, // required X-difference between lens center and sensor center double centerDeltaX, // required X-difference between lens center and sensor center
double centerDeltaY, // required Y-difference between lens center and sensor center double centerDeltaY, // required Y-difference between lens center and sensor center
Rectangle margins, Rectangle margins,
int [] numSamples, int [] numSamples,
...@@ -525,7 +528,7 @@ public class LensAdjustment { ...@@ -525,7 +528,7 @@ public class LensAdjustment {
boolean showAcquiredImages, boolean showAcquiredImages,
boolean showROI, boolean showROI,
boolean showSamples, boolean showSamples,
boolean showFittedParameters, boolean showFittedParameters,
boolean useHeadLasers, boolean useHeadLasers,
double psf_cutoffEnergy, // disregard pixels outside of this fraction of the total energy double psf_cutoffEnergy, // disregard pixels outside of this fraction of the total energy
...@@ -533,21 +536,21 @@ public class LensAdjustment { ...@@ -533,21 +536,21 @@ public class LensAdjustment {
int psf_minArea, // continue increasing the selected area, even if beyound psf_cutoffEnergy and psf_cutoffLevel, int psf_minArea, // continue increasing the selected area, even if beyound psf_cutoffEnergy and psf_cutoffLevel,
// if the selected area is smaller than this (so approximation wpuld work) // if the selected area is smaller than this (so approximation wpuld work)
double psf_blurSigma, // optionally blur the calculated mask double psf_blurSigma, // optionally blur the calculated mask
double weightRatioRedToGreen, // Use this data when combining defocusing data from different color PSF double weightRatioRedToGreen, // Use this data when combining defocusing data from different color PSF
double weightRatioBlueToGreen, double weightRatioBlueToGreen,
double targetFarNear, // target logariphm of average tangential-to-radial resolution double targetFarNear, // target logariphm of average tangential-to-radial resolution
boolean useRadialTangential, // Use targetFarNear (radial/tangential resolution) as a proxy for the distance boolean useRadialTangential, // Use targetFarNear (radial/tangential resolution) as a proxy for the distance
double targetMicrons, // target lens center distance (away from "best focus" double targetMicrons, // target lens center distance (away from "best focus"
double toleranceMicrons, // microns double toleranceMicrons, // microns
double toleranceTilt, // double toleranceTilt, //
double toleranceThreshold, // When each error is under swcaled thereshold, reduce correxction step twice double toleranceThreshold, // When each error is under swcaled thereshold, reduce correxction step twice
double parallelAdjustThreshold, // adjust 3 motors parallel if focal distance error in the center exceeds this double parallelAdjustThreshold, // adjust 3 motors parallel if focal distance error in the center exceeds this
double motorsSigma, // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma double motorsSigma, // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma
double motorsSigma3, // all 3 motors together (focusing center) double motorsSigma3, // all 3 motors together (focusing center)
double motorsMinSigma,// sigma will not drop below this value when fitting walk is getting smaller double motorsMinSigma,// sigma will not drop below this value when fitting walk is getting smaller
double motorsVarSigmaToTravel, // when walk is getting smaller, sigma will keep going down proportionally double motorsVarSigmaToTravel, // when walk is getting smaller, sigma will keep going down proportionally
double motorsFadeSigma, // after each step new sigma will have this part of the calculated from the travel double motorsFadeSigma, // after each step new sigma will have this part of the calculated from the travel
double motorsOverShootToBalance, //For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side double motorsOverShootToBalance, //For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side
boolean filterGoodDistance, // when measuring tilt, use those with good center with higher weight boolean filterGoodDistance, // when measuring tilt, use those with good center with higher weight
double goodDistanceSigma, // sigma for the weight function of tilt measurements, depending on the center distance error double goodDistanceSigma, // sigma for the weight function of tilt measurements, depending on the center distance error
...@@ -557,8 +560,8 @@ public class LensAdjustment { ...@@ -557,8 +560,8 @@ public class LensAdjustment {
double probe_M1M2M3, // how far to move average of the 3 motors: (M1+M2+M3)/3 double probe_M1M2M3, // how far to move average of the 3 motors: (M1+M2+M3)/3
double probe_M3_M1M2, // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2 double probe_M3_M1M2, // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2
double probe_M2_M1, // how far to move M2 opposite to M1: M2-M1 double probe_M2_M1, // how far to move M2 opposite to M1: M2-M1
double sigmaToProbe, // data from far samples decay proportionally to the probe distances double sigmaToProbe, // data from far samples decay proportionally to the probe distances
boolean useTheBest, // adjust from the best known position (false - from the last) boolean useTheBest, // adjust from the best known position (false - from the last)
boolean probeSymmetrical, // if true, probe 6 measurements), if false - only 4 (tetrahedron) boolean probeSymmetrical, // if true, probe 6 measurements), if false - only 4 (tetrahedron)
boolean parallelBeforeProbing, // move 3 motors before probing around boolean parallelBeforeProbing, // move 3 motors before probing around
double reProbeDistance, // re-run probing around in orthoganal directions, if the current position move farther from the last probing one double reProbeDistance, // re-run probing around in orthoganal directions, if the current position move farther from the last probing one
...@@ -578,7 +581,7 @@ public class LensAdjustment { ...@@ -578,7 +581,7 @@ public class LensAdjustment {
int scanNumberNegative, // of them negative int scanNumberNegative, // of them negative
boolean scanHysteresis, // scan both ways boolean scanHysteresis, // scan both ways
int scanHysteresisNumber, // number of test points for the Hysteresis measurement int scanHysteresisNumber, // number of test points for the Hysteresis measurement
boolean scanTiltEnable, //=true; // enable scanning tilt boolean scanTiltEnable, //=true; // enable scanning tilt
boolean scanTiltReverse, boolean scanTiltReverse,
boolean scanMeasureLast, boolean scanMeasureLast,
...@@ -588,15 +591,15 @@ public class LensAdjustment { ...@@ -588,15 +591,15 @@ public class LensAdjustment {
int scanTiltStepsX, //=24; int scanTiltStepsX, //=24;
int scanTiltStepsY, //=24; int scanTiltStepsY, //=24;
int motorHysteresis, int motorHysteresis,
double measuredHysteresis, // actually measured (will be saved/restored) double measuredHysteresis, // actually measured (will be saved/restored)
double motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image double motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image
double linearReductionRatio, // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105 double linearReductionRatio, // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105
int motorDebug,// 1 show motor moves, 2 - show hysteresis back-ups too int motorDebug,// 1 show motor moves, 2 - show hysteresis back-ups too
int lensDistanceNumPoints, // number of points to tabulate center focus parameters vs. focal distance int lensDistanceNumPoints, // number of points to tabulate center focus parameters vs. focal distance
int lensDistancePolynomialDegree, // polynomial degree to approximate center focus parameters vs. focal distance int lensDistancePolynomialDegree, // polynomial degree to approximate center focus parameters vs. focal distance
double lensDistanceWeightY, // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones double lensDistanceWeightY, // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones
double lensDistanceWeightK, // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives double lensDistanceWeightK, // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives
boolean lensDistanceInteractive, // Open dialog when calibrating focal distance boolean lensDistanceInteractive, // Open dialog when calibrating focal distance
boolean lensDistanceShowResults, // show results window from foca boolean lensDistanceShowResults, // show results window from foca
...@@ -612,8 +615,8 @@ public class LensAdjustment { ...@@ -612,8 +615,8 @@ public class LensAdjustment {
double smallestSubPix, // subdivide pixels down to that fraction when simulating double smallestSubPix, // subdivide pixels down to that fraction when simulating
double bitmapNonuniforityThreshold, // subdivide pixels until difference between the corners is below this value double bitmapNonuniforityThreshold, // subdivide pixels until difference between the corners is below this value
int subdiv, int subdiv,
double overexposedMaxFraction, // allowed fraction of the overexposed pixels in the PSF kernel measurement area double overexposedMaxFraction, // allowed fraction of the overexposed pixels in the PSF kernel measurement area
double minDefinedArea, // minimal (weighted) fraction of the defined patter pixels in the FFT area double minDefinedArea, // minimal (weighted) fraction of the defined patter pixels in the FFT area
int PSFKernelSize, int PSFKernelSize,
boolean approximateGrid, // approximate grid with polynomial boolean approximateGrid, // approximate grid with polynomial
...@@ -633,7 +636,7 @@ public class LensAdjustment { ...@@ -633,7 +636,7 @@ public class LensAdjustment {
double [] postUVscrewSensitivity, // microns/turn for 3 post-UV fixture adjustment screws double [] postUVscrewSensitivity, // microns/turn for 3 post-UV fixture adjustment screws
boolean flatFieldCorrection, boolean flatFieldCorrection,
double flatFieldExpand, double flatFieldExpand,
double thresholdFinish,// (copied from series) stop iterations if 2 last steps had less improvement (but not worsening ) double thresholdFinish,// (copied from series) stop iterations if 2 last steps had less improvement (but not worsening )
int numIterations, // maximal number of iterations int numIterations, // maximal number of iterations
boolean cameraIsConfigured, boolean cameraIsConfigured,
boolean useExtraSensor, boolean useExtraSensor,
...@@ -655,15 +658,15 @@ public class LensAdjustment { ...@@ -655,15 +658,15 @@ public class LensAdjustment {
this.showResults=showResults; // show focusing (includingh intermediate) results this.showResults=showResults; // show focusing (includingh intermediate) results
this.serialNumber=serialNumber; // camera serial number string this.serialNumber=serialNumber; // camera serial number string
this.sensorTemperature=sensorTemperature; // last measured sensor temperature this.sensorTemperature=sensorTemperature; // last measured sensor temperature
this.result_lastKT=result_lastKT; // focal distance temperature coefficient (um/C), measured from last run this.result_lastKT=result_lastKT; // focal distance temperature coefficient (um/C), measured from last run
this.result_lastFD20=result_lastFD20; // focal distance for 20C, measured from last run this.result_lastFD20=result_lastFD20; // focal distance for 20C, measured from last run
this.result_allHistoryKT=result_allHistoryKT; // focal distance temperature coefficient (um/C), measured from all the measurement histgory this.result_allHistoryKT=result_allHistoryKT; // focal distance temperature coefficient (um/C), measured from all the measurement histgory
this.result_allHistoryFD20=result_allHistoryFD20; // focal distance for 20C, measured from all the measurement histgory this.result_allHistoryFD20=result_allHistoryFD20; // focal distance for 20C, measured from all the measurement histgory
this.result_fDistance=result_fDistance; // last measured focal distance this.result_fDistance=result_fDistance; // last measured focal distance
this.result_tiltX=result_tiltX; // last measured tilt X this.result_tiltX=result_tiltX; // last measured tilt X
this.result_tiltY=result_tiltY; // last measured tilt Y this.result_tiltY=result_tiltY; // last measured tilt Y
this.result_R50=result_R50; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings) this.result_R50=result_R50; // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings)
this.result_A50=result_A50; // last measured A50 (simailar, but R^2 are averaged) this.result_A50=result_A50; // last measured A50 (simailar, but R^2 are averaged)
this.result_B50=result_B50; // last measured B50 (simailar, but R^4 are averaged) this.result_B50=result_B50; // last measured B50 (simailar, but R^4 are averaged)
this.result_RC50=result_RC50; // last measured RC50(R50 calculated only for the 2 center samples) this.result_RC50=result_RC50; // last measured RC50(R50 calculated only for the 2 center samples)
this.result_PX0=result_PX0; // lens center shift, X this.result_PX0=result_PX0; // lens center shift, X
...@@ -676,7 +679,7 @@ public class LensAdjustment { ...@@ -676,7 +679,7 @@ public class LensAdjustment {
this.manufacturingState=manufacturingState; this.manufacturingState=manufacturingState;
this.askLensSerial=askLensSerial; this.askLensSerial=askLensSerial;
this.includeLensSerial=includeLensSerial; // add lens serial to config filename this.includeLensSerial=includeLensSerial; // add lens serial to config filename
this.centerDeltaX=centerDeltaX; // required X-difference between lens center and sensor center this.centerDeltaX=centerDeltaX; // required X-difference between lens center and sensor center
this.centerDeltaY=centerDeltaY; // required Y-difference between lens center and sensor center this.centerDeltaY=centerDeltaY; // required Y-difference between lens center and sensor center
this.margins=(Rectangle) margins.clone(); this.margins=(Rectangle) margins.clone();
// this.origin=origin.clone(); // top left corner // this.origin=origin.clone(); // top left corner
...@@ -701,17 +704,17 @@ public class LensAdjustment { ...@@ -701,17 +704,17 @@ public class LensAdjustment {
this.weightRatioRedToGreen=weightRatioRedToGreen; // Use this data when combining defocusing data from different color PSF this.weightRatioRedToGreen=weightRatioRedToGreen; // Use this data when combining defocusing data from different color PSF
this.weightRatioBlueToGreen=weightRatioBlueToGreen; this.weightRatioBlueToGreen=weightRatioBlueToGreen;
this.targetFarNear=targetFarNear; // target logariphm of average tangential-to-radial resolution this.targetFarNear=targetFarNear; // target logariphm of average tangential-to-radial resolution
this.useRadialTangential=useRadialTangential; // Use targetFarNear (radial/tangential resolution) as a proxy for the distance this.useRadialTangential=useRadialTangential; // Use targetFarNear (radial/tangential resolution) as a proxy for the distance
this.targetMicrons=targetMicrons; // target lens center distance (away from "best focus" this.targetMicrons=targetMicrons; // target lens center distance (away from "best focus"
this.toleranceMicrons=toleranceMicrons; // microns this.toleranceMicrons=toleranceMicrons; // microns
this.toleranceTilt=toleranceTilt; // this.toleranceTilt=toleranceTilt; //
this.toleranceThreshold=toleranceThreshold; // When each error is under swcaled thereshold, reduce correxction step twice this.toleranceThreshold=toleranceThreshold; // When each error is under swcaled thereshold, reduce correxction step twice
this.parallelAdjustThreshold=parallelAdjustThreshold; // adjust 3 motors parallel if focal distance error in the center exceeds this this.parallelAdjustThreshold=parallelAdjustThreshold; // adjust 3 motors parallel if focal distance error in the center exceeds this
this.motorsSigma=motorsSigma; // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma this.motorsSigma=motorsSigma; // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma
this.motorsSigma3=motorsSigma3; // same when 3 motors move together this.motorsSigma3=motorsSigma3; // same when 3 motors move together
this.motorsMinSigma=motorsMinSigma; // sigma will not drop below this value when fitting walk is getting smaller this.motorsMinSigma=motorsMinSigma; // sigma will not drop below this value when fitting walk is getting smaller
this.motorsVarSigmaToTravel=motorsVarSigmaToTravel;// when walk is getting smaller, sigma will keep going down proportionally this.motorsVarSigmaToTravel=motorsVarSigmaToTravel;// when walk is getting smaller, sigma will keep going down proportionally
this.motorsFadeSigma=motorsFadeSigma; // after each step new sigma will have this part of the calculated from the travel this.motorsFadeSigma=motorsFadeSigma; // after each step new sigma will have this part of the calculated from the travel
this.motorsOverShootToBalance=motorsOverShootToBalance;//For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side this.motorsOverShootToBalance=motorsOverShootToBalance;//For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side
this.filterGoodDistance=filterGoodDistance; // when measuring tilt, use those with good center with higher weight this.filterGoodDistance=filterGoodDistance; // when measuring tilt, use those with good center with higher weight
this.goodDistanceSigma=goodDistanceSigma; // sigma for the weight function of tilt measurements, depending on the center distance error this.goodDistanceSigma=goodDistanceSigma; // sigma for the weight function of tilt measurements, depending on the center distance error
...@@ -722,7 +725,7 @@ public class LensAdjustment { ...@@ -722,7 +725,7 @@ public class LensAdjustment {
this.probe_M3_M1M2=probe_M3_M1M2; // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2 this.probe_M3_M1M2=probe_M3_M1M2; // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2
this.probe_M2_M1=probe_M2_M1; // how far to move M2 opposite to M1: M2-M1 this.probe_M2_M1=probe_M2_M1; // how far to move M2 opposite to M1: M2-M1
this.sigmaToProbe=sigmaToProbe; // data from far samples decay proportionally to the probe distances this.sigmaToProbe=sigmaToProbe; // data from far samples decay proportionally to the probe distances
this.useTheBest=useTheBest; // adjust from the best known position (false - from the last) this.useTheBest=useTheBest; // adjust from the best known position (false - from the last)
this.probeSymmetrical=probeSymmetrical; // if true, probe 6 measurements), if false - only 4 (tetrahedron) this.probeSymmetrical=probeSymmetrical; // if true, probe 6 measurements), if false - only 4 (tetrahedron)
this.parallelBeforeProbing=parallelBeforeProbing; // move 3 motors before probing around this.parallelBeforeProbing=parallelBeforeProbing; // move 3 motors before probing around
this.reProbeDistance=reProbeDistance; // re-run probing around in orthoganal directions, if the current position move farther from the last probing one this.reProbeDistance=reProbeDistance; // re-run probing around in orthoganal directions, if the current position move farther from the last probing one
...@@ -742,7 +745,7 @@ public class LensAdjustment { ...@@ -742,7 +745,7 @@ public class LensAdjustment {
this.scanNumberNegative=scanNumberNegative; // of them negative this.scanNumberNegative=scanNumberNegative; // of them negative
this.scanHysteresis=scanHysteresis; // scan both ways this.scanHysteresis=scanHysteresis; // scan both ways
this.scanHysteresisNumber=scanHysteresisNumber; // number of test points for the Hysteresis measurement this.scanHysteresisNumber=scanHysteresisNumber; // number of test points for the Hysteresis measurement
this.scanTiltEnable=scanTiltEnable; //=true; // enable scanning tilt this.scanTiltEnable=scanTiltEnable; //=true; // enable scanning tilt
this.scanTiltReverse=scanTiltReverse; this.scanTiltReverse=scanTiltReverse;
this.scanMeasureLast=scanMeasureLast; this.scanMeasureLast=scanMeasureLast;
...@@ -751,15 +754,15 @@ public class LensAdjustment { ...@@ -751,15 +754,15 @@ public class LensAdjustment {
this.scanTiltRangeY=scanTiltRangeY; //, //=14336; // 4 periods this.scanTiltRangeY=scanTiltRangeY; //, //=14336; // 4 periods
this.scanTiltStepsX=scanTiltStepsX; //=24; this.scanTiltStepsX=scanTiltStepsX; //=24;
this.scanTiltStepsY=scanTiltStepsY; //=24; this.scanTiltStepsY=scanTiltStepsY; //=24;
this.motorHysteresis=motorHysteresis; this.motorHysteresis=motorHysteresis;
this.measuredHysteresis=measuredHysteresis; // actually measured (will be saved/restored) this.measuredHysteresis=measuredHysteresis; // actually measured (will be saved/restored)
this.motorCalm=motorCalm; // wait (seconds) after motors reached final position (for the first time) before acquiring image this.motorCalm=motorCalm; // wait (seconds) after motors reached final position (for the first time) before acquiring image
this.linearReductionRatio=linearReductionRatio; // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105 this.linearReductionRatio=linearReductionRatio; // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105
this.motorDebug=motorDebug;// 1 show motor moves, 2 - show hysteresis back-ups too this.motorDebug=motorDebug;// 1 show motor moves, 2 - show hysteresis back-ups too
this.lensDistanceNumPoints=lensDistanceNumPoints; // number of points to tabulate center focus parameters vs. focal distance this.lensDistanceNumPoints=lensDistanceNumPoints; // number of points to tabulate center focus parameters vs. focal distance
this.lensDistancePolynomialDegree=lensDistancePolynomialDegree; // polynomial degree to approximate center focus parameters vs. focal distance this.lensDistancePolynomialDegree=lensDistancePolynomialDegree; // polynomial degree to approximate center focus parameters vs. focal distance
this.lensDistanceWeightY=lensDistanceWeightY; // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones this.lensDistanceWeightY=lensDistanceWeightY; // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones
this.lensDistanceWeightK=lensDistanceWeightK; // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives this.lensDistanceWeightK=lensDistanceWeightK; // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives
this.lensDistanceInteractive=lensDistanceInteractive; // Open dialog when calibrating focal distance this.lensDistanceInteractive=lensDistanceInteractive; // Open dialog when calibrating focal distance
this.lensDistanceShowResults=lensDistanceShowResults; // show results window from foca this.lensDistanceShowResults=lensDistanceShowResults; // show results window from foca
...@@ -774,12 +777,12 @@ public class LensAdjustment { ...@@ -774,12 +777,12 @@ public class LensAdjustment {
this.uvLasersCurrents=uvLasersCurrents.clone(); // default LED on currents (mA) this.uvLasersCurrents=uvLasersCurrents.clone(); // default LED on currents (mA)
this.smallestSubPix=smallestSubPix; this.smallestSubPix=smallestSubPix;
this.bitmapNonuniforityThreshold=bitmapNonuniforityThreshold; this.bitmapNonuniforityThreshold=bitmapNonuniforityThreshold;
this.subdiv=subdiv; this.subdiv=subdiv;
this.overexposedMaxFraction=overexposedMaxFraction; this.overexposedMaxFraction=overexposedMaxFraction;
this.minDefinedArea=minDefinedArea; this.minDefinedArea=minDefinedArea;
this.PSFKernelSize=PSFKernelSize; this.PSFKernelSize=PSFKernelSize;
this.approximateGrid = approximateGrid; // approximate grid with polynomial this.approximateGrid = approximateGrid; // approximate grid with polynomial
this.centerPSF = centerPSF; // approximate grid with polynomial this.centerPSF = centerPSF; // approximate grid with polynomial
this.mask1_sigma = mask1_sigma; this.mask1_sigma = mask1_sigma;
this.mask1_threshold = mask1_threshold; this.mask1_threshold = mask1_threshold;
this.gaps_sigma=gaps_sigma; this.gaps_sigma=gaps_sigma;
...@@ -795,7 +798,7 @@ public class LensAdjustment { ...@@ -795,7 +798,7 @@ public class LensAdjustment {
this.postUVscrewSensitivity=postUVscrewSensitivity.clone(); // microns/turn for 3 post-UV fixture adjustment screws this.postUVscrewSensitivity=postUVscrewSensitivity.clone(); // microns/turn for 3 post-UV fixture adjustment screws
this.flatFieldCorrection=flatFieldCorrection; this.flatFieldCorrection=flatFieldCorrection;
this.flatFieldExpand=flatFieldExpand; this.flatFieldExpand=flatFieldExpand;
this.thresholdFinish=thresholdFinish;// (copied from series) stop iterations if 2 last steps had less improvement (but not worsening ) this.thresholdFinish=thresholdFinish;// (copied from series) stop iterations if 2 last steps had less improvement (but not worsening )
this.numIterations=numIterations; // maximal number of iterations this.numIterations=numIterations; // maximal number of iterations
this.cameraIsConfigured=cameraIsConfigured; this.cameraIsConfigured=cameraIsConfigured;
this.useExtraSensor=useExtraSensor; this.useExtraSensor=useExtraSensor;
...@@ -806,7 +809,8 @@ public class LensAdjustment { ...@@ -806,7 +809,8 @@ public class LensAdjustment {
this.reportTemperature=reportTemperature; this.reportTemperature=reportTemperature;
this.showLegacy=showLegacy; this.showLegacy=showLegacy;
} }
public FocusMeasurementParameters clone(){ @Override
public FocusMeasurementParameters clone(){
return new FocusMeasurementParameters( return new FocusMeasurementParameters(
this.gridGeometryFile, this.gridGeometryFile,
this.initialCalibrationFile, this.initialCalibrationFile,
...@@ -819,15 +823,15 @@ public class LensAdjustment { ...@@ -819,15 +823,15 @@ public class LensAdjustment {
this.showResults, // show focusing (includingh intermediate) results this.showResults, // show focusing (includingh intermediate) results
this.serialNumber, // camera serial number string this.serialNumber, // camera serial number string
this.sensorTemperature, // last measured sensor temperature this.sensorTemperature, // last measured sensor temperature
this.result_lastKT, // focal distance temperature coefficient (um/C), measured from last run this.result_lastKT, // focal distance temperature coefficient (um/C), measured from last run
this.result_lastFD20, // focal distance for 20C, measured from last run this.result_lastFD20, // focal distance for 20C, measured from last run
this.result_allHistoryKT, // focal distance temperature coefficient (um/C), measured from all the measurement histgory this.result_allHistoryKT, // focal distance temperature coefficient (um/C), measured from all the measurement histgory
this.result_allHistoryFD20, // focal distance for 20C, measured from all the measurement histgory this.result_allHistoryFD20, // focal distance for 20C, measured from all the measurement histgory
this.result_fDistance, // last measured focal distance this.result_fDistance, // last measured focal distance
this.result_tiltX, // last measured tilt X this.result_tiltX, // last measured tilt X
this.result_tiltY, // last measured tilt Y this.result_tiltY, // last measured tilt Y
this.result_R50, // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings) this.result_R50, // last measured R50 (average PSF 50% level radius, pixels - somewhat larged than actual because of measurement settings)
this.result_A50, // last measured A50 (simailar, but R^2 are averaged) this.result_A50, // last measured A50 (simailar, but R^2 are averaged)
this.result_B50, // last measured B50 (simailar, but R^4 are averaged) this.result_B50, // last measured B50 (simailar, but R^4 are averaged)
this.result_RC50, // last measured RC50(R50 calculated only for the 2 center samples) this.result_RC50, // last measured RC50(R50 calculated only for the 2 center samples)
this.result_PX0, // lens center shift, X this.result_PX0, // lens center shift, X
...@@ -840,7 +844,7 @@ public class LensAdjustment { ...@@ -840,7 +844,7 @@ public class LensAdjustment {
this.manufacturingState, this.manufacturingState,
this.askLensSerial, this.askLensSerial,
this.includeLensSerial, // add lens serial to config filename this.includeLensSerial, // add lens serial to config filename
this.centerDeltaX, // required X-difference between lens center and sensor center this.centerDeltaX, // required X-difference between lens center and sensor center
this.centerDeltaY, // required Y-difference between lens center and sensor center this.centerDeltaY, // required Y-difference between lens center and sensor center
this.margins, this.margins,
this.numSamples, this.numSamples,
...@@ -863,18 +867,18 @@ public class LensAdjustment { ...@@ -863,18 +867,18 @@ public class LensAdjustment {
this.weightRatioRedToGreen, // Use this data when combining defocusing data from different color PSF this.weightRatioRedToGreen, // Use this data when combining defocusing data from different color PSF
this.weightRatioBlueToGreen, this.weightRatioBlueToGreen,
this.targetFarNear, // target logariphm of average tangential-to-radial resolution this.targetFarNear, // target logariphm of average tangential-to-radial resolution
this.useRadialTangential, // Use targetFarNear (radial/tangential resolution) as a proxy for the distance this.useRadialTangential, // Use targetFarNear (radial/tangential resolution) as a proxy for the distance
this.targetMicrons, // target lens center distance (away from "best focus" this.targetMicrons, // target lens center distance (away from "best focus"
this.toleranceMicrons, // microns this.toleranceMicrons, // microns
this.toleranceTilt, // this.toleranceTilt, //
this.toleranceThreshold, // When each error is under swcaled thereshold, reduce correxction step twice this.toleranceThreshold, // When each error is under swcaled thereshold, reduce correxction step twice
this.parallelAdjustThreshold, // adjust 3 motors parallel if focal distance error in the center exceeds this this.parallelAdjustThreshold, // adjust 3 motors parallel if focal distance error in the center exceeds this
this.motorsSigma, // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma this.motorsSigma, // when fitting planes for far/near, tiltX and tiltY the weights of the samples decay with this sigma
this.motorsSigma3, // same when 3 motors move together this.motorsSigma3, // same when 3 motors move together
this.motorsMinSigma, // sigma will not drop below this value when fitting walk is getting smaller this.motorsMinSigma, // sigma will not drop below this value when fitting walk is getting smaller
this.motorsVarSigmaToTravel, // when walk is getting smaller, sigma will keep going down proportionally this.motorsVarSigmaToTravel, // when walk is getting smaller, sigma will keep going down proportionally
this.motorsFadeSigma, // after each step new sigma will have this part of the calculated from the travel this.motorsFadeSigma, // after each step new sigma will have this part of the calculated from the travel
this.motorsOverShootToBalance, //For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side this.motorsOverShootToBalance, //For quadratic maximum the correction will be increased by 1+motorsOverShootToBalance if there are less samples on teh other side
this.filterGoodDistance, // when measuring tilt, use those with good center with higher weight this.filterGoodDistance, // when measuring tilt, use those with good center with higher weight
this.goodDistanceSigma, // sigma for the weight function of tilt measurements, depending on the center distance error this.goodDistanceSigma, // sigma for the weight function of tilt measurements, depending on the center distance error
...@@ -884,8 +888,8 @@ public class LensAdjustment { ...@@ -884,8 +888,8 @@ public class LensAdjustment {
this.probe_M1M2M3, // how far to move average of the 3 motors: (M1+M2+M3)/3 this.probe_M1M2M3, // how far to move average of the 3 motors: (M1+M2+M3)/3
this.probe_M3_M1M2, // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2 this.probe_M3_M1M2, // how far to move M3 opposite to M1 and M2: M3-(M1+M2)/2
this.probe_M2_M1, // how far to move M2 opposite to M1: M2-M1 this.probe_M2_M1, // how far to move M2 opposite to M1: M2-M1
this.sigmaToProbe, // data from far samples decay proportionally to the probe distances this.sigmaToProbe, // data from far samples decay proportionally to the probe distances
this.useTheBest, // adjust from the best known position (false - from the last) this.useTheBest, // adjust from the best known position (false - from the last)
this.probeSymmetrical, // if true, probe 6 measurements), if false - only 4 (tetrahedron) this.probeSymmetrical, // if true, probe 6 measurements), if false - only 4 (tetrahedron)
this.parallelBeforeProbing, // move 3 motors before probing around this.parallelBeforeProbing, // move 3 motors before probing around
this.reProbeDistance, // re-run probing around in orthoganal directions, if the current position move farther from the last probing one this.reProbeDistance, // re-run probing around in orthoganal directions, if the current position move farther from the last probing one
...@@ -905,7 +909,7 @@ public class LensAdjustment { ...@@ -905,7 +909,7 @@ public class LensAdjustment {
this.scanNumberNegative, // of them negative this.scanNumberNegative, // of them negative
this.scanHysteresis, // scan both ways this.scanHysteresis, // scan both ways
this.scanHysteresisNumber, // number of test points for the Hysteresis measurement this.scanHysteresisNumber, // number of test points for the Hysteresis measurement
this.scanTiltEnable, // enable scanning tilt this.scanTiltEnable, // enable scanning tilt
this.scanTiltReverse, this.scanTiltReverse,
this.scanMeasureLast, this.scanMeasureLast,
...@@ -915,14 +919,14 @@ public class LensAdjustment { ...@@ -915,14 +919,14 @@ public class LensAdjustment {
this.scanTiltStepsX, this.scanTiltStepsX,
this.scanTiltStepsY, this.scanTiltStepsY,
this.motorHysteresis, this.motorHysteresis,
this.measuredHysteresis, // actually measured (will be saved/restored) this.measuredHysteresis, // actually measured (will be saved/restored)
this.motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image this.motorCalm, // wait (seconds) after motors reached final position (for the first time) before acquiring image
this.linearReductionRatio, // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105 this.linearReductionRatio, // sensor travel to motors travel (all 3 together), By design it is 4/38~=0.105
this.motorDebug, // 1 show motor moves, 2 - show hysteresis back-ups too this.motorDebug, // 1 show motor moves, 2 - show hysteresis back-ups too
this.lensDistanceNumPoints, // number of points to tabulate center focus parameters vs. focal distance this.lensDistanceNumPoints, // number of points to tabulate center focus parameters vs. focal distance
this.lensDistancePolynomialDegree, // polynomial degree to approximate center focus parameters vs. focal distance this.lensDistancePolynomialDegree, // polynomial degree to approximate center focus parameters vs. focal distance
this.lensDistanceWeightY, // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones this.lensDistanceWeightY, // normalize overall sharpness (that depends on the lens quality and/or PSF parameters) to differential ones
this.lensDistanceWeightK, // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives this.lensDistanceWeightK, // 0.0 use 3 distances (to frac-R, frac-B and Y) with teh same weight when fitting, 1.0 - proportional to squared derivatives
this.lensDistanceInteractive, // Open dialog when calibrating focal distance this.lensDistanceInteractive, // Open dialog when calibrating focal distance
this.lensDistanceShowResults, // show results window from foca this.lensDistanceShowResults, // show results window from foca
...@@ -938,8 +942,8 @@ public class LensAdjustment { ...@@ -938,8 +942,8 @@ public class LensAdjustment {
this.smallestSubPix, this.smallestSubPix,
this.bitmapNonuniforityThreshold, this.bitmapNonuniforityThreshold,
this.subdiv, this.subdiv,
this.overexposedMaxFraction, this.overexposedMaxFraction,
this.minDefinedArea, this.minDefinedArea,
this.PSFKernelSize, this.PSFKernelSize,
this.approximateGrid, this.approximateGrid,
...@@ -959,7 +963,7 @@ public class LensAdjustment { ...@@ -959,7 +963,7 @@ public class LensAdjustment {
this.postUVscrewSensitivity, this.postUVscrewSensitivity,
this.flatFieldCorrection, this.flatFieldCorrection,
this.flatFieldExpand, this.flatFieldExpand,
this.thresholdFinish, this.thresholdFinish,
this.numIterations, this.numIterations,
this.cameraIsConfigured, this.cameraIsConfigured,
this.useExtraSensor, this.useExtraSensor,
...@@ -991,7 +995,7 @@ public class LensAdjustment { ...@@ -991,7 +995,7 @@ public class LensAdjustment {
if (!Double.isNaN(this.result_A50))properties.setProperty(prefix+"result_A50",this.result_A50+""); if (!Double.isNaN(this.result_A50))properties.setProperty(prefix+"result_A50",this.result_A50+"");
if (!Double.isNaN(this.result_B50))properties.setProperty(prefix+"result_B50",this.result_B50+""); if (!Double.isNaN(this.result_B50))properties.setProperty(prefix+"result_B50",this.result_B50+"");
if (!Double.isNaN(this.result_RC50))properties.setProperty(prefix+"result_RC50",this.result_RC50+""); if (!Double.isNaN(this.result_RC50))properties.setProperty(prefix+"result_RC50",this.result_RC50+"");
if (!Double.isNaN(this.result_PX0))properties.setProperty(prefix+"result_PX0",this.result_PX0+""); if (!Double.isNaN(this.result_PX0))properties.setProperty(prefix+"result_PX0",this.result_PX0+"");
if (!Double.isNaN(this.result_PY0))properties.setProperty(prefix+"result_PY0",this.result_PY0+""); if (!Double.isNaN(this.result_PY0))properties.setProperty(prefix+"result_PY0",this.result_PY0+"");
if (!Double.isNaN(this.result_PSI))properties.setProperty(prefix+"result_PSI",this.result_PSI+""); if (!Double.isNaN(this.result_PSI))properties.setProperty(prefix+"result_PSI",this.result_PSI+"");
...@@ -1019,7 +1023,7 @@ public class LensAdjustment { ...@@ -1019,7 +1023,7 @@ public class LensAdjustment {
properties.setProperty(prefix+"maxCorr",this.maxCorr+""); properties.setProperty(prefix+"maxCorr",this.maxCorr+"");
properties.setProperty(prefix+"showHistoryDetails",this.showHistoryDetails+""); properties.setProperty(prefix+"showHistoryDetails",this.showHistoryDetails+"");
properties.setProperty(prefix+"showHistorySamples",this.showHistorySamples+""); properties.setProperty(prefix+"showHistorySamples",this.showHistorySamples+"");
properties.setProperty(prefix+"showHistorySingleLine",this.showHistorySingleLine+""); properties.setProperty(prefix+"showHistorySingleLine",this.showHistorySingleLine+"");
properties.setProperty(prefix+"showAcquiredImages",this.showAcquiredImages+""); properties.setProperty(prefix+"showAcquiredImages",this.showAcquiredImages+"");
properties.setProperty(prefix+"showROI",this.showROI+""); properties.setProperty(prefix+"showROI",this.showROI+"");
...@@ -1048,13 +1052,13 @@ public class LensAdjustment { ...@@ -1048,13 +1052,13 @@ public class LensAdjustment {
properties.setProperty(prefix+"motorsVarSigmaToTravel",this.motorsVarSigmaToTravel+""); properties.setProperty(prefix+"motorsVarSigmaToTravel",this.motorsVarSigmaToTravel+"");
properties.setProperty(prefix+"motorsFadeSigma",this.motorsFadeSigma+""); properties.setProperty(prefix+"motorsFadeSigma",this.motorsFadeSigma+"");
properties.setProperty(prefix+"motorsOverShootToBalance",this.motorsOverShootToBalance+""); properties.setProperty(prefix+"motorsOverShootToBalance",this.motorsOverShootToBalance+"");
properties.setProperty(prefix+"filterGoodDistance",this.filterGoodDistance+""); properties.setProperty(prefix+"filterGoodDistance",this.filterGoodDistance+"");
properties.setProperty(prefix+"goodDistanceSigma",this.goodDistanceSigma+""); properties.setProperty(prefix+"goodDistanceSigma",this.goodDistanceSigma+"");
properties.setProperty(prefix+"goodTiltSigma",this.goodTiltSigma+""); properties.setProperty(prefix+"goodTiltSigma",this.goodTiltSigma+"");
properties.setProperty(prefix+"maxStep",this.maxStep+""); properties.setProperty(prefix+"maxStep",this.maxStep+"");
properties.setProperty(prefix+"probeStep",this.probeStep+""); properties.setProperty(prefix+"probeStep",this.probeStep+"");
properties.setProperty(prefix+"probe_M1M2M3",this.probe_M1M2M3+""); properties.setProperty(prefix+"probe_M1M2M3",this.probe_M1M2M3+"");
properties.setProperty(prefix+"probe_M3_M1M2",this.probe_M3_M1M2+""); properties.setProperty(prefix+"probe_M3_M1M2",this.probe_M3_M1M2+"");
properties.setProperty(prefix+"probe_M2_M1",this.probe_M2_M1+""); properties.setProperty(prefix+"probe_M2_M1",this.probe_M2_M1+"");
...@@ -1099,20 +1103,20 @@ public class LensAdjustment { ...@@ -1099,20 +1103,20 @@ public class LensAdjustment {
properties.setProperty(prefix+"lensDistanceInteractive",this.lensDistanceInteractive+""); properties.setProperty(prefix+"lensDistanceInteractive",this.lensDistanceInteractive+"");
properties.setProperty(prefix+"lensDistanceShowResults",this.lensDistanceShowResults+""); properties.setProperty(prefix+"lensDistanceShowResults",this.lensDistanceShowResults+"");
properties.setProperty(prefix+"lensDistanceMoveToGoal",this.lensDistanceMoveToGoal+""); properties.setProperty(prefix+"lensDistanceMoveToGoal",this.lensDistanceMoveToGoal+"");
properties.setProperty(prefix+"powerControlEnable",this.powerControlEnable+""); properties.setProperty(prefix+"powerControlEnable",this.powerControlEnable+"");
properties.setProperty(prefix+"powerControlMaximalTemperature",this.powerControlMaximalTemperature+""); properties.setProperty(prefix+"powerControlMaximalTemperature",this.powerControlMaximalTemperature+"");
properties.setProperty(prefix+"powerControlHeaterOnMinutes",this.powerControlHeaterOnMinutes+""); properties.setProperty(prefix+"powerControlHeaterOnMinutes",this.powerControlHeaterOnMinutes+"");
properties.setProperty(prefix+"powerControlNeitherOnMinutes",this.powerControlNeitherOnMinutes+""); properties.setProperty(prefix+"powerControlNeitherOnMinutes",this.powerControlNeitherOnMinutes+"");
properties.setProperty(prefix+"powerControlFanOnMinutes",this.powerControlFanOnMinutes+""); properties.setProperty(prefix+"powerControlFanOnMinutes",this.powerControlFanOnMinutes+"");
properties.setProperty(prefix+"uvLasersIP",this.uvLasersIP); properties.setProperty(prefix+"uvLasersIP",this.uvLasersIP);
properties.setProperty(prefix+"uvLasersBus",this.uvLasersBus+""); properties.setProperty(prefix+"uvLasersBus",this.uvLasersBus+"");
properties.setProperty(prefix+"uvLasersCurrents_0",this.uvLasersCurrents[0]+""); properties.setProperty(prefix+"uvLasersCurrents_0",this.uvLasersCurrents[0]+"");
properties.setProperty(prefix+"uvLasersCurrents_1",this.uvLasersCurrents[1]+""); properties.setProperty(prefix+"uvLasersCurrents_1",this.uvLasersCurrents[1]+"");
properties.setProperty(prefix+"uvLasersCurrents_2",this.uvLasersCurrents[2]+""); properties.setProperty(prefix+"uvLasersCurrents_2",this.uvLasersCurrents[2]+"");
properties.setProperty(prefix+"uvLasersCurrents_3",this.uvLasersCurrents[3]+""); properties.setProperty(prefix+"uvLasersCurrents_3",this.uvLasersCurrents[3]+"");
properties.setProperty(prefix+"smallestSubPix",this.smallestSubPix+""); properties.setProperty(prefix+"smallestSubPix",this.smallestSubPix+"");
properties.setProperty(prefix+"bitmapNonuniforityThreshold",this.bitmapNonuniforityThreshold+""); properties.setProperty(prefix+"bitmapNonuniforityThreshold",this.bitmapNonuniforityThreshold+"");
properties.setProperty(prefix+"subdiv",this.subdiv+""); properties.setProperty(prefix+"subdiv",this.subdiv+"");
...@@ -1129,7 +1133,7 @@ public class LensAdjustment { ...@@ -1129,7 +1133,7 @@ public class LensAdjustment {
properties.setProperty(prefix+"correlationSize",this.correlationSize+""); properties.setProperty(prefix+"correlationSize",this.correlationSize+"");
properties.setProperty(prefix+"correlationGaussWidth",this.correlationGaussWidth+""); properties.setProperty(prefix+"correlationGaussWidth",this.correlationGaussWidth+"");
properties.setProperty(prefix+"minUVSpan",this.minUVSpan+""); properties.setProperty(prefix+"minUVSpan",this.minUVSpan+"");
properties.setProperty(prefix+"correlationMinContrast",this.correlationMinContrast+""); properties.setProperty(prefix+"correlationMinContrast",this.correlationMinContrast+"");
properties.setProperty(prefix+"correlationMinInitialContrast",this.correlationMinInitialContrast+""); properties.setProperty(prefix+"correlationMinInitialContrast",this.correlationMinInitialContrast+"");
properties.setProperty(prefix+"correlationMinAbsoluteContrast",this.correlationMinAbsoluteContrast+""); properties.setProperty(prefix+"correlationMinAbsoluteContrast",this.correlationMinAbsoluteContrast+"");
...@@ -1141,11 +1145,11 @@ public class LensAdjustment { ...@@ -1141,11 +1145,11 @@ public class LensAdjustment {
properties.setProperty(prefix+"flatFieldExpand",this.flatFieldExpand+""); properties.setProperty(prefix+"flatFieldExpand",this.flatFieldExpand+"");
properties.setProperty(prefix+"thresholdFinish",this.thresholdFinish+""); properties.setProperty(prefix+"thresholdFinish",this.thresholdFinish+"");
properties.setProperty(prefix+"numIterations",this.numIterations+""); properties.setProperty(prefix+"numIterations",this.numIterations+"");
for (int i=0;i<this.ampsSeconds.length;i++) for (int i=0;i<this.ampsSeconds.length;i++)
properties.setProperty(prefix+"ampsSeconds_"+i,this.ampsSeconds[i]+""); properties.setProperty(prefix+"ampsSeconds_"+i,this.ampsSeconds[i]+"");
properties.setProperty(prefix+"reportTemperature",this.reportTemperature+""); properties.setProperty(prefix+"reportTemperature",this.reportTemperature+"");
properties.setProperty(prefix+"showLegacy",this.showLegacy+""); properties.setProperty(prefix+"showLegacy",this.showLegacy+"");
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
if (properties.getProperty(prefix+"gridGeometryFile")!=null) if (properties.getProperty(prefix+"gridGeometryFile")!=null)
this.gridGeometryFile=properties.getProperty(prefix+"gridGeometryFile"); this.gridGeometryFile=properties.getProperty(prefix+"gridGeometryFile");
...@@ -1160,11 +1164,11 @@ public class LensAdjustment { ...@@ -1160,11 +1164,11 @@ public class LensAdjustment {
if (properties.getProperty(prefix+"useLMAMetrics")!=null) if (properties.getProperty(prefix+"useLMAMetrics")!=null)
this.useLMAMetrics=Boolean.parseBoolean(properties.getProperty(prefix+"useLMAMetrics")); this.useLMAMetrics=Boolean.parseBoolean(properties.getProperty(prefix+"useLMAMetrics"));
if (properties.getProperty(prefix+"serialNumber")!=null) if (properties.getProperty(prefix+"serialNumber")!=null)
this.serialNumber=properties.getProperty(prefix+"serialNumber"); this.serialNumber=properties.getProperty(prefix+"serialNumber");
// this.serialNumber is only written, but never read from the configuration file (only from devivce) // this.serialNumber is only written, but never read from the configuration file (only from devivce)
if (properties.getProperty(prefix+"sensorTemperature")!=null) this.sensorTemperature=Double.parseDouble(properties.getProperty(prefix+"sensorTemperature")); if (properties.getProperty(prefix+"sensorTemperature")!=null) this.sensorTemperature=Double.parseDouble(properties.getProperty(prefix+"sensorTemperature"));
else this.sensorTemperature=Double.NaN; else this.sensorTemperature=Double.NaN;
if (properties.getProperty(prefix+"result_lastKT")!=null) this.result_lastKT=Double.parseDouble(properties.getProperty(prefix+"result_lastKT")); if (properties.getProperty(prefix+"result_lastKT")!=null) this.result_lastKT=Double.parseDouble(properties.getProperty(prefix+"result_lastKT"));
...@@ -1260,7 +1264,7 @@ public class LensAdjustment { ...@@ -1260,7 +1264,7 @@ public class LensAdjustment {
this.useExtraSensor=Boolean.parseBoolean(properties.getProperty(prefix+"useExtraSensor")); this.useExtraSensor=Boolean.parseBoolean(properties.getProperty(prefix+"useExtraSensor"));
if (properties.getProperty(prefix+"enRoundOff")!=null) if (properties.getProperty(prefix+"enRoundOff")!=null)
this.enRoundOff = Boolean.parseBoolean(properties.getProperty(prefix+"enRoundOff")); this.enRoundOff = Boolean.parseBoolean(properties.getProperty(prefix+"enRoundOff"));
if (properties.getProperty(prefix+"keepCircularMask")!=null) if (properties.getProperty(prefix+"keepCircularMask")!=null)
this.keepCircularMask=Boolean.parseBoolean(properties.getProperty(prefix+"keepCircularMask")); this.keepCircularMask=Boolean.parseBoolean(properties.getProperty(prefix+"keepCircularMask"));
if (properties.getProperty(prefix+"psf_cutoffEnergy")!=null) if (properties.getProperty(prefix+"psf_cutoffEnergy")!=null)
...@@ -1301,20 +1305,20 @@ public class LensAdjustment { ...@@ -1301,20 +1305,20 @@ public class LensAdjustment {
this.motorsFadeSigma=Double.parseDouble(properties.getProperty(prefix+"motorsFadeSigma")); this.motorsFadeSigma=Double.parseDouble(properties.getProperty(prefix+"motorsFadeSigma"));
if (properties.getProperty(prefix+"motorsOverShootToBalance")!=null) if (properties.getProperty(prefix+"motorsOverShootToBalance")!=null)
this.motorsOverShootToBalance=Double.parseDouble(properties.getProperty(prefix+"motorsOverShootToBalance")); this.motorsOverShootToBalance=Double.parseDouble(properties.getProperty(prefix+"motorsOverShootToBalance"));
if (properties.getProperty(prefix+"filterGoodDistance")!=null) if (properties.getProperty(prefix+"filterGoodDistance")!=null)
this.filterGoodDistance=Boolean.parseBoolean(properties.getProperty(prefix+"filterGoodDistance")); this.filterGoodDistance=Boolean.parseBoolean(properties.getProperty(prefix+"filterGoodDistance"));
if (properties.getProperty(prefix+"goodDistanceSigma")!=null) if (properties.getProperty(prefix+"goodDistanceSigma")!=null)
this.goodDistanceSigma=Double.parseDouble(properties.getProperty(prefix+"goodDistanceSigma")); this.goodDistanceSigma=Double.parseDouble(properties.getProperty(prefix+"goodDistanceSigma"));
if (properties.getProperty(prefix+"goodTiltSigma")!=null) if (properties.getProperty(prefix+"goodTiltSigma")!=null)
this.goodTiltSigma=Double.parseDouble(properties.getProperty(prefix+"goodTiltSigma")); this.goodTiltSigma=Double.parseDouble(properties.getProperty(prefix+"goodTiltSigma"));
if (properties.getProperty(prefix+"maxStep")!=null) if (properties.getProperty(prefix+"maxStep")!=null)
this.maxStep=Double.parseDouble(properties.getProperty(prefix+"maxStep")); this.maxStep=Double.parseDouble(properties.getProperty(prefix+"maxStep"));
if (properties.getProperty(prefix+"probeStep")!=null) if (properties.getProperty(prefix+"probeStep")!=null)
this.probeStep=Double.parseDouble(properties.getProperty(prefix+"probeStep")); this.probeStep=Double.parseDouble(properties.getProperty(prefix+"probeStep"));
if (properties.getProperty(prefix+"probe_M1M2M3")!=null) if (properties.getProperty(prefix+"probe_M1M2M3")!=null)
this.probe_M1M2M3=Double.parseDouble(properties.getProperty(prefix+"probe_M1M2M3")); this.probe_M1M2M3=Double.parseDouble(properties.getProperty(prefix+"probe_M1M2M3"));
if (properties.getProperty(prefix+"probe_M3_M1M2")!=null) if (properties.getProperty(prefix+"probe_M3_M1M2")!=null)
...@@ -1368,14 +1372,14 @@ public class LensAdjustment { ...@@ -1368,14 +1372,14 @@ public class LensAdjustment {
this.scanTiltEnable=Boolean.parseBoolean(properties.getProperty(prefix+"scanTiltEnable")); this.scanTiltEnable=Boolean.parseBoolean(properties.getProperty(prefix+"scanTiltEnable"));
if (properties.getProperty(prefix+"scanTiltReverse")!=null) if (properties.getProperty(prefix+"scanTiltReverse")!=null)
this.scanTiltReverse=Boolean.parseBoolean(properties.getProperty(prefix+"scanTiltReverse")); this.scanTiltReverse=Boolean.parseBoolean(properties.getProperty(prefix+"scanTiltReverse"));
if (properties.getProperty(prefix+"scanMeasureLast")!=null) if (properties.getProperty(prefix+"scanMeasureLast")!=null)
this.scanMeasureLast=Boolean.parseBoolean(properties.getProperty(prefix+"scanMeasureLast")); this.scanMeasureLast=Boolean.parseBoolean(properties.getProperty(prefix+"scanMeasureLast"));
if (properties.getProperty(prefix+"scanRunLMA")!=null) if (properties.getProperty(prefix+"scanRunLMA")!=null)
this.scanRunLMA=Boolean.parseBoolean(properties.getProperty(prefix+"scanRunLMA")); this.scanRunLMA=Boolean.parseBoolean(properties.getProperty(prefix+"scanRunLMA"));
if (properties.getProperty(prefix+"scanTiltRangeX")!=null) if (properties.getProperty(prefix+"scanTiltRangeX")!=null)
this.scanTiltRangeX=Integer.parseInt(properties.getProperty(prefix+"scanTiltRangeX")); this.scanTiltRangeX=Integer.parseInt(properties.getProperty(prefix+"scanTiltRangeX"));
if (properties.getProperty(prefix+"scanTiltRangeY")!=null) if (properties.getProperty(prefix+"scanTiltRangeY")!=null)
...@@ -1384,7 +1388,7 @@ public class LensAdjustment { ...@@ -1384,7 +1388,7 @@ public class LensAdjustment {
this.scanTiltStepsX=Integer.parseInt(properties.getProperty(prefix+"scanTiltStepsX")); this.scanTiltStepsX=Integer.parseInt(properties.getProperty(prefix+"scanTiltStepsX"));
if (properties.getProperty(prefix+"scanTiltStepsY")!=null) if (properties.getProperty(prefix+"scanTiltStepsY")!=null)
this.scanTiltStepsY=Integer.parseInt(properties.getProperty(prefix+"scanTiltStepsY")); this.scanTiltStepsY=Integer.parseInt(properties.getProperty(prefix+"scanTiltStepsY"));
if (properties.getProperty(prefix+"motorHysteresis")!=null) if (properties.getProperty(prefix+"motorHysteresis")!=null)
this.motorHysteresis=Integer.parseInt(properties.getProperty(prefix+"motorHysteresis")); this.motorHysteresis=Integer.parseInt(properties.getProperty(prefix+"motorHysteresis"));
if (properties.getProperty(prefix+"measuredHysteresis")!=null) if (properties.getProperty(prefix+"measuredHysteresis")!=null)
...@@ -1410,7 +1414,7 @@ public class LensAdjustment { ...@@ -1410,7 +1414,7 @@ public class LensAdjustment {
if (properties.getProperty(prefix+"lensDistanceMoveToGoal")!=null) if (properties.getProperty(prefix+"lensDistanceMoveToGoal")!=null)
this.lensDistanceMoveToGoal=Boolean.parseBoolean(properties.getProperty(prefix+"lensDistanceMoveToGoal")); this.lensDistanceMoveToGoal=Boolean.parseBoolean(properties.getProperty(prefix+"lensDistanceMoveToGoal"));
if (properties.getProperty(prefix+"powerControlEnable")!=null) if (properties.getProperty(prefix+"powerControlEnable")!=null)
this.powerControlEnable=Boolean.parseBoolean(properties.getProperty(prefix+"powerControlEnable")); this.powerControlEnable=Boolean.parseBoolean(properties.getProperty(prefix+"powerControlEnable"));
if (properties.getProperty(prefix+"powerControlMaximalTemperature")!=null) if (properties.getProperty(prefix+"powerControlMaximalTemperature")!=null)
...@@ -1421,7 +1425,7 @@ public class LensAdjustment { ...@@ -1421,7 +1425,7 @@ public class LensAdjustment {
this.powerControlNeitherOnMinutes=Double.parseDouble(properties.getProperty(prefix+"powerControlNeitherOnMinutes")); this.powerControlNeitherOnMinutes=Double.parseDouble(properties.getProperty(prefix+"powerControlNeitherOnMinutes"));
if (properties.getProperty(prefix+"powerControlFanOnMinutes")!=null) if (properties.getProperty(prefix+"powerControlFanOnMinutes")!=null)
this.powerControlFanOnMinutes=Double.parseDouble(properties.getProperty(prefix+"powerControlFanOnMinutes")); this.powerControlFanOnMinutes=Double.parseDouble(properties.getProperty(prefix+"powerControlFanOnMinutes"));
if (properties.getProperty(prefix+"uvLasersIP")!=null) if (properties.getProperty(prefix+"uvLasersIP")!=null)
this.uvLasersIP=properties.getProperty(prefix+"uvLasersIP"); this.uvLasersIP=properties.getProperty(prefix+"uvLasersIP");
if (properties.getProperty(prefix+"uvLasersBus")!=null) if (properties.getProperty(prefix+"uvLasersBus")!=null)
...@@ -1434,7 +1438,7 @@ public class LensAdjustment { ...@@ -1434,7 +1438,7 @@ public class LensAdjustment {
this.uvLasersCurrents[2]=Double.parseDouble(properties.getProperty(prefix+"uvLasersCurrents_2")); this.uvLasersCurrents[2]=Double.parseDouble(properties.getProperty(prefix+"uvLasersCurrents_2"));
if (properties.getProperty(prefix+"uvLasersCurrents_3")!=null) if (properties.getProperty(prefix+"uvLasersCurrents_3")!=null)
this.uvLasersCurrents[3]=Double.parseDouble(properties.getProperty(prefix+"uvLasersCurrents_3")); this.uvLasersCurrents[3]=Double.parseDouble(properties.getProperty(prefix+"uvLasersCurrents_3"));
if (properties.getProperty(prefix+"smallestSubPix")!=null) if (properties.getProperty(prefix+"smallestSubPix")!=null)
this.smallestSubPix=Double.parseDouble(properties.getProperty(prefix+"smallestSubPix")); this.smallestSubPix=Double.parseDouble(properties.getProperty(prefix+"smallestSubPix"));
if (properties.getProperty(prefix+"bitmapNonuniforityThreshold")!=null) if (properties.getProperty(prefix+"bitmapNonuniforityThreshold")!=null)
...@@ -1522,7 +1526,7 @@ public class LensAdjustment { ...@@ -1522,7 +1526,7 @@ public class LensAdjustment {
int manIndex= gd.getNextChoiceIndex(); int manIndex= gd.getNextChoiceIndex();
int manMod= (int) gd.getNextNumber(); int manMod= (int) gd.getNextNumber();
this.askLensSerial= gd.getNextBoolean(); this.askLensSerial= gd.getNextBoolean();
this.centerDeltaX= gd.getNextNumber(); this.centerDeltaX= gd.getNextNumber();
this.centerDeltaY= gd.getNextNumber(); this.centerDeltaY= gd.getNextNumber();
if (manMod<0) manMod=0; if (manMod<0) manMod=0;
else if (manMod>maxMod) manMod=maxMod; else if (manMod>maxMod) manMod=maxMod;
...@@ -1542,7 +1546,7 @@ public class LensAdjustment { ...@@ -1542,7 +1546,7 @@ public class LensAdjustment {
} }
} }
} }
// subset of showDialog() - only set parameters realated to scanning // subset of showDialog() - only set parameters realated to scanning
public boolean showScanningSetup(String title) { public boolean showScanningSetup(String title) {
GenericDialog gd = new GenericDialog(title); GenericDialog gd = new GenericDialog(title);
gd.addNumericField("Motor single movement (all 3 motors) in scan focus mode (signed value)", this.scanStep, 0,7,"motors steps"); gd.addNumericField("Motor single movement (all 3 motors) in scan focus mode (signed value)", this.scanStep, 0,7,"motors steps");
...@@ -1556,8 +1560,8 @@ public class LensAdjustment { ...@@ -1556,8 +1560,8 @@ public class LensAdjustment {
gd.addCheckbox ("Scan for tilt measurement in both directions", this.scanTiltReverse); gd.addCheckbox ("Scan for tilt measurement in both directions", this.scanTiltReverse);
gd.addCheckbox ("Calculate PSF after returning to the initial position", this.scanMeasureLast); gd.addCheckbox ("Calculate PSF after returning to the initial position", this.scanMeasureLast);
gd.addCheckbox ("Calculate model parameters after scanning", this.scanRunLMA); gd.addCheckbox ("Calculate model parameters after scanning", this.scanRunLMA);
gd.addNumericField("Full range of scanning motors tilting in X-direction", this.scanTiltRangeX, 0,7,"motors steps"); gd.addNumericField("Full range of scanning motors tilting in X-direction", this.scanTiltRangeX, 0,7,"motors steps");
gd.addNumericField("Full range of scanning motors tilting in Y-direction", this.scanTiltRangeY, 0,7,"motors steps"); gd.addNumericField("Full range of scanning motors tilting in Y-direction", this.scanTiltRangeY, 0,7,"motors steps");
gd.addNumericField("Number of stops measurements when tilting in X-deirection", this.scanTiltStepsX, 0); gd.addNumericField("Number of stops measurements when tilting in X-deirection", this.scanTiltStepsX, 0);
...@@ -1580,23 +1584,23 @@ public class LensAdjustment { ...@@ -1580,23 +1584,23 @@ public class LensAdjustment {
this.scanTiltReverse= gd.getNextBoolean(); this.scanTiltReverse= gd.getNextBoolean();
this.scanMeasureLast= gd.getNextBoolean(); this.scanMeasureLast= gd.getNextBoolean();
this.scanRunLMA= gd.getNextBoolean(); this.scanRunLMA= gd.getNextBoolean();
this.scanTiltRangeX= (int) gd.getNextNumber(); this.scanTiltRangeX= (int) gd.getNextNumber();
this.scanTiltRangeY= (int) gd.getNextNumber(); this.scanTiltRangeY= (int) gd.getNextNumber();
this.scanTiltStepsX= (int) gd.getNextNumber(); this.scanTiltStepsX= (int) gd.getNextNumber();
this.scanTiltStepsY= (int) gd.getNextNumber(); this.scanTiltStepsY= (int) gd.getNextNumber();
this.motorHysteresis= (int) gd.getNextNumber(); this.motorHysteresis= (int) gd.getNextNumber();
return true; return true;
} }
public boolean showDialog(String title) { public boolean showDialog(String title) {
GenericDialog gd = new GenericDialog(title); GenericDialog gd = new GenericDialog(title);
// this.serialNumber, // camera serial number string // this.serialNumber, // camera serial number string
gd.addMessage("Sensor board serial number is "+(((this.serialNumber==null)||(this.serialNumber==""))?"not specified":this.serialNumber)); gd.addMessage("Sensor board serial number is "+(((this.serialNumber==null)||(this.serialNumber==""))?"not specified":this.serialNumber));
gd.addStringField ("Comment to add to the result files", this.comment,80); gd.addStringField ("Comment to add to the result files", this.comment,80);
gd.addStringField ("Lens serial number",this.lensSerial); gd.addStringField ("Lens serial number",this.lensSerial);
int [] manufacturingIndexMod=getManufacturingIndexMod(this.manufacturingState); int [] manufacturingIndexMod=getManufacturingIndexMod(this.manufacturingState);
gd. addChoice("Manufacturing state", this.manufacturingStateNames, this.manufacturingStateNames[manufacturingIndexMod[0]]); gd. addChoice("Manufacturing state", this.manufacturingStateNames, this.manufacturingStateNames[manufacturingIndexMod[0]]);
int maxMod=9; int maxMod=9;
...@@ -1605,7 +1609,7 @@ public class LensAdjustment { ...@@ -1605,7 +1609,7 @@ public class LensAdjustment {
} }
gd.addNumericField("Optional manufacturing state modifier (0.."+maxMod+")", manufacturingIndexMod[1], 0,1,""); gd.addNumericField("Optional manufacturing state modifier (0.."+maxMod+")", manufacturingIndexMod[1], 0,1,"");
gd.addCheckbox ("Ask lens serial number on each camera power cycle",this.askLensSerial); gd.addCheckbox ("Ask lens serial number on each camera power cycle",this.askLensSerial);
gd.addCheckbox ("Add lens serial number to filenames",this.includeLensSerial); gd.addCheckbox ("Add lens serial number to filenames",this.includeLensSerial);
gd.addNumericField("Required X-shift between the lens axis and the sensor center", this.centerDeltaX, 0,4,"pix (180 for tilted)"); gd.addNumericField("Required X-shift between the lens axis and the sensor center", this.centerDeltaX, 0,4,"pix (180 for tilted)");
...@@ -1669,8 +1673,8 @@ public class LensAdjustment { ...@@ -1669,8 +1673,8 @@ public class LensAdjustment {
gd.addNumericField("Maximal allowed single-step focusing adjustment", this.maxStep, 1,7,"motors steps"); gd.addNumericField("Maximal allowed single-step focusing adjustment", this.maxStep, 1,7,"motors steps");
gd.addNumericField("How far to go to probe around the current point to measure derivatives", this.probeStep, 1,7,"motors steps"); gd.addNumericField("How far to go to probe around the current point to measure derivatives", this.probeStep, 1,7,"motors steps");
gd.addNumericField("How far too move average of the 3 motors: (M1+M2+M3)/3 during probing", this.probe_M1M2M3, 1,7,"motors steps"); gd.addNumericField("How far too move average of the 3 motors: (M1+M2+M3)/3 during probing", this.probe_M1M2M3, 1,7,"motors steps");
gd.addNumericField("How far to move M3 opposite to M1 and M2: M3-(M1+M2)/2 during probing", this.probe_M3_M1M2, 1,7,"motors steps"); gd.addNumericField("How far to move M3 opposite to M1 and M2: M3-(M1+M2)/2 during probing", this.probe_M3_M1M2, 1,7,"motors steps");
gd.addNumericField("How far to move M2 opposite to M1: M2-M1 during probing", this.probe_M2_M1, 1,7,"motors steps"); gd.addNumericField("How far to move M2 opposite to M1: M2-M1 during probing", this.probe_M2_M1, 1,7,"motors steps");
...@@ -1693,20 +1697,20 @@ public class LensAdjustment { ...@@ -1693,20 +1697,20 @@ public class LensAdjustment {
gd.addCheckbox ("Open dialog when calibrating focal distance", this.lensDistanceInteractive); gd.addCheckbox ("Open dialog when calibrating focal distance", this.lensDistanceInteractive);
gd.addCheckbox ("Show results window from focal distance calibration", this.lensDistanceShowResults); gd.addCheckbox ("Show results window from focal distance calibration", this.lensDistanceShowResults);
gd.addCheckbox ("Move motors together to the requested microns from the \"best focus\"", this.lensDistanceMoveToGoal); gd.addCheckbox ("Move motors together to the requested microns from the \"best focus\"", this.lensDistanceMoveToGoal);
gd.addCheckbox ("Enable power control for heater and fan", this.powerControlEnable); gd.addCheckbox ("Enable power control for heater and fan", this.powerControlEnable);
gd.addNumericField("Maximal allowed temperature", this.powerControlMaximalTemperature, 3,5,"C"); gd.addNumericField("Maximal allowed temperature", this.powerControlMaximalTemperature, 3,5,"C");
gd.addNumericField("Heater ON time", this.powerControlHeaterOnMinutes, 1,5,"min"); gd.addNumericField("Heater ON time", this.powerControlHeaterOnMinutes, 1,5,"min");
gd.addNumericField("Both heater and fan OFF time", this.powerControlNeitherOnMinutes, 1,5,"min"); gd.addNumericField("Both heater and fan OFF time", this.powerControlNeitherOnMinutes, 1,5,"min");
gd.addNumericField("Fan ON time", this.powerControlFanOnMinutes, 1,5,"min"); gd.addNumericField("Fan ON time", this.powerControlFanOnMinutes, 1,5,"min");
gd.addStringField ("IP address of the camera with 103641 board (UV LEDs and lasers) are attached", this.uvLasersIP,40); gd.addStringField ("IP address of the camera with 103641 board (UV LEDs and lasers) are attached", this.uvLasersIP,40);
gd.addNumericField("I2C bus where LED/laser board is attached (0 - through 10359, 1 - through 10369)",this.uvLasersBus, 0); gd.addNumericField("I2C bus where LED/laser board is attached (0 - through 10359, 1 - through 10369)",this.uvLasersBus, 0);
gd.addNumericField("UV LED1 \"on\" current (left/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA"); gd.addNumericField("UV LED1 \"on\" current (left/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addNumericField("UV LED2 \"on\" current (right/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA"); gd.addNumericField("UV LED2 \"on\" current (right/near when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addNumericField("UV LED3 \"on\" current (right/far when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA"); gd.addNumericField("UV LED3 \"on\" current (right/far when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addNumericField("UV LED4 \"on\" current (left/far when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA"); gd.addNumericField("UV LED4 \"on\" current (left/far when looking from the target)", this.uvLasersCurrents[0], 3,5,"mA");
gd.addMessage(""); gd.addMessage("");
gd.addNumericField("Minimal correction movement to initiate final series of corrections - focus/tilt mode", this.minCorr, 1,5,"motors steps"); gd.addNumericField("Minimal correction movement to initiate final series of corrections - focus/tilt mode", this.minCorr, 1,5,"motors steps");
gd.addNumericField("Finish if this number of last corrections where below minimum (previous input) - focus/tilt mode",this.numFinalCorr, 0); gd.addNumericField("Finish if this number of last corrections where below minimum (previous input) - focus/tilt mode",this.numFinalCorr, 0);
...@@ -1720,25 +1724,25 @@ public class LensAdjustment { ...@@ -1720,25 +1724,25 @@ public class LensAdjustment {
gd.addNumericField("Motor single movement (all 3 motors) in scan focus mode (signed value)", this.scanStep, 0,7,"motors steps"); gd.addNumericField("Motor single movement (all 3 motors) in scan focus mode (signed value)", this.scanStep, 0,7,"motors steps");
gd.addNumericField("Number of scan steps during (center) focus scanning", this.scanNumber, 0); gd.addNumericField("Number of scan steps during (center) focus scanning", this.scanNumber, 0);
gd.addNumericField("... of them - in the negative direction (closer lens to sensor)", this.scanNumberNegative, 0); gd.addNumericField("... of them - in the negative direction (closer lens to sensor)", this.scanNumberNegative, 0);
gd.addCheckbox ("Scan focus in 2 directions, after the calibration estimate hysteresis (play)", this.scanHysteresis); gd.addCheckbox ("Scan focus in 2 directions, after the calibration estimate hysteresis (play)", this.scanHysteresis);
gd.addNumericField("Number of scan steps during hysteresis (play) measurement", this.scanHysteresisNumber, 0); gd.addNumericField("Number of scan steps during hysteresis (play) measurement", this.scanHysteresisNumber, 0);
gd.addCheckbox ("Scan for tilt measurement (approximately preserving center)", this.scanTiltEnable); gd.addCheckbox ("Scan for tilt measurement (approximately preserving center)", this.scanTiltEnable);
gd.addCheckbox ("Scan for tilt measurement in both directions", this.scanTiltReverse); gd.addCheckbox ("Scan for tilt measurement in both directions", this.scanTiltReverse);
gd.addCheckbox ("Calculate PSF after returning to the initial position", this.scanMeasureLast); gd.addCheckbox ("Calculate PSF after returning to the initial position", this.scanMeasureLast);
gd.addNumericField("Full range of scanning motors tilting in X-direction", this.scanTiltRangeX, 0,7,"motors steps"); gd.addNumericField("Full range of scanning motors tilting in X-direction", this.scanTiltRangeX, 0,7,"motors steps");
gd.addNumericField("Full range of scanning motors tilting in Y-direction", this.scanTiltRangeY, 0,7,"motors steps"); gd.addNumericField("Full range of scanning motors tilting in Y-direction", this.scanTiltRangeY, 0,7,"motors steps");
gd.addNumericField("Number of stops measurements when tilting in X-deirection", this.scanTiltStepsX, 0); gd.addNumericField("Number of stops measurements when tilting in X-deirection", this.scanTiltStepsX, 0);
gd.addNumericField("Number of stops measurements when tilting in Y-deirection", this.scanTiltStepsY, 0); gd.addNumericField("Number of stops measurements when tilting in Y-deirection", this.scanTiltStepsY, 0);
gd.addMessage ("The following parameters overwrite some defined for aberration measurements in other dialogs"); gd.addMessage ("The following parameters overwrite some defined for aberration measurements in other dialogs");
gd.addNumericField("Smallest fraction to subdivide pixels at simulation", this.smallestSubPix, 3,5,"sensor pix"); gd.addNumericField("Smallest fraction to subdivide pixels at simulation", this.smallestSubPix, 3,5,"sensor pix");
gd.addNumericField("Maximal difference of the pattern value in the corners that triggers subdivision", this.bitmapNonuniforityThreshold, 3); gd.addNumericField("Maximal difference of the pattern value in the corners that triggers subdivision", this.bitmapNonuniforityThreshold, 3);
gd.addNumericField("Subdivide simulated pattern by:", this.subdiv, 0); gd.addNumericField("Subdivide simulated pattern by:", this.subdiv, 0);
gd.addNumericField("Allowed overexposed pixels (fraction of the area) ",this.overexposedMaxFraction,3); // 0.005; // allowed fraction of the overexposed pixels in the PSF kernel measurement area gd.addNumericField("Allowed overexposed pixels (fraction of the area) ",this.overexposedMaxFraction,3); // 0.005; // allowed fraction of the overexposed pixels in the PSF kernel measurement area
gd.addNumericField("Min fraction of the FFT square (weighted) to have defined pattern", this.minDefinedArea, 3); gd.addNumericField("Min fraction of the FFT square (weighted) to have defined pattern", this.minDefinedArea, 3);
gd.addNumericField ("PSF kernel size", this.PSFKernelSize, 0); gd.addNumericField ("PSF kernel size", this.PSFKernelSize, 0);
gd.addCheckbox ("Approximate pattern grid with a polynomial",this.approximateGrid); // true; // ignore lateral chromatic aberration (center OTF to 0,0) gd.addCheckbox ("Approximate pattern grid with a polynomial",this.approximateGrid); // true; // ignore lateral chromatic aberration (center OTF to 0,0)
...@@ -1764,24 +1768,24 @@ public class LensAdjustment { ...@@ -1764,24 +1768,24 @@ public class LensAdjustment {
for (int i=0;i<this.postUVscrewSensitivity.length;i++){ for (int i=0;i<this.postUVscrewSensitivity.length;i++){
gd.addNumericField("Screw "+i+" sensitivity", this.postUVscrewSensitivity[i], 4,6,"um/turn CW"); gd.addNumericField("Screw "+i+" sensitivity", this.postUVscrewSensitivity[i], 4,6,"um/turn CW");
} }
gd.addMessage("-----"); gd.addMessage("-----");
gd.addNumericField("Report focal length at this temperature", this.reportTemperature, 1,5,"C"); gd.addNumericField("Report focal length at this temperature", this.reportTemperature, 1,5,"C");
gd.addCheckbox ("Show legacy focusing parameters (most are already not supported anyway)", this.showLegacy); gd.addCheckbox ("Show legacy focusing parameters (most are already not supported anyway)", this.showLegacy);
if (!Double.isNaN(this.sensorTemperature)) gd.addMessage("Last measured sensor temperature is "+this.sensorTemperature+" C"); if (!Double.isNaN(this.sensorTemperature)) gd.addMessage("Last measured sensor temperature is "+this.sensorTemperature+" C");
if (!Double.isNaN(this.result_lastKT)) gd.addMessage("Temperature focal distance coefficient measured in last run is "+this.result_lastKT+"microns/C"); if (!Double.isNaN(this.result_lastKT)) gd.addMessage("Temperature focal distance coefficient measured in last run is "+this.result_lastKT+"microns/C");
if (!Double.isNaN(this.result_lastFD20)) gd.addMessage("Focal distance @20C measured at last run is "+this.result_lastFD20+" microns"); if (!Double.isNaN(this.result_lastFD20)) gd.addMessage("Focal distance @20C measured at last run is "+this.result_lastFD20+" microns");
if (!Double.isNaN(this.result_lastKT) && !Double.isNaN(this.result_lastFD20)){ if (!Double.isNaN(this.result_lastKT) && !Double.isNaN(this.result_lastFD20)){
gd.addMessage("Focal distance @"+this.reportTemperature+"C measured at last run is "+ gd.addMessage("Focal distance @"+this.reportTemperature+"C measured at last run is "+
(this.result_lastFD20+(this.reportTemperature-20.0)*this.result_lastKT)+" microns"); (this.result_lastFD20+(this.reportTemperature-20.0)*this.result_lastKT)+" microns");
} }
if (!Double.isNaN(this.result_allHistoryKT)) gd.addMessage("Temperature focal distance coefficient calculated from all measurements is "+this.result_allHistoryKT+" microns"); if (!Double.isNaN(this.result_allHistoryKT)) gd.addMessage("Temperature focal distance coefficient calculated from all measurements is "+this.result_allHistoryKT+" microns");
if (!Double.isNaN(this.result_allHistoryFD20)) gd.addMessage("Focal distance @20C calculated from all measurements is "+this.result_allHistoryFD20+" microns"); if (!Double.isNaN(this.result_allHistoryFD20)) gd.addMessage("Focal distance @20C calculated from all measurements is "+this.result_allHistoryFD20+" microns");
if (!Double.isNaN(this.result_allHistoryKT) && !Double.isNaN(this.result_allHistoryFD20)){ if (!Double.isNaN(this.result_allHistoryKT) && !Double.isNaN(this.result_allHistoryFD20)){
gd.addMessage("Focal distance @"+this.reportTemperature+"C calculated from all measurements is "+ gd.addMessage("Focal distance @"+this.reportTemperature+"C calculated from all measurements is "+
(this.result_allHistoryFD20+(this.reportTemperature-20.0)*this.result_allHistoryKT)+" microns"); (this.result_allHistoryFD20+(this.reportTemperature-20.0)*this.result_allHistoryKT)+" microns");
} }
if (!Double.isNaN(this.result_fDistance)) gd.addMessage("Focal distance is "+this.result_fDistance+" microns"); if (!Double.isNaN(this.result_fDistance)) gd.addMessage("Focal distance is "+this.result_fDistance+" microns");
if (!Double.isNaN(this.result_tiltX)) gd.addMessage("Horizontal angular/tangential asymmetry "+this.result_tiltX); if (!Double.isNaN(this.result_tiltX)) gd.addMessage("Horizontal angular/tangential asymmetry "+this.result_tiltX);
...@@ -1790,7 +1794,7 @@ public class LensAdjustment { ...@@ -1790,7 +1794,7 @@ public class LensAdjustment {
if (!Double.isNaN(this.result_A50)) gd.addMessage("Same, but with averaged r^2: "+this.result_A50+" C"); if (!Double.isNaN(this.result_A50)) gd.addMessage("Same, but with averaged r^2: "+this.result_A50+" C");
if (!Double.isNaN(this.result_B50)) gd.addMessage("Same, but with averaged r^4: "+this.result_B50+" C"); if (!Double.isNaN(this.result_B50)) gd.addMessage("Same, but with averaged r^4: "+this.result_B50+" C");
if (!Double.isNaN(this.result_RC50)) gd.addMessage("Average PSF 50% radius for center samples "+this.result_RC50+" pixels"); if (!Double.isNaN(this.result_RC50)) gd.addMessage("Average PSF 50% radius for center samples "+this.result_RC50+" pixels");
if (!Double.isNaN(this.result_PX0)) gd.addMessage("Lens center X-coordinate on the sensor "+this.result_PX0+" pixels"); if (!Double.isNaN(this.result_PX0)) gd.addMessage("Lens center X-coordinate on the sensor "+this.result_PX0+" pixels");
if (!Double.isNaN(this.result_PY0)) gd.addMessage("Lens center Y-coordinate on the sensor "+this.result_PY0+" pixels"); if (!Double.isNaN(this.result_PY0)) gd.addMessage("Lens center Y-coordinate on the sensor "+this.result_PY0+" pixels");
if (!Double.isNaN(this.result_PSI)) gd.addMessage("SFE rotation relative to target (clockwise - positive) "+this.result_PSI+" degrees"); if (!Double.isNaN(this.result_PSI)) gd.addMessage("SFE rotation relative to target (clockwise - positive) "+this.result_PSI+" degrees");
...@@ -1798,7 +1802,7 @@ public class LensAdjustment { ...@@ -1798,7 +1802,7 @@ public class LensAdjustment {
if (!Double.isNaN(this.result_FocalLength)) gd.addMessage("Lens focal length "+this.result_FocalLength+" mm"); if (!Double.isNaN(this.result_FocalLength)) gd.addMessage("Lens focal length "+this.result_FocalLength+" mm");
gd.addMessage("Cumulative currents that ran through UV LEDs:"); gd.addMessage("Cumulative currents that ran through UV LEDs:");
for (int i=0;i<this.ampsSeconds.length;i++) gd.addMessage("UV LED "+(i+1)+":"+IJ.d2s(this.ampsSeconds[i],3)+" coulombs (amp-seconds)"); for (int i=0;i<this.ampsSeconds.length;i++) gd.addMessage("UV LED "+(i+1)+":"+IJ.d2s(this.ampsSeconds[i],3)+" coulombs (amp-seconds)");
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
...@@ -1807,17 +1811,17 @@ public class LensAdjustment { ...@@ -1807,17 +1811,17 @@ public class LensAdjustment {
if (this.lensSerial.length()>0){ if (this.lensSerial.length()>0){
while (this.lensSerial.length()<lensSerialLength) this.lensSerial="0"+this.lensSerial; while (this.lensSerial.length()<lensSerialLength) this.lensSerial="0"+this.lensSerial;
} }
int manIndex= gd.getNextChoiceIndex(); int manIndex= gd.getNextChoiceIndex();
int manMod= (int) gd.getNextNumber(); int manMod= (int) gd.getNextNumber();
if (manMod<0) manMod=0; if (manMod<0) manMod=0;
else if (manMod>maxMod) manMod=maxMod; else if (manMod>maxMod) manMod=maxMod;
this.manufacturingState=this.manufacturingStateValues[manIndex]+manMod; // here no restriction on the order - can go backwards this.manufacturingState=this.manufacturingStateValues[manIndex]+manMod; // here no restriction on the order - can go backwards
this.askLensSerial= gd.getNextBoolean(); this.askLensSerial= gd.getNextBoolean();
this.includeLensSerial= gd.getNextBoolean(); this.includeLensSerial= gd.getNextBoolean();
this.centerDeltaX= gd.getNextNumber(); this.centerDeltaX= gd.getNextNumber();
this.centerDeltaY= gd.getNextNumber(); this.centerDeltaY= gd.getNextNumber();
this.gridGeometryFile= gd.getNextString(); this.gridGeometryFile= gd.getNextString();
...@@ -1861,7 +1865,7 @@ public class LensAdjustment { ...@@ -1861,7 +1865,7 @@ public class LensAdjustment {
this.weightRatioRedToGreen= gd.getNextNumber(); this.weightRatioRedToGreen= gd.getNextNumber();
this.weightRatioBlueToGreen= gd.getNextNumber(); this.weightRatioBlueToGreen= gd.getNextNumber();
this.targetFarNear= gd.getNextNumber(); this.targetFarNear= gd.getNextNumber();
this.useRadialTangential= gd.getNextBoolean(); this.useRadialTangential= gd.getNextBoolean();
this.targetMicrons= gd.getNextNumber(); this.targetMicrons= gd.getNextNumber();
this.toleranceMicrons= gd.getNextNumber(); this.toleranceMicrons= gd.getNextNumber();
this.toleranceTilt= gd.getNextNumber(); this.toleranceTilt= gd.getNextNumber();
...@@ -1869,9 +1873,9 @@ public class LensAdjustment { ...@@ -1869,9 +1873,9 @@ public class LensAdjustment {
this.parallelAdjustThreshold= gd.getNextNumber(); this.parallelAdjustThreshold= gd.getNextNumber();
this.motorsSigma= gd.getNextNumber(); this.motorsSigma= gd.getNextNumber();
this.motorsSigma3= gd.getNextNumber(); this.motorsSigma3= gd.getNextNumber();
this.motorsMinSigma= gd.getNextNumber(); this.motorsMinSigma= gd.getNextNumber();
this.motorsVarSigmaToTravel= gd.getNextNumber(); this.motorsVarSigmaToTravel= gd.getNextNumber();
this.motorsFadeSigma= gd.getNextNumber(); this.motorsFadeSigma= gd.getNextNumber();
this.motorsOverShootToBalance= gd.getNextNumber(); this.motorsOverShootToBalance= gd.getNextNumber();
this.filterGoodDistance= gd.getNextBoolean(); this.filterGoodDistance= gd.getNextBoolean();
this.goodDistanceSigma= gd.getNextNumber(); this.goodDistanceSigma= gd.getNextNumber();
...@@ -1881,8 +1885,8 @@ public class LensAdjustment { ...@@ -1881,8 +1885,8 @@ public class LensAdjustment {
this.probe_M1M2M3= gd.getNextNumber(); this.probe_M1M2M3= gd.getNextNumber();
this.probe_M3_M1M2= gd.getNextNumber(); this.probe_M3_M1M2= gd.getNextNumber();
this.probe_M2_M1= gd.getNextNumber(); this.probe_M2_M1= gd.getNextNumber();
this.sigmaToProbe= gd.getNextNumber(); this.sigmaToProbe= gd.getNextNumber();
this.useTheBest= gd.getNextBoolean(); this.useTheBest= gd.getNextBoolean();
this.probeSymmetrical= gd.getNextBoolean(); this.probeSymmetrical= gd.getNextBoolean();
this.parallelBeforeProbing= gd.getNextBoolean(); this.parallelBeforeProbing= gd.getNextBoolean();
this.reProbeDistance= gd.getNextNumber(); this.reProbeDistance= gd.getNextNumber();
...@@ -1905,14 +1909,14 @@ public class LensAdjustment { ...@@ -1905,14 +1909,14 @@ public class LensAdjustment {
this.powerControlHeaterOnMinutes= gd.getNextNumber(); this.powerControlHeaterOnMinutes= gd.getNextNumber();
this.powerControlNeitherOnMinutes= gd.getNextNumber(); this.powerControlNeitherOnMinutes= gd.getNextNumber();
this.powerControlFanOnMinutes= gd.getNextNumber(); this.powerControlFanOnMinutes= gd.getNextNumber();
this.uvLasersIP= gd.getNextString(); this.uvLasersIP= gd.getNextString();
this.uvLasersBus= (int) gd.getNextNumber(); this.uvLasersBus= (int) gd.getNextNumber();
this.uvLasersCurrents[0]= gd.getNextNumber(); this.uvLasersCurrents[0]= gd.getNextNumber();
this.uvLasersCurrents[1]= gd.getNextNumber(); this.uvLasersCurrents[1]= gd.getNextNumber();
this.uvLasersCurrents[2]= gd.getNextNumber(); this.uvLasersCurrents[2]= gd.getNextNumber();
this.uvLasersCurrents[3]= gd.getNextNumber(); this.uvLasersCurrents[3]= gd.getNextNumber();
this.minCorr= gd.getNextNumber(); this.minCorr= gd.getNextNumber();
this.numFinalCorr= (int) gd.getNextNumber(); this.numFinalCorr= (int) gd.getNextNumber();
this.minCorrPre= gd.getNextNumber(); this.minCorrPre= gd.getNextNumber();
...@@ -1927,7 +1931,7 @@ public class LensAdjustment { ...@@ -1927,7 +1931,7 @@ public class LensAdjustment {
this.scanNumberNegative= (int) gd.getNextNumber(); this.scanNumberNegative= (int) gd.getNextNumber();
this.scanHysteresis= gd.getNextBoolean(); this.scanHysteresis= gd.getNextBoolean();
this.scanHysteresisNumber= (int) gd.getNextNumber(); this.scanHysteresisNumber= (int) gd.getNextNumber();
this.scanTiltEnable= gd.getNextBoolean(); this.scanTiltEnable= gd.getNextBoolean();
this.scanTiltReverse= gd.getNextBoolean(); this.scanTiltReverse= gd.getNextBoolean();
this.scanMeasureLast= gd.getNextBoolean(); this.scanMeasureLast= gd.getNextBoolean();
...@@ -1935,12 +1939,12 @@ public class LensAdjustment { ...@@ -1935,12 +1939,12 @@ public class LensAdjustment {
this.scanTiltRangeY= (int) gd.getNextNumber(); this.scanTiltRangeY= (int) gd.getNextNumber();
this.scanTiltStepsX= (int) gd.getNextNumber(); this.scanTiltStepsX= (int) gd.getNextNumber();
this.scanTiltStepsY= (int) gd.getNextNumber(); this.scanTiltStepsY= (int) gd.getNextNumber();
this.smallestSubPix= gd.getNextNumber(); this.smallestSubPix= gd.getNextNumber();
this.bitmapNonuniforityThreshold=gd.getNextNumber(); this.bitmapNonuniforityThreshold=gd.getNextNumber();
this.subdiv= (int) gd.getNextNumber(); this.subdiv= (int) gd.getNextNumber();
this.overexposedMaxFraction= gd.getNextNumber(); this.overexposedMaxFraction= gd.getNextNumber();
this.minDefinedArea= gd.getNextNumber(); this.minDefinedArea= gd.getNextNumber();
this.PSFKernelSize= (int) gd.getNextNumber(); this.PSFKernelSize= (int) gd.getNextNumber();
this.approximateGrid= gd.getNextBoolean(); this.approximateGrid= gd.getNextBoolean();
...@@ -1969,13 +1973,13 @@ public class LensAdjustment { ...@@ -1969,13 +1973,13 @@ public class LensAdjustment {
return true; return true;
} }
/* ======================================================================== */ /* ======================================================================== */
//returns triads - x,y,distance from the lens center //returns triads - x,y,distance from the lens center
public double [][][] sampleCoordinates( public double [][][] sampleCoordinates(
double x0, // lens center on the sensor double x0, // lens center on the sensor
double y0){ // lens center on the sensor double y0){ // lens center on the sensor
int ix0=(int) Math.round(x0); int ix0=(int) Math.round(x0);
int iy0=(int) Math.round(y0); int iy0=(int) Math.round(y0);
// Rectangle woi=new Rectangle(this.margins); // Rectangle woi=new Rectangle(this.margins);
Rectangle woi=this.getMargins(); Rectangle woi=this.getMargins();
// System.out.println("Selection Rectangle("+woi.x+", "+woi.y+", "+woi.width+", "+woi.height+ ")"); // System.out.println("Selection Rectangle("+woi.x+", "+woi.y+", "+woi.width+", "+woi.height+ ")");
...@@ -2007,7 +2011,7 @@ public class LensAdjustment { ...@@ -2007,7 +2011,7 @@ public class LensAdjustment {
woi.width-=this.sampleSize; woi.width-=this.sampleSize;
woi.height-=this.sampleSize; woi.height-=this.sampleSize;
// System.out.println("Selection - sample centers: Rectangle("+woi.x+", "+woi.y+", "+woi.width+", "+woi.height+ ")"); // System.out.println("Selection - sample centers: Rectangle("+woi.x+", "+woi.y+", "+woi.width+", "+woi.height+ ")");
double [][][] sampleCoord=new double[this.numSamples[1]][this.numSamples[0]][3]; double [][][] sampleCoord=new double[this.numSamples[1]][this.numSamples[0]][3];
int y,x; int y,x;
for (int i=0;i<this.numSamples[1];i++){ for (int i=0;i<this.numSamples[1];i++){
...@@ -2027,7 +2031,7 @@ public class LensAdjustment { ...@@ -2027,7 +2031,7 @@ public class LensAdjustment {
sampleCoord[i][j][2]=Math.sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0)); // distance from tyhe center sampleCoord[i][j][2]=Math.sqrt((x-x0)*(x-x0)+(y-y0)*(y-y0)); // distance from tyhe center
} }
} }
/* /*
for (int i=0;i<this.numSamples[1];i++){ for (int i=0;i<this.numSamples[1];i++){
for (int j=0;j<this.numSamples[0];j++){ for (int j=0;j<this.numSamples[0];j++){
System.out.println ("i="+i+" j="+j+" sampleCoord[i][j][0]="+sampleCoord[i][j][0]+" sampleCoord[i][j][1]="+sampleCoord[i][j][1]); System.out.println ("i="+i+" j="+j+" sampleCoord[i][j][0]="+sampleCoord[i][j][0]+" sampleCoord[i][j][1]="+sampleCoord[i][j][1]);
...@@ -2079,12 +2083,12 @@ public class LensAdjustment { ...@@ -2079,12 +2083,12 @@ public class LensAdjustment {
// System.out.println(s); // System.out.println(s);
// System.out.println(sb.toString()); // System.out.println(sb.toString());
return sb.toString(); return sb.toString();
} }
} }
} }
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -124,15 +124,7 @@ public class DoubleFHT { ...@@ -124,15 +124,7 @@ public class DoubleFHT {
public boolean transform(double [] data, boolean inverse) { public boolean transform(double [] data, boolean inverse) {
//IJ.log("transform: "+maxN+" "+inverse); //IJ.log("transform: "+maxN+" "+inverse);
updateMaxN(data); updateMaxN(data);
// maxN = (int) Math.sqrt(data.length);
// if ((S==null) || (S.length!=(maxN/4))) {
// makeSinCosTables(maxN);
// makeBitReverseTable(maxN);
// tempArr = new double[maxN];
// }
// float[] fht = (float[])getPixels();
rc2DFHT(data, inverse, this.maxN); rc2DFHT(data, inverse, this.maxN);
// isFrequencyDomain = !inverse;
return true; return true;
} }
...@@ -141,21 +133,15 @@ public class DoubleFHT { ...@@ -141,21 +133,15 @@ public class DoubleFHT {
double lowPass){ double lowPass){
return createFrequencyFilter(null,highPass,lowPass); return createFrequencyFilter(null,highPass,lowPass);
} }
/* public double []createFrequencyFilter(
double [] data, public double [] createFrequencyFilter(
double highPass,
double lowPass){
return createFrequencyFilter(data.length,highPass,lowPass);
}
*/
public double [] createFrequencyFilter(
double [] data, //int n, double [] data, //int n,
double highPass, double highPass,
double lowPass){ double lowPass){
if (data !=null) updateMaxN(data); if (data !=null) updateMaxN(data);
// int n; // int n;
if ((this.freqMask!=null) && (this.freqPass[0]==highPass) && (this.freqPass[0]==lowPass)) return this.freqMask; if ((this.freqMask!=null) && (this.freqPass[0]==highPass) && (this.freqPass[1]==lowPass)) return this.freqMask;
this.freqMask= new double [(this.maxN+1)*this.maxN/2+1]; this.freqMask= new double [(this.maxN+1)*this.maxN/2+1];
double [] lo=new double[this.maxN]; double [] lo=new double[this.maxN];
double [] hi=new double[this.maxN]; double [] hi=new double[this.maxN];
...@@ -177,12 +163,9 @@ public class DoubleFHT { ...@@ -177,12 +163,9 @@ public class DoubleFHT {
if (j>this.maxN/2) j=this.maxN-j; if (j>this.maxN/2) j=this.maxN-j;
this.freqMask[index]=(1.0-hi[i]*hi[j])*lo[i]*lo[j]; this.freqMask[index]=(1.0-hi[i]*hi[j])*lo[i]*lo[j];
} }
// this.freqMaskN=n;
this.freqPass=new double[2]; this.freqPass=new double[2];
this.freqPass[0]=highPass; this.freqPass[0]=highPass;
this.freqPass[1]=lowPass; this.freqPass[1]=lowPass;
// this.freqMask_cache[this.ln2]=this.freqMask;
// this.freqPass_cache[this.ln2]=this.freqPass;
return this.freqMask; return this.freqMask;
} }
/** /**
...@@ -195,49 +178,6 @@ public class DoubleFHT { ...@@ -195,49 +178,6 @@ public class DoubleFHT {
*/ */
public double [] shift(double [] data, double dx, double dy){ public double [] shift(double [] data, double dx, double dy){
return shift(data, 1, dx, dy); return shift(data, 1, dx, dy);
/*
updateMaxN(data);
double sX=2*Math.PI*dx/this.maxN;
double sY=2*Math.PI*dy/this.maxN;
int halfN=this.maxN/2;
double [] cosDX = new double[this.maxN];
double [] sinDX = new double[this.maxN];
double [] cosDY = new double[halfN+1];
double [] sinDY = new double[halfN+1];
for (int i=0;i<=halfN;i++){ // need less?
cosDX[i]=Math.cos(sX*i);
sinDX[i]=Math.sin(sX*i);
cosDY[i]=Math.cos(sY*i);
sinDY[i]=Math.sin(sY*i);
}
for (int i=1;i<halfN;i++){ // need less?
cosDX[this.maxN-i]= cosDX[i];
sinDX[this.maxN-i]=-sinDX[i];
}
swapQuadrants(data);
if (!transform(data,false)) return null; // direct FHT
for (int row =0; row<=halfN; row++) {
int rowMod = (this.maxN - row) % this.maxN;
int maxCol=(row<halfN)?(this.maxN-1):halfN;
for (int col=0; col<=maxCol; col++) {
int colMod = (this.maxN - col) % this.maxN;
int index= row * this.maxN + col;
int indexMod=rowMod * this.maxN + colMod;
double re=0.5*(data[index]+data[indexMod]);
double im=0.5*(data[index]-data[indexMod]);
if ((col==halfN) || (row==halfN)) im=0;
double cosDelta= cosDX[col]*cosDY[row] - sinDX[col]*sinDY[row]; // cos(deltaX)*cos(deltaY)-sin(deltaX)*sin(deltaY)
double sinDelta= sinDX[col]*cosDY[row] + cosDX[col]*sinDY[row]; // sin(deltaX)*cos(deltaY)+cos(deltaX)*sin(deltaY)
double reMod=re*cosDelta-im*sinDelta;
double imMod=re*sinDelta+im*cosDelta;
data[index]= reMod+imMod;
data[indexMod]=reMod-imMod;
}
}
if (!transform(data,true)) return null; // inverse FHT
swapQuadrants(data);
return data;
*/
} }
/** /**
* Upsample input array by padding in the frequency domain * Upsample input array by padding in the frequency domain
...@@ -247,30 +187,6 @@ public class DoubleFHT { ...@@ -247,30 +187,6 @@ public class DoubleFHT {
*/ */
public double [] upsample( double [] first, int scale){ public double [] upsample( double [] first, int scale){
return shift (first, scale, 0.0, 0.0); return shift (first, scale, 0.0, 0.0);
/*
if (scale <=1) return first.clone();
updateMaxN(first);
swapQuadrants(first);
if (!transform(first,false)) return null; // direct FHT
int halfN=this.maxN/2;
int shift=this.maxN*(scale-1);
int scaledN=this.maxN*scale;
double [] result =new double [first.length*scale*scale];
for (int i=0;i<result.length;i++) result [i]=0.0;
double scale2=scale*scale;
for (int i=0;i<first.length;i++){
int iy=i/this.maxN;
int ix=i%this.maxN;
if (ix>halfN) ix+=shift;
if (iy>halfN) iy+=shift;
result[scaledN*iy+ix]=scale2*first[i];
}
updateMaxN(result);
if (!transform(result,true)) return null; // inverse FHT
swapQuadrants(result);
return result;
*/
} }
/** /**
...@@ -408,6 +324,54 @@ public class DoubleFHT { ...@@ -408,6 +324,54 @@ public class DoubleFHT {
swapQuadrants(first); swapQuadrants(first);
return first; return first;
} }
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double high_pass,
double low_pass) { // high/low pass filtering
return phaseCorrelate(first, phaseCoeff, high_pass, low_pass, null);
}
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double high_pass,
double low_pass, // high/low pass filtering
double [] fht_save){ //null-OK
updateMaxN(first);
double [] filter = null;
if ((high_pass >0) || (low_pass > 0)) {
filter = createFrequencyFilter(high_pass, low_pass);
}
return phaseCorrelate(first, phaseCoeff, filter,fht_save);
}
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double [] filter) { // high/low pass filtering
return phaseCorrelate(first, phaseCoeff, filter, null);
}
public double [] phaseCorrelate (
double [] first,
double phaseCoeff,
double [] filter, // high/low pass filtering
double [] fht_save){ //null-OK
updateMaxN(first);
swapQuadrants(first);
if (!transform(first,false)) return null; // direct FHT
if (fht_save != null) {
System.arraycopy(first, 0, fht_save, 0, first.length);
}
first= phaseMultiplyNorm(first, first, phaseCoeff); // correlation, not convolution
if (filter!=null) multiplyByReal(first, filter);
transform(first,true) ; // inverse transform
swapQuadrants(first);
return first;
}
//
public double [] applyFreqFilter( public double [] applyFreqFilter(
double [] first, double [] first,
double [] filter double [] filter
...@@ -2024,6 +1988,7 @@ public class DoubleFHT { ...@@ -2024,6 +1988,7 @@ public class DoubleFHT {
return product; return product;
} }
public double [] phaseMultiply(double [] h1, double [] h2, double phaseCoeff) { public double [] phaseMultiply(double [] h1, double [] h2, double phaseCoeff) {
int rowMod, colMod; int rowMod, colMod;
double h2e, h2o,d; double h2e, h2o,d;
...@@ -2041,6 +2006,54 @@ public class DoubleFHT { ...@@ -2041,6 +2006,54 @@ public class DoubleFHT {
return product; return product;
} }
public double [] phaseMultiplyNorm(double [] h1, double [] h2, double phaseCoeff) {
int size = maxN;
int size2 = size >> 1;
int size21 = size*size2;
int rowMod, colMod, base, baseMod;
double h2e, h2o;
double[] product = new double[size*size];
for (int r =0; r<size; r++) {
rowMod = (size - r) % size;
for (int c=0; c<size; c++) {
colMod = (size - c) % size;
h2e = (h2[r * size + c] + h2[rowMod * size + colMod]) / 2;
h2o = (h2[r * size + c] - h2[rowMod * size + colMod]) / 2;
product[r * size + c] = (h1[r * size + c] * h2e - h1[rowMod * size + colMod] * h2o);
}
}
double [] amplitude = calculateAmplitudeHalf(product);
double avg_ampl = 0.0;
for (int row = 1; row < size2; row++) {
base = row*size;
for (int col = 0; col < size; col++) {
avg_ampl += amplitude[col+base];
}
}
avg_ampl *= 2;
for (int col = 0; col < size; col++) {
avg_ampl += amplitude[col] + amplitude[col + size21];
}
avg_ampl /= size*size;
double aoffs = (1.0 - phaseCoeff) * avg_ampl;
double ampl;
for (int row = 0; row <= size2; row++) {
base = row*size;
rowMod = (size - row) % size;
baseMod = rowMod * size;
for (int col = 0; col < size; col++) {
ampl = phaseCoeff * amplitude[col+base] + aoffs;
product[col+base] /= ampl;
if ((row > 0) && (row < size2)) {
colMod = (size - col) % size;
product[colMod + baseMod] /= ampl;
}
}
}
return product;
}
// Multiply by real array (i.e. filtering in frequency domain). Array m length should be at least maxN*maxN/2+1 // Multiply by real array (i.e. filtering in frequency domain). Array m length should be at least maxN*maxN/2+1
public void multiplyByReal(double [] h, double [] m) { public void multiplyByReal(double [] h, double [] m) {
...@@ -2094,6 +2107,17 @@ public class DoubleFHT { ...@@ -2094,6 +2107,17 @@ public class DoubleFHT {
swapQuadrants(amp); swapQuadrants(amp);
return amp; return amp;
} }
public double [] calculateAmplitudeHalf(double [] fht) {
int size=(int) Math.sqrt(fht.length);
int size2 = (size >>1) +1;
double[] amp = new double[size* size2];
for (int row=0; row<size2; row++) {
amplitude(row, size, fht, amp);
}
return amp;
}
public double [] calculateAmplitude2(double [] fht) { public double [] calculateAmplitude2(double [] fht) {
int size=(int) Math.sqrt(fht.length); int size=(int) Math.sqrt(fht.length);
double[] amp = new double[size*size]; double[] amp = new double[size*size];
...@@ -2133,8 +2157,6 @@ public class DoubleFHT { ...@@ -2133,8 +2157,6 @@ public class DoubleFHT {
row2=(fftsize-row1) %fftsize; row2=(fftsize-row1) %fftsize;
for (col1=0;col1<fftsize;col1++) { for (col1=0;col1<fftsize;col1++) {
col2=(fftsize-col1) %fftsize; col2=(fftsize-col1) %fftsize;
// fftHalf[row1][col1]= complex( 0.5*(fht_pixels[row1*fftsize+col1] + fht_pixels[row2*fftsize+col2]),
// 0.5*(fht_pixels[row2*fftsize+col2] - fht_pixels[row1*fftsize+col1]));
fftHalf[row1][col1][0]= 0.5*(fht_pixels[row1*fftsize+col1] + fht_pixels[row2*fftsize+col2]); fftHalf[row1][col1][0]= 0.5*(fht_pixels[row1*fftsize+col1] + fht_pixels[row2*fftsize+col2]);
fftHalf[row1][col1][1]= 0.5*(fht_pixels[row2*fftsize+col2] - fht_pixels[row1*fftsize+col1]); fftHalf[row1][col1][1]= 0.5*(fht_pixels[row2*fftsize+col2] - fht_pixels[row1*fftsize+col1]);
} }
......
...@@ -112,6 +112,30 @@ import ij.process.ImageProcessor; ...@@ -112,6 +112,30 @@ import ij.process.ImageProcessor;
return; return;
} else showArrays(pixels, width, height, titles); } else showArrays(pixels, width, height, titles);
} }
public void showComplex(double[][][] cpixels, String title) {
int height = cpixels.length;
int width = cpixels[0].length;
double [][]pixels = new double [height*width][];
int indx = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixels[indx++] = cpixels[y][x];
}
}
showComplex(pixels, width, title);
}
public void showComplex(double[][] cpixels, int width, String title) {
int height = cpixels.length/width;
double [][]pixels = new double [2][cpixels.length];
for (int i = 0; i< cpixels.length; i++) {
pixels[0][i]= cpixels[i][0];
pixels[1][i]= cpixels[i][1];
}
String [] titles = {"Re", "Im"};
showArrays(pixels, width, height, true, title, titles);
}
public void showArrays(float[][] pixels, int width, int height, boolean asStack, String title, String [] titles) { public void showArrays(float[][] pixels, int width, int height, boolean asStack, String title, String [] titles) {
int i,j; int i,j;
......
...@@ -1407,7 +1407,12 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970 ...@@ -1407,7 +1407,12 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*"); NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) { for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName(); String name= allNodes.item(i).getNodeName();
String value=allNodes.item(i).getFirstChild().getNodeValue(); String value="";
try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch(Exception e) {
}
imp.setProperty(name, value); imp.setProperty(name, value);
} }
......
...@@ -26,10 +26,14 @@ ...@@ -26,10 +26,14 @@
*/ */
package com.elphel.imagej.lwir; package com.elphel.imagej.lwir;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Properties; import java.util.Properties;
import com.elphel.imagej.common.GenericJTabbedDialog; import com.elphel.imagej.common.GenericJTabbedDialog;
import ij.Prefs;
public class LwirReaderParameters { public class LwirReaderParameters {
private boolean parameters_updated = false; private boolean parameters_updated = false;
protected int avg_number = 4; // number of measurements to average protected int avg_number = 4; // number of measurements to average
...@@ -49,6 +53,7 @@ public class LwirReaderParameters { ...@@ -49,6 +53,7 @@ public class LwirReaderParameters {
protected double vnir_gain_g = 2.0; protected double vnir_gain_g = 2.0;
protected double vnir_gain_rg = 0.7705; // 1.116; halogen/fluorescent protected double vnir_gain_rg = 0.7705; // 1.116; halogen/fluorescent
protected double vnir_gain_bg = 2.401; // 1.476; protected double vnir_gain_bg = 2.401; // 1.476;
protected boolean [] selected_channels = {true, true, true, true, true, true, true, true};
/* /*
protected double [] vnir_exp_corr = {1.0, 1.0, 1.0, 1.0}; protected double [] vnir_exp_corr = {1.0, 1.0, 1.0, 1.0};
...@@ -70,7 +75,7 @@ public class LwirReaderParameters { ...@@ -70,7 +75,7 @@ public class LwirReaderParameters {
protected int vnir_lag = 1; // frames protected int vnir_lag = 1; // frames
protected double max_mismatch_ms = 0.05; protected double max_mismatch_ms = 0.05;
protected int max_frame_diff = 1; // 2; protected int max_frame_diff = 1; // 2;
protected int debug_level = 0;//-3: OFF, -2:Fatal, -1:ERROR, 0:WARN, 1:INFO,2:DEBUG protected int debug_level = 0;//-3: OFF, -2:Fatal, -1:ERROR, 0:WARN, 1:INFO,2:DEBUG
// --- interface methods // --- interface methods
...@@ -106,6 +111,7 @@ public class LwirReaderParameters { ...@@ -106,6 +111,7 @@ public class LwirReaderParameters {
properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+""); properties.setProperty(prefix+"max_mismatch_ms", this.max_mismatch_ms+"");
properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+""); properties.setProperty(prefix+"max_frame_diff", this.max_frame_diff+"");
properties.setProperty(prefix+"debug_level", this.debug_level+""); properties.setProperty(prefix+"debug_level", this.debug_level+"");
properties.setProperty(prefix+"selected_channels", arr_to_str(this.selected_channels));
} }
...@@ -134,6 +140,7 @@ public class LwirReaderParameters { ...@@ -134,6 +140,7 @@ public class LwirReaderParameters {
if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms")); if (properties.getProperty(prefix+"max_mismatch_ms")!=null) this.max_mismatch_ms=Double.parseDouble(properties.getProperty(prefix+"max_mismatch_ms"));
if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff")); if (properties.getProperty(prefix+"max_frame_diff")!=null) this.max_frame_diff=Integer.parseInt(properties.getProperty(prefix+"max_frame_diff"));
if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level")); if (properties.getProperty(prefix+"debug_level")!=null) this.debug_level=Integer.parseInt(properties.getProperty(prefix+"debug_level"));
if (properties.getProperty(prefix+"selected_channels")!=null) this.selected_channels=str_to_barr(properties.getProperty(prefix+"selected_channels"));
parameters_updated = true; parameters_updated = true;
} }
@Override @Override
...@@ -163,6 +170,7 @@ public class LwirReaderParameters { ...@@ -163,6 +170,7 @@ public class LwirReaderParameters {
lrp.max_mismatch_ms= this.max_mismatch_ms; lrp.max_mismatch_ms= this.max_mismatch_ms;
lrp.max_frame_diff= this.max_frame_diff; lrp.max_frame_diff= this.max_frame_diff;
lrp.debug_level= this.debug_level; lrp.debug_level= this.debug_level;
lrp.selected_channels = this.selected_channels.clone();
return lrp; return lrp;
} }
...@@ -198,7 +206,8 @@ public class LwirReaderParameters { ...@@ -198,7 +206,8 @@ public class LwirReaderParameters {
(lrp.vnir_lag == this.vnir_lag) && (lrp.vnir_lag == this.vnir_lag) &&
(lrp.max_mismatch_ms == this.max_mismatch_ms) && (lrp.max_mismatch_ms == this.max_mismatch_ms) &&
(lrp.max_frame_diff == this.max_frame_diff) && (lrp.max_frame_diff == this.max_frame_diff) &&
(lrp.debug_level == this.debug_level); (lrp.debug_level == this.debug_level) &&
(java.util.Arrays.equals(lrp.selected_channels, this.selected_channels));
} }
@Override @Override
...@@ -225,6 +234,7 @@ public class LwirReaderParameters { ...@@ -225,6 +234,7 @@ public class LwirReaderParameters {
result = prime * result + arr_to_str(vnir_exp_corr).hashCode(); result = prime * result + arr_to_str(vnir_exp_corr).hashCode();
result = prime * result + arr_to_str(vnir_gcorr_rbgb).hashCode(); result = prime * result + arr_to_str(vnir_gcorr_rbgb).hashCode();
result = prime * result + (new Integer(lwir_trig_dly)).hashCode(); result = prime * result + (new Integer(lwir_trig_dly)).hashCode();
result = prime * result + arr_to_str(selected_channels).hashCode();
// next are not needed to be programmed to the cameras // next are not needed to be programmed to the cameras
// result = prime * result + (new Integer(vnir_lag)).hashCode(); // result = prime * result + (new Integer(vnir_lag)).hashCode();
// result = prime * result + (new Double(max_mismatch_ms)).hashCode(); // result = prime * result + (new Double(max_mismatch_ms)).hashCode();
...@@ -241,7 +251,7 @@ public class LwirReaderParameters { ...@@ -241,7 +251,7 @@ public class LwirReaderParameters {
gd.addStringField ("LWIR channels", arr_to_str(this.lwir_channels), 20, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'"); gd.addStringField ("LWIR channels", arr_to_str(this.lwir_channels), 20, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'");
gd.addStringField ("VNIR channels", arr_to_str(this.vnir_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'"); gd.addStringField ("VNIR channels", arr_to_str(this.vnir_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'");
gd.addCheckbox ("LWIR telemetry", this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)"); gd.addCheckbox ("LWIR telemetry", this.lwir_telemetry, "Set LWIR sesnors to provide telemetry data in the last 2 lines (may become mandatory later)");
gd.addNumericField("VNIR quality", this.vnir_quality, 3,6,"ms", "Visible range camera JPEG compression quality (all channels)"); gd.addNumericField("VNIR quality", this.vnir_quality, 3,6,"%", "Visible range camera JPEG compression quality (all channels)");
gd.addCheckbox ("VNIR undo white balance", this.vnir_scale, "Undo in-camera white balancing"); gd.addCheckbox ("VNIR undo white balance", this.vnir_scale, "Undo in-camera white balancing");
gd.addCheckbox ("VNIR autoexposure", this.vnir_autoexp, "Enable autoexposure for the visible range camera"); gd.addCheckbox ("VNIR autoexposure", this.vnir_autoexp, "Enable autoexposure for the visible range camera");
gd.addNumericField("VNIR vnir_max_autoexp_ms", this.vnir_max_autoexp_ms, 3,6,"ms", "Visible range camera maximal exposure in autoexposure mode"); gd.addNumericField("VNIR vnir_max_autoexp_ms", this.vnir_max_autoexp_ms, 3,6,"ms", "Visible range camera maximal exposure in autoexposure mode");
...@@ -256,12 +266,13 @@ public class LwirReaderParameters { ...@@ -256,12 +266,13 @@ public class LwirReaderParameters {
gd.addNumericField("VNIR lag", this.vnir_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one"); gd.addNumericField("VNIR lag", this.vnir_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one");
gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization"); gd.addNumericField("Max mismatch", this.max_mismatch_ms, 3,6,"ms","Maximal mismatch between image timestamps. Larger mismatch requires LWIR sinsor reinitialization");
gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps"); gd.addNumericField("Max frame diff",this.max_frame_diff, 0,3,"","Maximal difference in frames between simultaneously acquired channels as calculated from the timestamps");
gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG"); gd.addNumericField("Debug level", this.debug_level, 0,3,"","Image acquisition log level: -3: OFF, -2:FATAL, -1:ERROR, 0:WARN, 1:INFO, 2:DEBUG");
gd.addStringField ("Selected channels", arr_to_str(this.selected_channels), 20, "Space-separated channel selection (1 - selected, 0 - unselected)");
} }
public void dialogAnswers(GenericJTabbedDialog gd) { public void dialogAnswers(GenericJTabbedDialog gd) {
this.avg_number = (int) gd.getNextNumber(); this.avg_number = (int) gd.getNextNumber();
this.lwir_ffc = gd.getNextBoolean(); this.lwir_ffc = gd.getNextBoolean();
this.avg_all = gd.getNextBoolean(); this.avg_all = gd.getNextBoolean();
this.lwir_ip = gd.getNextString(); this.lwir_ip = gd.getNextString();
this.vnir_ip = gd.getNextString(); this.vnir_ip = gd.getNextString();
...@@ -284,6 +295,7 @@ public class LwirReaderParameters { ...@@ -284,6 +295,7 @@ public class LwirReaderParameters {
this.max_mismatch_ms = gd.getNextNumber(); this.max_mismatch_ms = gd.getNextNumber();
this.max_frame_diff = (int) gd.getNextNumber(); this.max_frame_diff = (int) gd.getNextNumber();
this.debug_level = (int) gd.getNextNumber(); this.debug_level = (int) gd.getNextNumber();
this.selected_channels = str_to_barr(gd.getNextString());
parameters_updated = true; parameters_updated = true;
} }
...@@ -307,6 +319,80 @@ public class LwirReaderParameters { ...@@ -307,6 +319,80 @@ public class LwirReaderParameters {
parameters_updated = false; parameters_updated = false;
} }
public boolean [] getSelected(){
return selected_channels;
}
public boolean [] getSelectedLwir(){
boolean [] sel = selected_channels.clone();
for (int i = lwir_channels.length; i < sel.length; i++ ) {
sel[i] = false;
}
return sel;
}
public boolean [] getSelectedVnir(){
boolean [] sel = selected_channels.clone();
for (int i = 0; i < lwir_channels.length; i++ ) {
sel[i] = false;
}
return sel;
}
public String [] getSourceFilesFlat(String [] sets, boolean[] channels) {
int num_sel = 0;
for (boolean s: channels) if (s) num_sel++;
String [] files = new String [sets.length * num_sel];
int indx = 0;
for (String set:sets) {
for (int i = 0; i < channels.length; i++) if (channels[i]) {
String file_base = set;
if (set.indexOf(Prefs.getFileSeparator()) >=0) {
file_base = set.substring(set.lastIndexOf(Prefs.getFileSeparator())+1);
}
files[indx++] =set + Prefs.getFileSeparator()+ file_base+"_"+i+".tiff";
}
}
return files;
}
// Image set may have different timestamps, only lwir0 matches
public String [][] getSourceFiles(String [] sets, boolean[] channels) {
String [][] files = new String [sets.length][channels.length];
for (int nset= 0; nset < sets.length; nset++) {
// read all files in the directory
File set_dir = new File(sets[nset]);
File [] channel_files = set_dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File current, String name) {
if (!(new File(current, name).isFile()) || !name.endsWith(".tiff")) return false;
String base = name.substring(0, name.lastIndexOf(".tiff"));
int undr = base.lastIndexOf("_");
if (undr < 0) return false;
int chn = -1;
try {
chn = Integer.parseInt(base.substring(undr + 1));
} catch (Exception e) {
}
return chn >= 0;
}
});
for (File f: channel_files) {
String base = f.getName().substring(0, f.getName().lastIndexOf(".tiff"));
int undr = base.lastIndexOf("_");
int chn = Integer.parseInt(base.substring(undr + 1));
if ((chn >= 0) && (chn < channels.length) && channels[chn]) {
files[nset][chn] = f.getPath();
}
}
}
return files;
}
// --- internal methods // --- internal methods
private String arr_to_str(int [] arr) { private String arr_to_str(int [] arr) {
...@@ -321,6 +407,23 @@ public class LwirReaderParameters { ...@@ -321,6 +407,23 @@ public class LwirReaderParameters {
return s.trim(); return s.trim();
} }
private String arr_to_str(boolean [] arr) {
String s = "";
for (boolean c:arr) s+= (c?1:0)+" ";
return s.trim();
}
private boolean [] str_to_barr(String s) {
int [] iarr = str_to_iarr(s);
if (iarr == null) return null;
boolean [] barr = new boolean [iarr.length];
for (int i = 0; i < barr.length; i++) {
barr[i] = iarr[i] != 0;
}
return barr;
}
private int [] str_to_iarr(String s) { private int [] str_to_iarr(String s) {
String [] sa; String [] sa;
if (s.indexOf(",") >= 0) { if (s.indexOf(",") >= 0) {
...@@ -349,4 +452,22 @@ public class LwirReaderParameters { ...@@ -349,4 +452,22 @@ public class LwirReaderParameters {
return darr; return darr;
} }
public boolean [] selectSourceChannels(){
return selectSourceChannels(selected_channels);
}
public boolean [] selectSourceChannels(boolean [] sel) {
GenericJTabbedDialog gd = new GenericJTabbedDialog("Set CLT parameters",300,500);
for (int i = 0; i < sel.length; i++) {
gd.addCheckbox ("Channel "+i, sel[i], "Enable processing camera channel "+i);
}
gd.showDialog();
if (gd.wasCanceled()) return null;
for (int i = 0; i < sel.length; i++) {
sel[i] = gd.getNextBoolean();
}
return sel;
}
} }
...@@ -640,7 +640,7 @@ the type of pixel data in this file getPixelType() ...@@ -640,7 +640,7 @@ the type of pixel data in this file getPixelType()
} }
// copied from JP46_Reader_camera.java // copied from JP46_Reader_camera.java
public ImagePlus encodeProperiesToInfo(ImagePlus imp){ public static ImagePlus encodeProperiesToInfo(ImagePlus imp){
String info="<?xml version=\"1.0\" encoding=\"UTF-8\"?><properties>"; String info="<?xml version=\"1.0\" encoding=\"UTF-8\"?><properties>";
Set<Object> jp4_set; Set<Object> jp4_set;
Properties jp4_prop; Properties jp4_prop;
...@@ -661,7 +661,7 @@ the type of pixel data in this file getPixelType() ...@@ -661,7 +661,7 @@ the type of pixel data in this file getPixelType()
return imp; return imp;
} }
public boolean decodeProperiesFromInfo(ImagePlus imp){ public static boolean decodeProperiesFromInfo(ImagePlus imp){
if (imp.getProperty("Info")==null) return false; if (imp.getProperty("Info")==null) return false;
String xml= (String) imp.getProperty("Info"); String xml= (String) imp.getProperty("Info");
...@@ -684,11 +684,15 @@ the type of pixel data in this file getPixelType() ...@@ -684,11 +684,15 @@ the type of pixel data in this file getPixelType()
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*"); NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) { for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName(); String name= allNodes.item(i).getNodeName();
String value=allNodes.item(i).getFirstChild().getNodeValue(); // System.out.print(name+" -> ");
imp.setProperty(name, value); String value = "";
try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch (Exception e) {
}
// System.out.println(value);
imp.setProperty(name, value);
} }
return true; return true;
} }
......
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