Commit 3f9c52b0 authored by Andrey Filippov's avatar Andrey Filippov

merged with lwir

parents 13959a97 047fdb5e
...@@ -55,6 +55,8 @@ import org.w3c.dom.NodeList; ...@@ -55,6 +55,8 @@ import org.w3c.dom.NodeList;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import com.elphel.imagej.readers.ImagejJp4Tiff;
import ij.IJ; import ij.IJ;
import ij.ImageJ; import ij.ImageJ;
import ij.ImagePlus; import ij.ImagePlus;
...@@ -69,6 +71,7 @@ import ij.plugin.frame.PlugInFrame; ...@@ -69,6 +71,7 @@ import ij.plugin.frame.PlugInFrame;
import ij.process.ImageConverter; import ij.process.ImageConverter;
import ij.process.ImageProcessor; import ij.process.ImageProcessor;
import ij.text.TextWindow; import ij.text.TextWindow;
import loci.formats.FormatException;
...@@ -87,6 +90,8 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener { ...@@ -87,6 +90,8 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener {
static File dir; static File dir;
ImagejJp4Tiff imagejJp4Tiff = new ImagejJp4Tiff();
public String camera_url = "http://192.168.0.236:8081/"; public String camera_url = "http://192.168.0.236:8081/";
public String camera_img = "bimg"; public String camera_img = "bimg";
public String camera_img_new = "towp/wait/bimg"; // will always wait for the next image (repetitive acquisitions get new images) public String camera_img_new = "towp/wait/bimg"; // will always wait for the next image (repetitive acquisitions get new images)
...@@ -109,8 +114,9 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener { ...@@ -109,8 +114,9 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener {
panel1 = new Panel(); panel1 = new Panel();
panel1.setLayout(new GridLayout(6, 1, 50, 5)); panel1.setLayout(new GridLayout(8, 1, 50, 5));
addButton("Open JP4/Tiff...",panel1);
addButton("Open JP4/JP46...",panel1); addButton("Open JP4/JP46...",panel1);
addButton("Open JP4/JP46 from camera",panel1); addButton("Open JP4/JP46 from camera",panel1);
addButton("Configure...",panel1); addButton("Configure...",panel1);
...@@ -137,8 +143,8 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener { ...@@ -137,8 +143,8 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener {
panel1 = new Panel(); panel1 = new Panel();
panel1.setLayout(new GridLayout(6, 1, 50, 5)); panel1.setLayout(new GridLayout(8, 1, 50, 5));
addButton("Open JP4/Tiff...",panel1);
addButton("Open JP4/JP46...",panel1); addButton("Open JP4/JP46...",panel1);
addButton("Open JP4/JP46 from camera",panel1); addButton("Open JP4/JP46 from camera",panel1);
addButton("Configure...",panel1); addButton("Configure...",panel1);
...@@ -169,7 +175,11 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener { ...@@ -169,7 +175,11 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener {
if (label==null) return; if (label==null) return;
/* button */ /* button */
if (label.equals("Open JP4/JP46...")) { if (label.equals("Open JP4/Tiff...")) {
read_jp4Tiff(arg,true);
}else if (label.equals("Open JP4/Tiff (no scale)...")) {
read_jp4Tiff(arg,false);
}else if (label.equals("Open JP4/JP46...")) {
read_jp46(arg,true); read_jp46(arg,true);
}else if (label.equals("Open JP4/JP46 (no scale)...")) { }else if (label.equals("Open JP4/JP46 (no scale)...")) {
read_jp46(arg,false); read_jp46(arg,false);
...@@ -227,7 +237,54 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener { ...@@ -227,7 +237,54 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener {
imp_stack.getProcessor().resetMinAndMax(); imp_stack.getProcessor().resetMinAndMax();
imp_stack.show(); imp_stack.show();
} }
public void read_jp4Tiff(String arg, // not used?
boolean scale) {
String LOG_LEVEL = ABSOLUTELY_SILENT? "OFF" : (IS_SILENT?"ERROR":"INFO");
boolean LOG_LEVEL_SET = loci.common.DebugTools.enableLogging(LOG_LEVEL);
if (!LOG_LEVEL_SET) { // only first time true
loci.common.DebugTools.setRootLevel(LOG_LEVEL);
}
JFileChooser fc=null;
//try {fc = new JFileChooser();}
fc = new JFileChooser();
//catch (Throwable e) {IJ.error("This plugin requires Java 2 or Swing."); return;}
fc.setMultiSelectionEnabled(true);
if (dir==null) {
String sdir = OpenDialog.getDefaultDirectory();
if (sdir!=null)
dir = new File(sdir);
}
if (dir!=null)
fc.setCurrentDirectory(dir);
int returnVal = fc.showOpenDialog(IJ.getInstance());
if (returnVal!=JFileChooser.APPROVE_OPTION)
return;
File[] files = fc.getSelectedFiles();
if (files.length==0) { // getSelectedFiles does not work on some JVMs
files = new File[1];
files[0] = fc.getSelectedFile();
}
String path = fc.getCurrentDirectory().getPath()+Prefs.getFileSeparator();
dir = fc.getCurrentDirectory();
for (int i=0; i<files.length; i++) {
try {
ImagePlus imp = imagejJp4Tiff.readTiffJp4(path + files[i].getName(), scale);
// imp.updateAndDraw();
imp.show();
} catch (IOException | FormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // throws IOException, FormatException { // std - include non-elphel properties with prefix std
// open(path, files[i].getName(), arg, scale);
}
}
public void read_jp46(String arg, boolean scale) { public void read_jp46(String arg, boolean scale) {
JFileChooser fc=null; JFileChooser fc=null;
//try {fc = new JFileChooser();} //try {fc = new JFileChooser();}
...@@ -274,6 +331,7 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener { ...@@ -274,6 +331,7 @@ public class JP46_Reader_camera0 extends PlugInFrame implements ActionListener {
confpanel = new Panel(); confpanel = new Panel();
gd.addPanel(confpanel); gd.addPanel(confpanel);
addButton("Open JP4/Tiff (no scale)...", confpanel);
addButton("Open JP4/JP46 (no scale)...", confpanel); addButton("Open JP4/JP46 (no scale)...", confpanel);
addButton("Open JP4/JP46 from camera (no scale)", confpanel); addButton("Open JP4/JP46 from camera (no scale)", confpanel);
...@@ -1413,9 +1471,13 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970 ...@@ -1413,9 +1471,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
); );
...@@ -350,12 +361,15 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene ...@@ -350,12 +361,15 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSimulatedPattern.DistortionParameters( public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSimulatedPattern.DistortionParameters(
64, //32, // use 64 for less artifacts, // correlationSize 64, //32, // use 64 for less artifacts, // correlationSize
64, // Maximal correlation size 16, // int correlationSizeLwir,
128, // 64, // Maximal correlation size
16, // int maximalCorrelationSizeLwir,
0.75,// reduce to 0.5 when correlationSize==64 // correlationGaussWidth 0.75,// reduce to 0.5 when correlationSize==64 // correlationGaussWidth
false, // boolean absoluteCorrelationGaussWidth=false; // do not scale correlationGaussWidth when the FFT size is increased false, // boolean absoluteCorrelationGaussWidth=false; // do not scale correlationGaussWidth when the FFT size is increased
0, //zeros - // leave this number of zeros on the margins of the window (toatal from both sides). If correlationGaussWidth>0 will 0, //zeros - // leave this number of zeros on the margins of the window (toatal from both sides). If correlationGaussWidth>0 will
// additionally multiply by Hamming // additionally multiply by Hamming
128, // FFT size 256, // FFTSize (was 128)
32, // FFTSize_lwir
0.5, //fftGaussWidth 0.5, //fftGaussWidth
0.0, //phaseCorrelationFraction 0.0, //phaseCorrelationFraction
1.5, // 2.5, //6.0, // 2.0, // 0.0, // correlationHighPassSigma, - pixels in frequency domain 1.5, // 2.5, //6.0, // 2.0, // 0.0, // correlationHighPassSigma, - pixels in frequency domain
...@@ -364,15 +378,18 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -364,15 +378,18 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
8.0, // 3.0, // correlationMaxOffset, // maximal distance between predicted and actual pattern node 8.0, // 3.0, // correlationMaxOffset, // maximal distance between predicted and actual pattern node
3.0, // 2.0, // increase back to .5? was needed with fisheye. 5.0, // double correlationMinContrast, // minimal contrast for the pattern to pass 3.0, // 2.0, // increase back to .5? was needed with fisheye. 5.0, // double correlationMinContrast, // minimal contrast for the pattern to pass
3.5, // 2.5, // correlationMinInitialContrast, // minimal contrast for the pattern of the center (initial point) 3.5, // 2.5, // correlationMinInitialContrast, // minimal contrast for the pattern of the center (initial point)
1.0, //this.correlationMinAbsoluteContrast, // minimal contrast for the pattern to pass, does not compensate for low ligt // Absolute contrast is broken (05.29.2019), disabling it
0.0, // 1.0, //this.correlationMinAbsoluteContrast, // minimal contrast for the pattern to pass, does not compensate for low ligt
// TODO: adjust to a reasonable number // TODO: adjust to a reasonable number
1.0, //this.correlationMinAbsoluteInitialContrast, // minimal contrast for the pattern of the center (initial point) 0.0, // 1.0, //this.correlationMinAbsoluteInitialContrast, // minimal contrast for the pattern of the center (initial point)
0.8, // scaleFirstPassContrast, // Decrease contrast of cells that are too close to the border to be processed in refinement pass 0.8, // scaleFirstPassContrast, // Decrease contrast of cells that are too close to the border to be processed in refinement pass
2.0, // public double contrastSelectSigmaCenter; // Gaussian sigma to select correlation centers (fraction of UV period), 0.02 (center spot)
0.1, // contrastSelectSigma, // Gaussian sigma to select correlation centers (fraction of UV period), 0.1 0.1, // contrastSelectSigma, // Gaussian sigma to select correlation centers (fraction of UV period), 0.1
0.5, //contrastAverageSigma, // Gaussian sigma to average correlation variations (as contrast reference) 0.5 0.5, //contrastAverageSigma, // Gaussian sigma to average correlation variations (as contrast reference) 0.5
150, // minimalPatternCluster minimal pattern cluster size (0 - disable retries) 40, // 150, // minimalPatternCluster minimal pattern cluster size (0 - disable retries)
10, // 150, // minimalPatternClusterLwir minimal pattern cluster size (0 - disable retries)
2.0, // scaleMinimalInitialContrast increase/decrease minimal contrast if initial cluster is >0 but less than minimalPatternCluster 2.0, // scaleMinimalInitialContrast increase/decrease minimal contrast if initial cluster is >0 but less than minimalPatternCluster
0.5, // when searching for grid, step this amount of the FFTSize 0.5, // when searching for grid, step this amount of the FFTSize
4, // public int patternSubdiv; 4, // public int patternSubdiv;
...@@ -674,11 +691,11 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -674,11 +691,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 +1011,8 @@ if (MORE_BUTTONS) { ...@@ -994,6 +1011,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 +1160,7 @@ if (MORE_BUTTONS) { ...@@ -1141,7 +1160,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")) {
...@@ -1402,6 +1421,7 @@ if (MORE_BUTTONS) { ...@@ -1402,6 +1421,7 @@ if (MORE_BUTTONS) {
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again // matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask(); // matchSimulatedPattern.invalidateFocusMask();
matchSimulatedPattern.calculateDistortions( matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters,
DISTORTION, // DISTORTION, //
PATTERN_DETECT, PATTERN_DETECT,
SIMUL, SIMUL,
...@@ -1798,6 +1818,7 @@ if (MORE_BUTTONS) { ...@@ -1798,6 +1818,7 @@ if (MORE_BUTTONS) {
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again // matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
// matchSimulatedPattern.invalidateFocusMask(); // matchSimulatedPattern.invalidateFocusMask();
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions( int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters,
DISTORTION, // DISTORTION, //
PATTERN_DETECT, PATTERN_DETECT,
SIMUL, SIMUL,
...@@ -2567,113 +2588,7 @@ if (MORE_BUTTONS) { ...@@ -2567,113 +2588,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;
} }
/* ======================================================================== */ /* ======================================================================== */
...@@ -9501,6 +9416,11 @@ if (MORE_BUTTONS) { ...@@ -9501,6 +9416,11 @@ if (MORE_BUTTONS) {
/// POWER_CONTROL.lightsOff(); /// POWER_CONTROL.lightsOff();
return; return;
} }
/* ======================================================================== */
if (label.equals("LWIR grids")) {
calculateLwirGrids();
return;
}
...@@ -9517,7 +9437,254 @@ if (MORE_BUTTONS) { ...@@ -9517,7 +9437,254 @@ 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
boolean [] sel_chn = LWIR_PARAMETERS.getSelected();
int numFiles = LWIR_PARAMETERS.getSourceFilesFlat(sourceSetList, sel_chn).length; // just the number
String [][] sourceFilesList=LWIR_PARAMETERS.getSourceFiles(sourceSetList, sel_chn);
boolean saveGrids=DISTORTION_PROCESS_CONFIGURATION.saveGridImages;
boolean overwriteGrids=DISTORTION_PROCESS_CONFIGURATION.overwriteResultFiles;
if (sourceSetList==null) return;
showPatternMinMaxPeriodDialog(PATTERN_DETECT, true);
int saved_file = 0;
int in_file = 0;
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){
in_file++;
long startFileTime=System.nanoTime();
if (DEBUG_LEVEL>0){
System.out.println(IJ.d2s(0.000000001*(System.nanoTime()-startTime),3)+"s: Processing set "+(nset+1) +" (of "+
sourceFilesList.length+"), channel # "+(nfile + 1)+
" (of "+ sourceFilesList[nset].length+"), file "+in_file+" (of "+ numFiles+ ") success in "+saved_file+" - "+sourceFilesList[nset][nfile]);
}
String grid_path = null;
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);
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();
boolean is_lwir = LWIR_PARAMETERS.is_LWIR(imp_sel);
int numAbsolutePoints=matchSimulatedPattern.calculateDistortions(
LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters,
DISTORTION, //
PATTERN_DETECT,
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 "+(in_file)+" 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 (imp_calibrated == null) {
if (DEBUG_LEVEL> -1) System.out.println("Grid is empty !");
continue;
}
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();
// String path = gridDir + Prefs.getFileSeparator() + set_name+Prefs.getFileSeparator()+imp_calibrated.getTitle();
if (UPDATE_STATUS) IJ.showStatus("Saving "+grid_path);
if (DEBUG_LEVEL>0) System.out.println("-->>> Saving "+grid_path+" - using "+numAbsolutePoints+" laser pointer references");
fs.saveAsTiffStack(grid_path);
}
}
}
if (DEBUG_LEVEL>0) System.out.println("Grid "+(saved_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;
}
saved_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(
LWIR_PARAMETERS, // LwirReaderParameters lwirReaderParameters,,
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;
}
/* ======================================================================== */ /* ======================================================================== */
public void processCalibrationFiles() { public void processCalibrationFiles() {
if (!showProcessCalibrationFilesDialog(PROCESS_PARAMETERS)) return; if (!showProcessCalibrationFilesDialog(PROCESS_PARAMETERS)) return;
...@@ -9561,10 +9728,10 @@ if (MORE_BUTTONS) { ...@@ -9561,10 +9728,10 @@ if (MORE_BUTTONS) {
imp_sel); // reuse the same image window imp_sel); // reuse the same image window
//Remove for old method? //Remove for old method?
matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize); matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
matchSimulatedPattern.calculateDistortions( matchSimulatedPattern.calculateDistortions(
DISTORTION, // LWIR_PARAMETERS,
PATTERN_DETECT, DISTORTION, //
PATTERN_DETECT,
SIMUL, SIMUL,
COMPONENTS.equalizeGreens, COMPONENTS.equalizeGreens,
imp_sel, imp_sel,
...@@ -12470,7 +12637,7 @@ if (MORE_BUTTONS) { ...@@ -12470,7 +12637,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
...@@ -12487,6 +12654,7 @@ if (MORE_BUTTONS) { ...@@ -12487,6 +12654,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
...@@ -17012,9 +17180,13 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17012,9 +17180,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 */
...@@ -17029,7 +17201,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17029,7 +17201,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
null, // no mesh distortion here null, // no mesh distortion here
thisSimulParameters.subdiv,// SIMUL.subdiv, - do not need high quality here thisSimulParameters.subdiv,// SIMUL.subdiv, - do not need high quality here
size, size,
true); // center for greens true, // center for greens
false);//boolean mono
sim_pix= simulationPattern.extractSimulPatterns ( sim_pix= simulationPattern.extractSimulPatterns (
thisSimulParameters, thisSimulParameters,
1, 1,
...@@ -17049,8 +17222,10 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17049,8 +17222,10 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
pixels[4], pixels[4],
WVgreens, // wave vectors (same units as the pixels array) WVgreens, // wave vectors (same units as the pixels array)
// patternDetectParameters.corrRingWidth, // ring (around r=0.5 dist to opposite corr) width // patternDetectParameters.corrRingWidth, // ring (around r=0.5 dist to opposite corr) width
0.1, // contrastSelectSigma 2.0, // distortionParameters.contrastSelectSigmaCenter, // Gaussian sigma to select correlation centers (fraction of UV period), 0.1
0.5, // contrastAverageSigma 0.1, // distortionParameters.contrastSelectSigma, // Gaussian sigma to select correlation centers (fraction of UV period), 0.1
// 0.1, // contrastSelectSigma
// 0.5, // contrastAverageSigma
0.0, // x0, // center coordinates 0.0, // x0, // center coordinates
0.0, //y0, 0.0, //y0,
title)[0]; // title base for optional plots names title)[0]; // title base for optional plots names
...@@ -17576,6 +17751,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17576,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
...@@ -17600,7 +17777,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17600,7 +17777,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
distortedPattern[2], // distortedPattern[2], //
simulParameters.subdiv, simulParameters.subdiv,
fft_size, fft_size,
simulParameters.center_for_g2); simulParameters.center_for_g2,
false);//boolean mono
wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel; wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel;
wVectors[0][1]=2.0*distortedPattern[0][1]/subpixel; wVectors[0][1]=2.0*distortedPattern[0][1]/subpixel;
wVectors[1][0]=2.0*distortedPattern[1][0]/subpixel; wVectors[1][0]=2.0*distortedPattern[1][0]/subpixel;
...@@ -17652,7 +17830,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) { ...@@ -17652,7 +17830,8 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
simCorr, // simCorr, //
simulParameters.subdiv, simulParameters.subdiv,
fft_size, fft_size,
simulParameters.center_for_g2); simulParameters.center_for_g2,
false);//boolean mono
} }
simul_pixels= simulationPattern.extractSimulPatterns ( simul_pixels= simulationPattern.extractSimulPatterns (
simulParameters, simulParameters,
...@@ -19828,7 +20007,7 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -19828,7 +20007,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);
...@@ -19844,16 +20023,30 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -19844,16 +20023,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();
...@@ -19864,23 +20057,44 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -19864,23 +20057,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;
}
/* ======================================================================== */ /* ======================================================================== */
...@@ -20084,10 +20298,13 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -20084,10 +20298,13 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
public boolean showDistortionDialog(MatchSimulatedPattern.DistortionParameters distortionParameters) { public boolean showDistortionDialog(MatchSimulatedPattern.DistortionParameters distortionParameters) {
int i; int i;
GenericDialog gd = new GenericDialog("Distrortion parameters"); GenericDialog gd = new GenericDialog("Distrortion parameters");
gd.addNumericField("FFTSize (Initial pattern detection only):", distortionParameters.FFTSize, 0); // 128 gd.addNumericField("FFTSize (Initial pattern detection only):", distortionParameters.FFTSize, 0); // 256
gd.addNumericField("FFTSize for LWIR sensors):", distortionParameters.FFTSize_lwir, 0); // 32
gd.addNumericField("FFT Gaussian width (relative):", distortionParameters.fftGaussWidth, 3); gd.addNumericField("FFT Gaussian width (relative):", distortionParameters.fftGaussWidth, 3);
gd.addNumericField("Correlation size:", distortionParameters.correlationSize, 0); // 64 gd.addNumericField("Correlation size:", distortionParameters.correlationSize, 0); // 64
gd.addNumericField("Maximal correlation size:", distortionParameters.maximalCorrelationSize, 0); // 64 gd.addNumericField("Correlation size LWIR:", distortionParameters.correlationSizeLwir, 0); // 16
gd.addNumericField("Maximal correlation size:", distortionParameters.maximalCorrelationSize, 0); // 128
gd.addNumericField("Maximal correlation size LWIR:", distortionParameters.maximalCorrelationSizeLwir, 0); // 16
gd.addNumericField("Correlation Gauss width (relative):", distortionParameters.correlationGaussWidth, 3); gd.addNumericField("Correlation Gauss width (relative):", distortionParameters.correlationGaussWidth, 3);
gd.addCheckbox("Keep Gaussian width absolute when increasing FFT size",distortionParameters.absoluteCorrelationGaussWidth); gd.addCheckbox("Keep Gaussian width absolute when increasing FFT size",distortionParameters.absoluteCorrelationGaussWidth);
...@@ -20108,23 +20325,25 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -20108,23 +20325,25 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
gd.addNumericField("Correlation minimal contrast for initial search (absolute)", distortionParameters.correlationMinAbsoluteInitialContrast, 3); gd.addNumericField("Correlation minimal contrast for initial search (absolute)", distortionParameters.correlationMinAbsoluteInitialContrast, 3);
gd.addNumericField("Decrease contrast of cells that are too close to the border to be processed in refinement pass", distortionParameters.scaleFirstPassContrast, 3); gd.addNumericField("Decrease contrast of cells that are too close to the border to be processed in refinement pass", distortionParameters.scaleFirstPassContrast, 3);
gd.addNumericField("Gaussian sigma to select correlation centers (fraction of UV period), 0.1", distortionParameters.contrastSelectSigma, 3); gd.addNumericField("Gaussian sigma to select correlation center in pixels, 2.0", distortionParameters.contrastSelectSigmaCenter, 3);
gd.addNumericField("Gaussian sigma to select correlation off-centers (fraction of UV period), 0.1", distortionParameters.contrastSelectSigma, 3);
gd.addNumericField("Gaussian sigma to average correlation variations (as contrast reference), 0.5", distortionParameters.contrastAverageSigma, 3); gd.addNumericField("Gaussian sigma to average correlation variations (as contrast reference), 0.5", distortionParameters.contrastAverageSigma, 3);
gd.addNumericField("Minimal initial pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternCluster, 0); gd.addNumericField("Minimal initial pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternCluster, 0); // 40
gd.addNumericField("Minimal initial LWIR pattern cluster size (0 - disable retries)", distortionParameters.minimalPatternClusterLwir, 0); // 10
gd.addNumericField("Scale minimal contrast if the initial cluster is nonzero but smaller", distortionParameters.scaleMinimalInitialContrast, 3); gd.addNumericField("Scale minimal contrast if the initial cluster is nonzero but smaller", distortionParameters.scaleMinimalInitialContrast, 3);
gd.addNumericField("Overlap of FFT areas when searching for pattern", distortionParameters.searchOverlap, 3); gd.addNumericField("Overlap of FFT areas when searching for pattern", distortionParameters.searchOverlap, 3);
gd.addNumericField("Pattern subdivision:", distortionParameters.patternSubdiv, 0); gd.addNumericField("Pattern subdivision:", distortionParameters.patternSubdiv, 0); // 4
gd.addNumericField("Blur pattern bitmap (sigma): ", distortionParameters.bPatternSigma, 3,5,"pattern cell"); gd.addNumericField("Blur pattern bitmap (sigma): ", distortionParameters.bPatternSigma, 3,5,"pattern cell"); // 0.02
gd.addNumericField("Blur pattern (sigma): ", distortionParameters.barraySigma, 3,5,"sensor pix"); gd.addNumericField("Blur pattern (sigma): ", distortionParameters.barraySigma, 3,5,"sensor pix"); // 0.5
gd.addNumericField("Correlation weights (around maximum):", distortionParameters.correlationWeightSigma, 3,5,"nodes"); gd.addNumericField("Correlation weights (around maximum):", distortionParameters.correlationWeightSigma, 3,5,"nodes"); // 2.5
gd.addNumericField("Correlation radius scale (0 - sharp sigma)", distortionParameters.correlationRadiusScale, 1,3,"sigmas"); gd.addNumericField("Correlation radius scale (0 - sharp sigma)", distortionParameters.correlationRadiusScale, 1,3,"sigmas"); //2.0
gd.addNumericField("Correlation maximal radius to use", distortionParameters.correlationRadius, 0,1,"pix"); gd.addNumericField("Correlation maximal radius to use", distortionParameters.correlationRadius, 0,1,"pix"); // 2.0
gd.addNumericField("Correlation maximum calculation threshold", distortionParameters.correlationThreshold*100, 2,5,"%"); gd.addNumericField("Correlation maximum calculation threshold", distortionParameters.correlationThreshold*100, 2,5,"%"); // .8
gd.addNumericField("Interpolate correlation (FFT*linear)", distortionParameters.correlationSubdiv, 0,1,"x"); gd.addNumericField("Interpolate correlation (FFT*linear)", distortionParameters.correlationSubdiv, 0,3,"x"); // 16
gd.addNumericField("Interpolate correlation with FFT", distortionParameters.correlationFFTSubdiv, 0,1,"x"); gd.addNumericField("Interpolate correlation with FFT", distortionParameters.correlationFFTSubdiv, 0,3,"x"); // 4
gd.addNumericField("Correlation dx (debug)", distortionParameters.correlationDx, 3); gd.addNumericField("Correlation dx (debug)", distortionParameters.correlationDx, 3);
gd.addNumericField("Correlation dy (debug)", distortionParameters.correlationDy, 3); gd.addNumericField("Correlation dy (debug)", distortionParameters.correlationDy, 3);
...@@ -20167,35 +20386,37 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -20167,35 +20386,37 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
WindowTools.addScrollBars(gd); WindowTools.addScrollBars(gd);
gd.showDialog(); gd.showDialog();
if (gd.wasCanceled()) return false; if (gd.wasCanceled()) return false;
distortionParameters.FFTSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.FFTSize=1; distortionParameters.FFTSize_lwir = makePowerOfTwo((int) gd.getNextNumber());
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.FFTSize <<=1; /* make it to be power of 2 */ distortionParameters.fftGaussWidth= gd.getNextNumber();
distortionParameters.fftGaussWidth= gd.getNextNumber(); distortionParameters.correlationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.correlationSize=1; distortionParameters.correlationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.correlationSize <<=1; /* make it to be power of 2 */ distortionParameters.maximalCorrelationSize = makePowerOfTwo((int) gd.getNextNumber());
distortionParameters.maximalCorrelationSize=1; distortionParameters.maximalCorrelationSizeLwir = makePowerOfTwo((int) gd.getNextNumber());
for (i=(int) gd.getNextNumber(); i >1; i>>=1) distortionParameters.maximalCorrelationSize <<=1; /* make it to be power of 2 */ distortionParameters.correlationGaussWidth= gd.getNextNumber();
distortionParameters.correlationGaussWidth= gd.getNextNumber();
distortionParameters.absoluteCorrelationGaussWidth=gd.getNextBoolean(); distortionParameters.absoluteCorrelationGaussWidth=gd.getNextBoolean();
distortionParameters.zeros= (int) gd.getNextNumber(); distortionParameters.zeros= (int) gd.getNextNumber();
distortionParameters.phaseCorrelationFraction=gd.getNextNumber(); distortionParameters.phaseCorrelationFraction= gd.getNextNumber();
distortionParameters.correlationHighPassSigma=gd.getNextNumber(); distortionParameters.correlationHighPassSigma= gd.getNextNumber();
distortionParameters.correlationLowPassSigma= gd.getNextNumber(); distortionParameters.correlationLowPassSigma= gd.getNextNumber();
distortionParameters.correlationMaxOffset= gd.getNextNumber(); distortionParameters.correlationMaxOffset= gd.getNextNumber();
distortionParameters.correlationRingWidth= gd.getNextNumber(); distortionParameters.correlationRingWidth= gd.getNextNumber();
distortionParameters.correlationMinContrast= gd.getNextNumber(); distortionParameters.correlationMinContrast= gd.getNextNumber();
distortionParameters.correlationMinInitialContrast= gd.getNextNumber(); distortionParameters.correlationMinInitialContrast= gd.getNextNumber();
distortionParameters.correlationMinAbsoluteContrast= gd.getNextNumber(); distortionParameters.correlationMinAbsoluteContrast= gd.getNextNumber();
distortionParameters.correlationMinAbsoluteInitialContrast= gd.getNextNumber(); distortionParameters.correlationMinAbsoluteInitialContrast= gd.getNextNumber();
distortionParameters.scaleFirstPassContrast= gd.getNextNumber(); distortionParameters.scaleFirstPassContrast= gd.getNextNumber();
distortionParameters.contrastSelectSigma= gd.getNextNumber(); distortionParameters.contrastSelectSigmaCenter= gd.getNextNumber();
distortionParameters.contrastAverageSigma= gd.getNextNumber(); distortionParameters.contrastSelectSigma= gd.getNextNumber();
distortionParameters.contrastAverageSigma= gd.getNextNumber();
distortionParameters.minimalPatternCluster=(int) gd.getNextNumber(); distortionParameters.minimalPatternCluster=(int) gd.getNextNumber();
distortionParameters.minimalPatternClusterLwir=(int) gd.getNextNumber();
distortionParameters.scaleMinimalInitialContrast=gd.getNextNumber(); distortionParameters.scaleMinimalInitialContrast=gd.getNextNumber();
distortionParameters.searchOverlap= gd.getNextNumber(); distortionParameters.searchOverlap= gd.getNextNumber();
distortionParameters.patternSubdiv= (int) gd.getNextNumber(); distortionParameters.patternSubdiv= (int) gd.getNextNumber();
distortionParameters.bPatternSigma= gd.getNextNumber(); distortionParameters.bPatternSigma= gd.getNextNumber();
...@@ -20240,6 +20461,12 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica ...@@ -20240,6 +20461,12 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
MASTER_DEBUG_LEVEL= (int) gd.getNextNumber(); MASTER_DEBUG_LEVEL= (int) gd.getNextNumber();
return true; return true;
} }
private int makePowerOfTwo(int v) {
int v2 = 1;
for (int i=v; i > 1; i>>=1 ) v2 <<=1; /* make it to be power of 2 */
return v2;
}
/* ======================================================================== */ /* ======================================================================== */
/* ======================================================================== */ /* ======================================================================== */
public boolean showGaussianStackDialog(EyesisAberrations.InverseParameters inverseParameters) { public boolean showGaussianStackDialog(EyesisAberrations.InverseParameters inverseParameters) {
...@@ -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,13 @@ public class EyesisAberrations { ...@@ -1277,10 +1276,13 @@ public class EyesisAberrations {
} }
} }
} }
int rslt=matchSimulatedPattern.calculateDistortions( int rslt=matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, // distortionParameters, //
patternDetectParameters, patternDetectParameters,
// patternDetectParameters.minGridPeriod/2,
// patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
colorComponents.equalizeGreens, colorComponents.equalizeGreens,
imp, imp,
...@@ -1313,11 +1315,11 @@ public class EyesisAberrations { ...@@ -1313,11 +1315,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 +1327,7 @@ public class EyesisAberrations { ...@@ -1325,7 +1327,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 +1349,20 @@ public class EyesisAberrations { ...@@ -1347,20 +1349,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 +1372,11 @@ public class EyesisAberrations { ...@@ -1370,11 +1372,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 +1414,14 @@ public class EyesisAberrations { ...@@ -1412,14 +1414,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 +1435,7 @@ public class EyesisAberrations { ...@@ -1433,7 +1435,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 +1443,8 @@ public class EyesisAberrations { ...@@ -1441,8 +1443,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 +1457,7 @@ public class EyesisAberrations { ...@@ -1455,7 +1457,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 +1502,7 @@ public class EyesisAberrations { ...@@ -1500,7 +1502,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 +1538,7 @@ public class EyesisAberrations { ...@@ -1536,7 +1538,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 +1553,7 @@ public class EyesisAberrations { ...@@ -1551,7 +1553,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 +1564,8 @@ public class EyesisAberrations { ...@@ -1562,8 +1564,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 +1583,7 @@ public class EyesisAberrations { ...@@ -1581,7 +1583,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 +1601,7 @@ public class EyesisAberrations { ...@@ -1599,7 +1601,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 +1636,9 @@ public class EyesisAberrations { ...@@ -1634,9 +1636,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 +1705,18 @@ public class EyesisAberrations { ...@@ -1703,18 +1705,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 +1735,14 @@ public class EyesisAberrations { ...@@ -1733,14 +1735,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 +1769,9 @@ public class EyesisAberrations { ...@@ -1767,9 +1769,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 +1782,7 @@ public class EyesisAberrations { ...@@ -1780,7 +1782,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 +1815,7 @@ public class EyesisAberrations { ...@@ -1813,7 +1815,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 +1833,9 @@ public class EyesisAberrations { ...@@ -1831,9 +1833,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 +1891,7 @@ public class EyesisAberrations { ...@@ -1889,7 +1891,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 +1910,7 @@ public class EyesisAberrations { ...@@ -1908,7 +1910,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 +1932,7 @@ public class EyesisAberrations { ...@@ -1930,7 +1932,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 +1942,9 @@ public class EyesisAberrations { ...@@ -1940,9 +1942,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 +1962,9 @@ public class EyesisAberrations { ...@@ -1960,9 +1962,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 +1995,7 @@ public class EyesisAberrations { ...@@ -1993,7 +1995,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 +2027,8 @@ public class EyesisAberrations { ...@@ -2025,8 +2027,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 +2046,7 @@ public class EyesisAberrations { ...@@ -2044,7 +2046,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 +2055,7 @@ public class EyesisAberrations { ...@@ -2053,7 +2055,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 +2082,11 @@ public class EyesisAberrations { ...@@ -2080,11 +2082,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 +2106,12 @@ public class EyesisAberrations { ...@@ -2104,12 +2106,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 +2150,9 @@ public class EyesisAberrations { ...@@ -2148,9 +2150,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 +2225,7 @@ public class EyesisAberrations { ...@@ -2223,7 +2225,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 +2233,7 @@ public class EyesisAberrations { ...@@ -2231,7 +2233,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 +2252,7 @@ public class EyesisAberrations { ...@@ -2250,7 +2252,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 +2287,7 @@ public class EyesisAberrations { ...@@ -2285,7 +2287,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 +2311,17 @@ public class EyesisAberrations { ...@@ -2309,16 +2311,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 +2339,7 @@ public class EyesisAberrations { ...@@ -2336,7 +2339,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 +2363,7 @@ public class EyesisAberrations { ...@@ -2360,7 +2363,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 +2374,7 @@ public class EyesisAberrations { ...@@ -2371,7 +2374,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 +2402,8 @@ public class EyesisAberrations { ...@@ -2399,7 +2402,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 +2440,7 @@ public class EyesisAberrations { ...@@ -2436,7 +2440,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 +2489,7 @@ public class EyesisAberrations { ...@@ -2485,7 +2489,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 +2538,7 @@ public class EyesisAberrations { ...@@ -2534,7 +2538,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 +2644,7 @@ public class EyesisAberrations { ...@@ -2640,7 +2644,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 +2658,7 @@ public class EyesisAberrations { ...@@ -2654,7 +2658,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 +2673,18 @@ public class EyesisAberrations { ...@@ -2669,16 +2673,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
...@@ -2704,7 +2710,8 @@ public class EyesisAberrations { ...@@ -2704,7 +2710,8 @@ public class EyesisAberrations {
distortedPattern[2], // distortedPattern[2], //
simulParameters.subdiv, simulParameters.subdiv,
fft_size, fft_size,
simulParameters.center_for_g2); simulParameters.center_for_g2,
false);//boolean mono
wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel; wVectors[0][0]=2.0*distortedPattern[0][0]/subpixel;
wVectors[0][1]=2.0*distortedPattern[0][1]/subpixel; wVectors[0][1]=2.0*distortedPattern[0][1]/subpixel;
wVectors[1][0]=2.0*distortedPattern[1][0]/subpixel; wVectors[1][0]=2.0*distortedPattern[1][0]/subpixel;
...@@ -2747,7 +2754,8 @@ public class EyesisAberrations { ...@@ -2747,7 +2754,8 @@ public class EyesisAberrations {
simCorr, // simCorr, //
simulParameters.subdiv, simulParameters.subdiv,
fft_size, fft_size,
simulParameters.center_for_g2); simulParameters.center_for_g2,
false);//boolean mono
} }
// simul_pixels= simulationPattern.extractSimulPatterns ( // simul_pixels= simulationPattern.extractSimulPatterns (
simul_pixels= simulationPattern.extractSimulPatterns ( simul_pixels= simulationPattern.extractSimulPatterns (
...@@ -2765,10 +2773,10 @@ public class EyesisAberrations { ...@@ -2765,10 +2773,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 +2791,7 @@ public class EyesisAberrations { ...@@ -2783,7 +2791,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 +2814,7 @@ public class EyesisAberrations { ...@@ -2806,7 +2814,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 +2828,7 @@ public class EyesisAberrations { ...@@ -2820,7 +2828,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 +2910,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -2902,7 +2910,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 +2946,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -2938,7 +2946,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 +3000,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -2992,8 +3000,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 +3124,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3116,7 +3124,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 +3178,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3170,7 +3178,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 +3186,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3178,11 +3186,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 +3199,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3191,7 +3199,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 +3218,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3210,7 +3218,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 +3286,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3278,7 +3286,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 +3308,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3300,14 +3308,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 +3343,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3335,7 +3343,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 +3361,19 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3353,19 +3361,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 +3447,17 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3439,17 +3447,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 +3523,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3515,7 +3523,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 +3557,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3549,14 +3557,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 +3586,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3578,7 +3586,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 +3598,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3590,14 +3598,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 +3663,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3655,13 +3663,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 +3705,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3697,7 +3705,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 +3768,9 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3760,9 +3768,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 +3874,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -3866,7 +3874,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 +4008,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4000,11 +4008,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 +4156,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4148,7 +4156,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 +4227,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4219,7 +4227,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 +4250,9 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4242,9 +4250,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 +4313,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4305,7 +4313,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 +4412,20 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4404,20 +4412,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 +4449,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4441,7 +4449,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 +4474,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4466,7 +4474,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 +4488,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4480,7 +4488,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 +4533,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4525,7 +4533,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 +4552,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4544,7 +4552,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 +4590,15 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4582,15 +4590,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 +4614,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4606,8 +4614,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 +4635,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4627,14 +4635,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 +4652,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4644,7 +4652,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 +4661,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4653,8 +4661,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 +4675,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4667,8 +4675,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 +4690,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4682,7 +4690,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 +4707,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4699,7 +4707,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 +4756,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4748,7 +4756,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 +4779,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4771,7 +4779,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 +4796,19 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4788,19 +4796,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 +4829,18 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4821,18 +4829,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 +4856,14 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4848,14 +4856,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 +4880,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4872,7 +4880,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 +4891,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4883,7 +4891,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 +4902,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4894,7 +4902,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 +4913,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4905,7 +4913,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 +4922,11 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4914,11 +4922,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 +4941,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4933,7 +4941,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 +4996,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -4988,7 +4996,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 +5036,13 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5027,13 +5036,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 +5076,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5067,8 +5076,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 +5085,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5076,7 +5085,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 +5298,8 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5288,8 +5298,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 +5344,7 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5334,7 +5344,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 +5354,10 @@ if (globalDebugLevel>2)globalDebugLevel=0; //*********************************** ...@@ -5344,10 +5354,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"));
} }
} }
} }
...@@ -665,9 +665,12 @@ horizontal axis: ...@@ -665,9 +665,12 @@ horizontal axis:
boolean noMessageBoxes=true; boolean noMessageBoxes=true;
int numAbsolutePoints = matchSimulatedPattern.calculateDistortions( int numAbsolutePoints = matchSimulatedPattern.calculateDistortions(
null, // LwirReaderParameters lwirReaderParameters, // null is OK
// 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, //
...@@ -838,23 +841,26 @@ horizontal axis: ...@@ -838,23 +841,26 @@ horizontal axis:
// matchSimulatedPatterns[numSensor].getChannel(images[numSensor])+" "); // matchSimulatedPatterns[numSensor].getChannel(images[numSensor])+" ");
int numAbsolutePoints = this.matchSimulatedPatterns[numSensor].calculateDistortions( int numAbsolutePoints = this.matchSimulatedPatterns[numSensor].calculateDistortions(
// allow more of grid around pointers? null, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, // // allow more of grid around pointers?
this.patternDetectParameters, distortionParameters, //
simulParameters, this.patternDetectParameters,
equalizeGreens, imp_eq, // this.patternDetectParameters.minGridPeriod/2,
this.laserPointers, // null, //LASER_POINTERS, // // this.patternDetectParameters.maxGridPeriod/2,
// LaserPointer laserPointer, // simulParameters,
// LaserPointer object or null equalizeGreens, imp_eq,
true, // don't care -removeOutOfGridPointers this.laserPointers, // null, //LASER_POINTERS, //
null, // double [][][] hintGrid, // predicted grid array (or null) // LaserPointer laserPointer, //
0, // double hintGridTolerance, // allowed mismatch (fraction of period) or 0 - orientation only // LaserPointer object or null
true, // don't care -removeOutOfGridPointers
threadsMax, null, // double [][][] hintGrid, // predicted grid array (or null)
updateStatus, 0, // double hintGridTolerance, // allowed mismatch (fraction of period) or 0 - orientation only
debug_level,
distortionParameters.loop_debug_level, // debug level threadsMax,
noMessageBoxes); updateStatus,
debug_level,
distortionParameters.loop_debug_level, // debug level
noMessageBoxes);
if (numAbsolutePoints <= 0) { // no pointers in this image if (numAbsolutePoints <= 0) { // no pointers in this image
String msg = "*** No laser pointers matched for " + images[numSensor].getTitle() + " - they are needed for absolute grid positioning"; String msg = "*** No laser pointers matched for " + images[numSensor].getTitle() + " - they are needed for absolute grid positioning";
if (debug_level > 0) System.out.println("Warning: " + msg); if (debug_level > 0) System.out.println("Warning: " + msg);
......
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) &&
...@@ -100,6 +99,7 @@ public class LensAdjustment { ...@@ -100,6 +99,7 @@ public class LensAdjustment {
ImagePlus imp_eq=matchSimulatedPattern.applyFlatField (imp); // will throw if image size mismatch ImagePlus imp_eq=matchSimulatedPattern.applyFlatField (imp); // will throw if image size mismatch
if (updating) { if (updating) {
double maxActualCorr= matchSimulatedPattern.refineDistortionCorrelation ( double maxActualCorr= matchSimulatedPattern.refineDistortionCorrelation (
null, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, // distortionParameters, //
patternDetectParameters, patternDetectParameters,
simulParameters, simulParameters,
...@@ -118,7 +118,7 @@ public class LensAdjustment { ...@@ -118,7 +118,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,15 +127,18 @@ public class LensAdjustment { ...@@ -127,15 +127,18 @@ 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());
} }
matchSimulatedPattern.distortions( matchSimulatedPattern.distortions(
null, // is not used in update mode null, //LwirReaderParameters lwirReaderParameters, // null is OK
null, // final boolean [] triedIndices, // 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
...@@ -156,8 +159,11 @@ public class LensAdjustment { ...@@ -156,8 +159,11 @@ public class LensAdjustment {
// matchSimulatedPattern.invalidateFlatFieldForGrid(); //Keep these! // matchSimulatedPattern.invalidateFlatFieldForGrid(); //Keep these!
// matchSimulatedPattern.invalidateFocusMask(); // matchSimulatedPattern.invalidateFocusMask();
numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // allow more of grid around pointers? numAbsolutePoints=matchSimulatedPattern.calculateDistortions( // allow more of grid around pointers?
null, // LwirReaderParameters lwirReaderParameters, // null is OK
distortionParameters, // distortionParameters, //
patternDetectParameters, patternDetectParameters,
// patternDetectParameters.minGridPeriod/2,
// patternDetectParameters.maxGridPeriod/2,
simulParameters, simulParameters,
equalizeGreens, equalizeGreens,
imp_eq, imp_eq,
...@@ -201,7 +207,7 @@ public class LensAdjustment { ...@@ -201,7 +207,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 +222,15 @@ public class LensAdjustment { ...@@ -216,15 +222,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 +243,10 @@ public class LensAdjustment { ...@@ -237,10 +243,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 +264,34 @@ public class LensAdjustment { ...@@ -258,34 +264,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 +301,15 @@ public class LensAdjustment { ...@@ -295,15 +301,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 +318,16 @@ public class LensAdjustment { ...@@ -312,16 +318,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 +336,45 @@ public class LensAdjustment { ...@@ -330,45 +336,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 +390,24 @@ public class LensAdjustment { ...@@ -384,24 +390,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 +422,10 @@ public class LensAdjustment { ...@@ -416,10 +422,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 +437,7 @@ public class LensAdjustment { ...@@ -431,7 +437,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 +449,7 @@ public class LensAdjustment { ...@@ -443,7 +449,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 +460,21 @@ public class LensAdjustment { ...@@ -454,21 +460,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 +496,15 @@ public class LensAdjustment { ...@@ -490,15 +496,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 +517,7 @@ public class LensAdjustment { ...@@ -511,7 +517,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 +531,7 @@ public class LensAdjustment { ...@@ -525,7 +531,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 +539,21 @@ public class LensAdjustment { ...@@ -533,21 +539,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 +563,8 @@ public class LensAdjustment { ...@@ -557,8 +563,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 +584,7 @@ public class LensAdjustment { ...@@ -578,7 +584,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 +594,15 @@ public class LensAdjustment { ...@@ -588,15 +594,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 +618,8 @@ public class LensAdjustment { ...@@ -612,8 +618,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 +639,7 @@ public class LensAdjustment { ...@@ -633,7 +639,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 +661,15 @@ public class LensAdjustment { ...@@ -655,15 +661,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 +682,7 @@ public class LensAdjustment { ...@@ -676,7 +682,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 +707,17 @@ public class LensAdjustment { ...@@ -701,17 +707,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 +728,7 @@ public class LensAdjustment { ...@@ -722,7 +728,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 +748,7 @@ public class LensAdjustment { ...@@ -742,7 +748,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 +757,15 @@ public class LensAdjustment { ...@@ -751,15 +757,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 +780,12 @@ public class LensAdjustment { ...@@ -774,12 +780,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 +801,7 @@ public class LensAdjustment { ...@@ -795,7 +801,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 +812,8 @@ public class LensAdjustment { ...@@ -806,7 +812,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 +826,15 @@ public class LensAdjustment { ...@@ -819,15 +826,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 +847,7 @@ public class LensAdjustment { ...@@ -840,7 +847,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 +870,18 @@ public class LensAdjustment { ...@@ -863,18 +870,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 +891,8 @@ public class LensAdjustment { ...@@ -884,8 +891,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 +912,7 @@ public class LensAdjustment { ...@@ -905,7 +912,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 +922,14 @@ public class LensAdjustment { ...@@ -915,14 +922,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 +945,8 @@ public class LensAdjustment { ...@@ -938,8 +945,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 +966,7 @@ public class LensAdjustment { ...@@ -959,7 +966,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 +998,7 @@ public class LensAdjustment { ...@@ -991,7 +998,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 +1026,7 @@ public class LensAdjustment { ...@@ -1019,7 +1026,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 +1055,13 @@ public class LensAdjustment { ...@@ -1048,13 +1055,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 +1106,20 @@ public class LensAdjustment { ...@@ -1099,20 +1106,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 +1136,7 @@ public class LensAdjustment { ...@@ -1129,7 +1136,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 +1148,11 @@ public class LensAdjustment { ...@@ -1141,11 +1148,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 +1167,11 @@ public class LensAdjustment { ...@@ -1160,11 +1167,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 +1267,7 @@ public class LensAdjustment { ...@@ -1260,7 +1267,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 +1308,20 @@ public class LensAdjustment { ...@@ -1301,20 +1308,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 +1375,14 @@ public class LensAdjustment { ...@@ -1368,14 +1375,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 +1391,7 @@ public class LensAdjustment { ...@@ -1384,7 +1391,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 +1417,7 @@ public class LensAdjustment { ...@@ -1410,7 +1417,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 +1428,7 @@ public class LensAdjustment { ...@@ -1421,7 +1428,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 +1441,7 @@ public class LensAdjustment { ...@@ -1434,7 +1441,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 +1529,7 @@ public class LensAdjustment { ...@@ -1522,7 +1529,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 +1549,7 @@ public class LensAdjustment { ...@@ -1542,7 +1549,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 +1563,8 @@ public class LensAdjustment { ...@@ -1556,8 +1563,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 +1587,23 @@ public class LensAdjustment { ...@@ -1580,23 +1587,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 +1612,7 @@ public class LensAdjustment { ...@@ -1605,7 +1612,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 +1676,8 @@ public class LensAdjustment { ...@@ -1669,8 +1676,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 +1700,20 @@ public class LensAdjustment { ...@@ -1693,20 +1700,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 +1727,25 @@ public class LensAdjustment { ...@@ -1720,25 +1727,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 +1771,24 @@ public class LensAdjustment { ...@@ -1764,24 +1771,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 +1797,7 @@ public class LensAdjustment { ...@@ -1790,7 +1797,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 +1805,7 @@ public class LensAdjustment { ...@@ -1798,7 +1805,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 +1814,17 @@ public class LensAdjustment { ...@@ -1807,17 +1814,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 +1868,7 @@ public class LensAdjustment { ...@@ -1861,7 +1868,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 +1876,9 @@ public class LensAdjustment { ...@@ -1869,9 +1876,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 +1888,8 @@ public class LensAdjustment { ...@@ -1881,8 +1888,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 +1912,14 @@ public class LensAdjustment { ...@@ -1905,14 +1912,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 +1934,7 @@ public class LensAdjustment { ...@@ -1927,7 +1934,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 +1942,12 @@ public class LensAdjustment { ...@@ -1935,12 +1942,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 +1976,13 @@ public class LensAdjustment { ...@@ -1969,13 +1976,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 +2014,7 @@ public class LensAdjustment { ...@@ -2007,7 +2014,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 +2034,7 @@ public class LensAdjustment { ...@@ -2027,7 +2034,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 +2086,12 @@ public class LensAdjustment { ...@@ -2079,12 +2086,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.
...@@ -17,7 +17,7 @@ import ij.IJ; ...@@ -17,7 +17,7 @@ import ij.IJ;
** Copyright (C) 2010-2011 Elphel, Inc. ** Copyright (C) 2010-2011 Elphel, Inc.
** **
** -----------------------------------------------------------------------------** ** -----------------------------------------------------------------------------**
** **
** SimulationPattern.java is free software: you can redistribute it and/or modify ** SimulationPattern.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
...@@ -35,11 +35,11 @@ import ij.IJ; ...@@ -35,11 +35,11 @@ import ij.IJ;
*/ */
public class SimulationPattern { public class SimulationPattern {
// private double [] bPattern; // pattern bitmap (does not change) // private double [] bPattern; // pattern bitmap (does not change)
// private double[][] barray; // high resolution boolean pattern array (specific to distortions in each area) // private double[][] barray; // high resolution boolean pattern array (specific to distortions in each area)
public double [] bPattern=null; // pattern bitmap (does not change) public double [] bPattern=null; // pattern bitmap (does not change)
public int bPatternSize=0; public int bPatternSize=0;
/// public double[][] barray; // high resolution boolean pattern array (specific to distortions in each area) /// public double[][] barray; // high resolution boolean pattern array (specific to distortions in each area)
public double[] barray; // high resolution boolean pattern array (specific to distortions in each area) public double[] barray; // high resolution boolean pattern array (specific to distortions in each area)
public double bPatternSigma=0.0; public double bPatternSigma=0.0;
public double barraySigma=0.0; public double barraySigma=0.0;
...@@ -55,15 +55,15 @@ public class SimulationPattern { ...@@ -55,15 +55,15 @@ public class SimulationPattern {
} }
public SimulationPattern( public SimulationPattern(
SimulParameters simulParameters ) { SimulParameters simulParameters ) {
this.bPatternSigma=simulParameters.bPatternSigma; this.bPatternSigma=simulParameters.bPatternSigma;
this.barraySigma=simulParameters.barraySigma; this.barraySigma=simulParameters.barraySigma;
patternGenerator(simulParameters); patternGenerator(simulParameters);
} }
public SimulationPattern( public SimulationPattern(
int size, int size,
int patternNumber, int patternNumber,
double patternModifier) { double patternModifier) {
patternGenerator(size,patternNumber,patternModifier); patternGenerator(size,patternNumber,patternModifier);
} }
/* ======================================================================== */ /* ======================================================================== */
public double [] patternGenerator( public double [] patternGenerator(
...@@ -116,10 +116,10 @@ public class SimulationPattern { ...@@ -116,10 +116,10 @@ public class SimulationPattern {
break; break;
default: for (index=0;index<this.bPattern.length;index++) this.bPattern[index]=1.0; default: for (index=0;index<this.bPattern.length;index++) this.bPattern[index]=1.0;
} }
// blur pattern // blur pattern
if (this.bPatternSigma>0) { if (this.bPatternSigma>0) {
if (this.bPatternSigma>0.25) this.bPatternSigma=0.25; if (this.bPatternSigma>0.25) this.bPatternSigma=0.25;
// 1 - add margins around the pattern // 1 - add margins around the pattern
int i1,j1; int i1,j1;
int margin= (int) Math.ceil(3*size*this.bPatternSigma); int margin= (int) Math.ceil(3*size*this.bPatternSigma);
int sizeM=size+2*margin; int sizeM=size+2*margin;
...@@ -134,11 +134,11 @@ public class SimulationPattern { ...@@ -134,11 +134,11 @@ public class SimulationPattern {
bPatternM[i*sizeM+j]= (invertX ^ invertY)?(1.0-this.bPattern[i1*size+j1]):this.bPattern[i1*size+j1]; bPatternM[i*sizeM+j]= (invertX ^ invertY)?(1.0-this.bPattern[i1*size+j1]):this.bPattern[i1*size+j1];
} }
} }
// apply blur // apply blur
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(bPatternM,sizeM,sizeM, "bPatternM"); if (this.debugLevel>3) SDFA_INSTANCE.showArrays(bPatternM,sizeM,sizeM, "bPatternM");
this.gb.blurDouble(bPatternM,sizeM,sizeM,size*this.bPatternSigma,size*this.bPatternSigma, 0.01); this.gb.blurDouble(bPatternM,sizeM,sizeM,size*this.bPatternSigma,size*this.bPatternSigma, 0.01);
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(bPatternM,sizeM,sizeM, "bPatternM-blured"); if (this.debugLevel>3) SDFA_INSTANCE.showArrays(bPatternM,sizeM,sizeM, "bPatternM-blured");
// remove margins // remove margins
for (i=0;i<size;i++) for (j=0;j<size;j++) { for (i=0;i<size;i++) for (j=0;j<size;j++) {
this.bPattern[i*size+j]= bPatternM[(i+margin)*sizeM+(j+margin)]; this.bPattern[i*size+j]= bPatternM[(i+margin)*sizeM+(j+margin)];
} }
...@@ -146,7 +146,7 @@ public class SimulationPattern { ...@@ -146,7 +146,7 @@ public class SimulationPattern {
return this.bPattern; return this.bPattern;
} }
/* ======================================================================== */ /* ======================================================================== */
public void simulatePatternFullPattern( public void simulatePatternFullPattern(
double freqX1, double freqX1,
double freqY1, double freqY1,
...@@ -157,7 +157,8 @@ public class SimulationPattern { ...@@ -157,7 +157,8 @@ public class SimulationPattern {
double [] corr, double [] corr,
int subdiv, int subdiv,
int size, int size,
boolean center_for_g2) { boolean center_for_g2,
boolean mono) {// takes precedence over center_for_g2, makes symmetrical around center of array (between pixels)
this.barray=simulatePatternFullPatternSafe( this.barray=simulatePatternFullPatternSafe(
freqX1, freqX1,
freqY1, freqY1,
...@@ -168,10 +169,12 @@ public class SimulationPattern { ...@@ -168,10 +169,12 @@ public class SimulationPattern {
corr, corr,
subdiv, subdiv,
size, size,
center_for_g2); center_for_g2,
mono);
} }
public double [] simulatePatternFullPatternSafe( public double [] simulatePatternFullPatternSafe(
double freqX1, double freqX1,
double freqY1, double freqY1,
...@@ -182,7 +185,8 @@ public class SimulationPattern { ...@@ -182,7 +185,8 @@ public class SimulationPattern {
double [] corr, double [] corr,
int subdiv, int subdiv,
int size, int size,
boolean center_for_g2) { boolean center_for_g2,
boolean mono) {// takes precedence over center_for_g2, makes symmetrical around center of array (between pixels)
int patternSize= (this.bPattern!=null)?((int) Math.sqrt(this.bPattern.length)):0; int patternSize= (this.bPattern!=null)?((int) Math.sqrt(this.bPattern.length)):0;
double twicePatternSize=2*patternSize; double twicePatternSize=2*patternSize;
int i,j; int i,j;
...@@ -211,12 +215,16 @@ public class SimulationPattern { ...@@ -211,12 +215,16 @@ public class SimulationPattern {
double [] phases={phase1/(Math.PI*2)+0.25,phase2/(Math.PI*2)+0.25}; // period=1.0; double [] phases={phase1/(Math.PI*2)+0.25,phase2/(Math.PI*2)+0.25}; // period=1.0;
int iu,iv; int iu,iv;
boolean invert; boolean invert;
for (i=0;i<fullSize;i++) {
yl=(i-0.5*fullSize)/subdiv-(center_for_g2?0.5:1.0); // center in the middle of Bayer
for (j=0;j<fullSize;j++) {
xl=(j-0.5*fullSize)/subdiv-(center_for_g2?0.5:1.0); // center in the middle of Bayer
/* apply second order polynomial correction to x,y double offset = mono? 0.0: ((center_for_g2?0.5:1.0));
double center = 0.5*fullSize; // +(mono?-0.5: 0.0); // see if it is needed!
// in mono mode result barray is symmetrical around [fullSize/2,fullSize/2], but
// after extractSimulMono result will be symmetrical around [size/2-0.5, size/2 - 0.5]
for (i=0; i<fullSize; i++) {
yl=(i - center) / subdiv - offset; // center in the middle of Bayer
for (j=0; j<fullSize; j++) {
xl=(j - center) / subdiv - offset; // center in the middle of Bayer
/* apply second order polynomial correction to x,y
x=xl+Ax*xl^2+Bx*yl^2+2*Cx*xl*yl; x=xl+Ax*xl^2+Bx*yl^2+2*Cx*xl*yl;
y=xl+Ay*xl^2+By*yl^2+2*Cy*xl*yl; */ y=xl+Ay*xl^2+By*yl^2+2*Cy*xl*yl; */
if (corr==null) { if (corr==null) {
...@@ -256,31 +264,31 @@ public class SimulationPattern { ...@@ -256,31 +264,31 @@ public class SimulationPattern {
} }
} }
} }
// Blur barray pattern if sigma >0 // Blur barray pattern if sigma >0
if (this.barraySigma>0) { if (this.barraySigma>0) {
double sigma=this.barraySigma*subdiv; //*/ 2? double sigma=this.barraySigma*subdiv; //*/ 2?
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(localBarray, "localBarray"); if (this.debugLevel>3) SDFA_INSTANCE.showArrays(localBarray, "localBarray");
this.gb.blurDouble(localBarray,fullSize,fullSize,sigma,sigma, 0.01); this.gb.blurDouble(localBarray,fullSize,fullSize,sigma,sigma, 0.01);
if (this.debugLevel>3) SDFA_INSTANCE.showArrays(localBarray, "localBarray-blured"); if (this.debugLevel>3) SDFA_INSTANCE.showArrays(localBarray, "localBarray-blured");
} }
return localBarray; return localBarray;
} }
/* ======================================================================== */ /* ======================================================================== */
public double [] recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1) public double [] recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
SimulParameters simulParameters, SimulParameters simulParameters,
double [] xy, // top-left corner double [] xy, // top-left corner
double [] dxy, // increments to other corners double [] dxy, // increments to other corners
double [][][] cornersXY, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1) double [][][] cornersXY, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
double [] uv, // UV value for the top-left corner (matching cornersXY[0][0]) double [] uv, // UV value for the top-left corner (matching cornersXY[0][0])
double [] duv, // distances to the opposite corner in UV double [] duv, // distances to the opposite corner in UV
// final boolean maskOnly, // just mark defined cells // final boolean maskOnly, // just mark defined cells
int debug int debug
){ //use this.bPattern, this.bPatternSize (side of the square) ){ //use this.bPattern, this.bPatternSize (side of the square)
double [][][] cornersUV=new double [2][2][]; double [][][] cornersUV=new double [2][2][];
double [] xy4=new double[2]; double [] xy4=new double[2];
double [] result ={0.0,0.0}; double [] result ={0.0,0.0};
int numInside=0; int numInside=0;
for (int i=0;i<2;i++) for (int j=0;j<2;j++) { for (int i=0;i<2;i++) for (int j=0;j<2;j++) {
xy4[0]=xy[0]+j*dxy[0]; xy4[0]=xy[0]+j*dxy[0];
xy4[1]=xy[1]+i*dxy[1]; xy4[1]=xy[1]+i*dxy[1];
...@@ -289,7 +297,7 @@ public class SimulationPattern { ...@@ -289,7 +297,7 @@ public class SimulationPattern {
} }
if (debug>21){ if (debug>21){
String dbgStr=""; String dbgStr="";
// IJ.d2s(quarter_patterns[iq][0][0],4) // IJ.d2s(quarter_patterns[iq][0][0],4)
dbgStr+="xy={"+IJ.d2s(xy[0],2)+","+IJ.d2s(xy[1],2)+"} "; dbgStr+="xy={"+IJ.d2s(xy[0],2)+","+IJ.d2s(xy[1],2)+"} ";
dbgStr+=" dxy={"+IJ.d2s(dxy[0],2)+","+IJ.d2s(dxy[1],2)+"} "; dbgStr+=" dxy={"+IJ.d2s(dxy[0],2)+","+IJ.d2s(dxy[1],2)+"} ";
dbgStr+=" uv={"+IJ.d2s(uv[0],2)+","+IJ.d2s(uv[1],2)+"} "; dbgStr+=" uv={"+IJ.d2s(uv[0],2)+","+IJ.d2s(uv[1],2)+"} ";
...@@ -307,25 +315,25 @@ public class SimulationPattern { ...@@ -307,25 +315,25 @@ public class SimulationPattern {
} }
if (numInside==0) return result; // all corners outside of the (sub)pattern cell if (numInside==0) return result; // all corners outside of the (sub)pattern cell
// if (maskOnly) { // if (maskOnly) {
if (simulParameters==null) { if (simulParameters==null) {
result[1]=dxy[0]*dxy[1]; result[1]=dxy[0]*dxy[1];
result[0]=result[1]; result[0]=result[1];
return result; return result;
} }
// recalculate to the full uv // recalculate to the full uv
boolean cornersInvert; boolean cornersInvert;
double [][] cornerValue=new double [2][2]; double [][] cornerValue=new double [2][2];
int [] iPat=new int [2]; int [] iPat=new int [2];
double min=1.0,max=-1.0; double min=1.0,max=-1.0;
for (int i=0;i<2;i++) for (int j=0;j<2;j++) { for (int i=0;i<2;i++) for (int j=0;j<2;j++) {
// cornersUV[i][j][0]=uv[0]+j*cornersUV[i][j][0]*duv[0]; // cornersUV[i][j][0]=uv[0]+j*cornersUV[i][j][0]*duv[0];
// cornersUV[i][j][1]=uv[1]+i*cornersUV[i][j][1]*duv[1]; // cornersUV[i][j][1]=uv[1]+i*cornersUV[i][j][1]*duv[1];
cornersUV[i][j][0]=uv[0]+cornersUV[i][j][0]*duv[0]; cornersUV[i][j][0]=uv[0]+cornersUV[i][j][0]*duv[0];
cornersUV[i][j][1]=uv[1]+cornersUV[i][j][1]*duv[1]; cornersUV[i][j][1]=uv[1]+cornersUV[i][j][1]*duv[1];
cornersInvert=false; cornersInvert=false;
for (int k=0;k<2;k++) { for (int k=0;k<2;k++) {
// iPat[k] = (int) Math.floor(cornersUV[i][j][k]*this.bPatternSize*2.0); // 0.5 ->bPatternSize // iPat[k] = (int) Math.floor(cornersUV[i][j][k]*this.bPatternSize*2.0); // 0.5 ->bPatternSize
iPat[k] = (int) Math.floor(cornersUV[i][j][k]*this.bPatternSize); // 1.0 ->bPatternSize iPat[k] = (int) Math.floor(cornersUV[i][j][k]*this.bPatternSize); // 1.0 ->bPatternSize
if (iPat[k]<0){ if (iPat[k]<0){
iPat[k]+=this.bPatternSize; iPat[k]+=this.bPatternSize;
...@@ -343,11 +351,11 @@ public class SimulationPattern { ...@@ -343,11 +351,11 @@ public class SimulationPattern {
if (max<cornerValue[i][j]) max=cornerValue[i][j]; if (max<cornerValue[i][j]) max=cornerValue[i][j];
if (min>cornerValue[i][j]) min=cornerValue[i][j]; if (min>cornerValue[i][j]) min=cornerValue[i][j];
} }
if (((max-min)>simulParameters.bitmapNonuniforityThreshold) && if (((max-min)>simulParameters.bitmapNonuniforityThreshold) &&
(dxy[0]>simulParameters.smallestSubPix) && (dxy[0]>simulParameters.smallestSubPix) &&
(dxy[1]>simulParameters.smallestSubPix)) { (dxy[1]>simulParameters.smallestSubPix)) {
// divide this square into 4 quadrants, return sum of the recursively called method on them // divide this square into 4 quadrants, return sum of the recursively called method on them
double [][] quadrants={{0.0,0.0},{0.5,0.0},{0.0,0.5},{0.5,0.5}}; double [][] quadrants={{0.0,0.0},{0.5,0.0},{0.0,0.5},{0.5,0.5}};
double [] subResult; double [] subResult;
double [] subxy=new double [2]; double [] subxy=new double [2];
...@@ -356,28 +364,28 @@ public class SimulationPattern { ...@@ -356,28 +364,28 @@ public class SimulationPattern {
System.out.println("---> Subdividing into "+subdxy[0]+"x"+subdxy[0]+" (max="+IJ.d2s(max,3)+" min="+IJ.d2s(min,3)+ System.out.println("---> Subdividing into "+subdxy[0]+"x"+subdxy[0]+" (max="+IJ.d2s(max,3)+" min="+IJ.d2s(min,3)+
" max-min="+IJ.d2s(max-min,3)+ " max-min="+IJ.d2s(max-min,3)+
" cornerValue: [0][0]="+IJ.d2s(cornerValue[0][0],3)+ " cornerValue: [0][0]="+IJ.d2s(cornerValue[0][0],3)+
" [0][1]="+IJ.d2s(cornerValue[0][1],3)+ " [0][1]="+IJ.d2s(cornerValue[0][1],3)+
" [1][0]="+IJ.d2s(cornerValue[1][0],3)+ " [1][0]="+IJ.d2s(cornerValue[1][0],3)+
" [1][1]="+IJ.d2s(cornerValue[1][1],3)+ " [1][1]="+IJ.d2s(cornerValue[1][1],3)+
" cornersUV={{{"+IJ.d2s(cornersUV[0][0][0],3)+","+IJ.d2s(cornersUV[0][0][1],3)+"},"+ " cornersUV={{{"+IJ.d2s(cornersUV[0][0][0],3)+","+IJ.d2s(cornersUV[0][0][1],3)+"},"+
"{"+IJ.d2s(cornersUV[0][1][0],3)+","+IJ.d2s(cornersUV[0][1][1],3)+"}},"+ "{"+IJ.d2s(cornersUV[0][1][0],3)+","+IJ.d2s(cornersUV[0][1][1],3)+"}},"+
"{{"+IJ.d2s(cornersUV[1][0][0],3)+","+IJ.d2s(cornersUV[1][0][1],3)+"},"+ "{{"+IJ.d2s(cornersUV[1][0][0],3)+","+IJ.d2s(cornersUV[1][0][1],3)+"},"+
"{"+IJ.d2s(cornersUV[1][1][0],3)+","+IJ.d2s(cornersUV[1][1][1],3)+"}}}"); "{"+IJ.d2s(cornersUV[1][1][0],3)+","+IJ.d2s(cornersUV[1][1][1],3)+"}}}");
} }
for (int i=0;i<quadrants.length;i++) { for (int i=0;i<quadrants.length;i++) {
subxy[0]=xy[0]+dxy[0]*quadrants[i][0]; subxy[0]=xy[0]+dxy[0]*quadrants[i][0];
subxy[1]=xy[1]+dxy[1]*quadrants[i][1]; subxy[1]=xy[1]+dxy[1]*quadrants[i][1];
subResult= recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1) subResult= recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
simulParameters, simulParameters,
subxy, // top-left corner subxy, // top-left corner
subdxy, // increments to other corners subdxy, // increments to other corners
cornersXY, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1) cornersXY, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
uv, // UV value for the top-left corner (matching cornersXY[0][0]) uv, // UV value for the top-left corner (matching cornersXY[0][0])
duv, // distances to the opposite corner in UV duv, // distances to the opposite corner in UV
// maskOnly, // just mark defined cells //always false - will never get here // maskOnly, // just mark defined cells //always false - will never get here
debug debug
); );
result[0]+=subResult[0]; result[0]+=subResult[0];
result[1]+=subResult[1]; result[1]+=subResult[1];
} }
...@@ -391,7 +399,7 @@ public class SimulationPattern { ...@@ -391,7 +399,7 @@ public class SimulationPattern {
result[1]=dxy[0]*dxy[1]; result[1]=dxy[0]*dxy[1];
result[0]*=result[1]; result[0]*=result[1];
if (numInside <4) { if (numInside <4) {
double f=((double) numInside)/4; // estimate fraction of the pixel - start with simple number of corners double f=((double) numInside)/4; // estimate fraction of the pixel - start with simple number of corners
result[0]*=f; result[0]*=f;
result[1]*=f; result[1]*=f;
} }
...@@ -402,7 +410,7 @@ public class SimulationPattern { ...@@ -402,7 +410,7 @@ public class SimulationPattern {
} }
return result; return result;
} }
/* ======================================================================== */ /* ======================================================================== */
/** /**
* @param cornersXY first index V, second index U, third index:0 - x, 1-y * @param cornersXY first index V, second index U, third index:0 - x, 1-y
* @param xy 0-x,1-y of the point, for which UV should be generated * @param xy 0-x,1-y of the point, for which UV should be generated
...@@ -411,7 +419,7 @@ public class SimulationPattern { ...@@ -411,7 +419,7 @@ public class SimulationPattern {
public double [] bilinearXY2UV( public double [] bilinearXY2UV(
double [][][] cornersXY, // first index V, second index U, third index:0 - x, 1-y double [][][] cornersXY, // first index V, second index U, third index:0 - x, 1-y
double [] xy, // 0-x,1-y of the point, for which double [] xy, // 0-x,1-y of the point, for which
int debug int debug
) { ) {
return bilinearXY2UV( return bilinearXY2UV(
cornersXY, // first index V, second index U, third index:0 - x, 1-y cornersXY, // first index V, second index U, third index:0 - x, 1-y
...@@ -429,9 +437,9 @@ public class SimulationPattern { ...@@ -429,9 +437,9 @@ public class SimulationPattern {
double [][][] cornersXY, // first index V, second index U, third index:0 - x, 1-y double [][][] cornersXY, // first index V, second index U, third index:0 - x, 1-y
double [] xy, // 0-x,1-y of the point, for which double [] xy, // 0-x,1-y of the point, for which
double quadThreshold, // if abs(4*a*c)/b^2 is less than this, use linear, not quadratic equations double quadThreshold, // if abs(4*a*c)/b^2 is less than this, use linear, not quadratic equations
int debug int debug
) { ) {
/* /*
x,y -> u,v x,y -> u,v
(1) x= v*u*Ax + v*Bx + u*Cx + Dx (1) x= v*u*Ax + v*Bx + u*Cx + Dx
...@@ -460,8 +468,8 @@ Av=(By*Ax-Bx*Ay) ...@@ -460,8 +468,8 @@ Av=(By*Ax-Bx*Ay)
Bv=((-Bx*Cy-Ay*Dx+By*Cx+Ax*Dy)+Ay*x-Ax*y) Bv=((-Bx*Cy-Ay*Dx+By*Cx+Ax*Dy)+Ay*x-Ax*y)
Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
*/ */
double Ax=cornersXY[1][1][0]-cornersXY[1][0][0]-cornersXY[0][1][0]+cornersXY[0][0][0]; double Ax=cornersXY[1][1][0]-cornersXY[1][0][0]-cornersXY[0][1][0]+cornersXY[0][0][0];
double Bx=cornersXY[1][0][0]-cornersXY[0][0][0]; double Bx=cornersXY[1][0][0]-cornersXY[0][0][0];
double Cx=cornersXY[0][1][0]-cornersXY[0][0][0]; double Cx=cornersXY[0][1][0]-cornersXY[0][0][0];
...@@ -479,26 +487,26 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -479,26 +487,26 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
double Av=(By*Ax-Bx*Ay); double Av=(By*Ax-Bx*Ay);
double Bv=((-Bx*Cy-Ay*Dx+By*Cx+Ax*Dy)+Ay*xy[0]-Ax*xy[1]); double Bv=((-Bx*Cy-Ay*Dx+By*Cx+Ax*Dy)+Ay*xy[0]-Ax*xy[1]);
double Cv=(Cy*xy[0]-Cx*xy[1])+(-Cy*Dx+Cx*Dy); double Cv=(Cy*xy[0]-Cx*xy[1])+(-Cy*Dx+Cx*Dy);
// double [] UV={-Cv/Bv,-Cu/Bu}; // linear solution - use for linear grid // double [] UV={-Cv/Bv,-Cu/Bu}; // linear solution - use for linear grid
double [] UV={-Cu/Bu,-Cv/Bv}; // linear solution - use for linear grid double [] UV={-Cu/Bu,-Cv/Bv}; // linear solution - use for linear grid
double au=0.0,bu=0.0,av=0.0,bv=0.0; double au=0.0,bu=0.0,av=0.0,bv=0.0;
if (Math.abs(Au*Cu)/(Bu*Bu)>quadThreshold) { // use quadratic equation for U if (Math.abs(Au*Cu)/(Bu*Bu)>quadThreshold) { // use quadratic equation for U
au=-Bu/(2*Au); au=-Bu/(2*Au);
bu=Math.sqrt(Bu*Bu-4*Au*Cu)/Math.abs(2*Au); bu=Math.sqrt(Bu*Bu-4*Au*Cu)/Math.abs(2*Au);
// Use solution that is closer to linear one // Use solution that is closer to linear one
if (UV[0]>au) UV[0]=au+bu; if (UV[0]>au) UV[0]=au+bu;
else UV[0]=au-bu; else UV[0]=au-bu;
} }
if (Math.abs(Av*Cv)/(Bv*Bv)>quadThreshold) { // use quadratic equation for V if (Math.abs(Av*Cv)/(Bv*Bv)>quadThreshold) { // use quadratic equation for V
av=-Bv/(2*Av); av=-Bv/(2*Av);
bv=Math.sqrt(Bv*Bv-4*Av*Cv)/Math.abs(2*Av); bv=Math.sqrt(Bv*Bv-4*Av*Cv)/Math.abs(2*Av);
// Use solution that is closer to linear one // Use solution that is closer to linear one
if (UV[1]>av) UV[1]=av+bv; if (UV[1]>av) UV[1]=av+bv;
else UV[1]=av-bv; else UV[1]=av-bv;
} }
if (debug>2){ if (debug>2){
String dbgStr=""; String dbgStr="";
// IJ.d2s(quarter_patterns[iq][0][0],4) // IJ.d2s(quarter_patterns[iq][0][0],4)
dbgStr+=" Ax="+IJ.d2s(Ax,5)+", Bx="+IJ.d2s(Bx,5)+", Cx="+IJ.d2s(Cx,5)+", Dx="+IJ.d2s(Dx,5); dbgStr+=" Ax="+IJ.d2s(Ax,5)+", Bx="+IJ.d2s(Bx,5)+", Cx="+IJ.d2s(Cx,5)+", Dx="+IJ.d2s(Dx,5);
dbgStr+=" Ay="+IJ.d2s(Ay,5)+", By="+IJ.d2s(By,5)+", Cy="+IJ.d2s(Cy,5)+", Dy="+IJ.d2s(Dy,5); dbgStr+=" Ay="+IJ.d2s(Ay,5)+", By="+IJ.d2s(By,5)+", Cy="+IJ.d2s(Cy,5)+", Dy="+IJ.d2s(Dy,5);
dbgStr+=" Au="+IJ.d2s(Au,5)+", Bu="+IJ.d2s(Bu,5)+", Cu="+IJ.d2s(Cu,5); dbgStr+=" Au="+IJ.d2s(Au,5)+", Bu="+IJ.d2s(Bu,5)+", Cu="+IJ.d2s(Cu,5);
...@@ -511,388 +519,390 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -511,388 +519,390 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
return UV; return UV;
} }
/* ======================================================================== */ /* ======================================================================== */
private boolean isCellValid( private boolean isCellValid(
double [][][][] grid, double [][][][] grid,
int [] uv){ int [] uv){
if ((uv[1]>=0) && (uv[0]>=0) && (uv[1]<grid.length) && (uv[0]<grid[uv[1]].length)) { if ((uv[1]>=0) && (uv[0]>=0) && (uv[1]<grid.length) && (uv[0]<grid[uv[1]].length)) {
double [][] cell = grid[uv[1]][uv[0]]; double [][] cell = grid[uv[1]][uv[0]];
return ((cell!=null) && (cell.length>1)); return ((cell!=null) && (cell.length>1));
} }
return false; return false;
} }
/* /*
private boolean isCellDefined( private boolean isCellDefined(
double [][][][] grid, double [][][][] grid,
int [] uv){ int [] uv){
return ((uv[1]>=0) && (uv[0]>=0) && (uv[1]<grid.length) && (uv[0]<grid[uv[1]].length) && return ((uv[1]>=0) && (uv[0]>=0) && (uv[1]<grid.length) && (uv[0]<grid[uv[1]].length) &&
(grid[uv[1]][uv[0]]!=null) && (grid[uv[1]][uv[0]][0]!=null)); (grid[uv[1]][uv[0]]!=null) && (grid[uv[1]][uv[0]][0]!=null));
} }
*/ */
public float [] combineWithCanvas( public float [] combineWithCanvas(
double canvasFill, double canvasFill,
int width, int width,
int height, int height,
Rectangle woi, Rectangle woi,
float [] selection ){ float [] selection ){
float []canvas=new float[width*height]; float []canvas=new float[width*height];
for (int i=0;i<canvas.length;i++)canvas[i]= (float) canvasFill; for (int i=0;i<canvas.length;i++)canvas[i]= (float) canvasFill;
return combineWithCanvas(canvas, width, woi, selection ); return combineWithCanvas(canvas, width, woi, selection );
} }
public float [] combineWithCanvas( public float [] combineWithCanvas(
float [] canvas, float [] canvas,
int width, int width,
Rectangle woi, Rectangle woi,
float [] selection ){ float [] selection ){
// debug // debug
if (selection==null) System.out.println("combineWithCanvas(): selection==null"); if (selection==null) System.out.println("combineWithCanvas(): selection==null");
if (woi==null) System.out.println("combineWithCanvas(): woi==null"); if (woi==null) System.out.println("combineWithCanvas(): woi==null");
if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height); if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height);
int i0=0; int i0=0;
int i1=width*woi.y+woi.x; int i1=width*woi.y+woi.x;
for (int y=0;y<woi.height;y++){ for (int y=0;y<woi.height;y++){
for (int x=0;x<woi.width;x++){ for (int x=0;x<woi.width;x++){
if ((i1>canvas.length) ||(i0>=selection.length)){ if ((i1>canvas.length) ||(i0>=selection.length)){
System.out.println("canvas.length="+canvas.length+" width="+width+" selection.length="+selection.length+" y="+y+" x="+x+" i0="+i0+" i1="+i1+ System.out.println("canvas.length="+canvas.length+" width="+width+" selection.length="+selection.length+" y="+y+" x="+x+" i0="+i0+" i1="+i1+
" woi.x="+woi.x+" woi.y="+woi.y+" woi.width="+woi.width+" woi.height="+woi.height); " woi.x="+woi.x+" woi.y="+woi.y+" woi.width="+woi.width+" woi.height="+woi.height);
} }
canvas[i1++]=selection[i0++]; // OOB 18720 canvas[i1++]=selection[i0++]; // OOB 18720
}
i1+=(width-woi.width);
}
return canvas;
}
public double [] combineWithCanvas(
double canvasFill,
int width,
int height,
Rectangle woi,
double [] selection ){
double []canvas=new double[width*height];
for (int i=0;i<canvas.length;i++)canvas[i]= canvasFill;
return combineWithCanvas(canvas, width, woi, selection );
}
public double [] combineWithCanvas(
double [] canvas,
int width,
Rectangle woi,
double [] selection ){
if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height);
int i0=0;
int i1=width*woi.y+woi.x;
for (int y=0;y<woi.height;y++){
for (int x=0;x<woi.width;x++) canvas[i1++]=selection[i0++];
i1+=(width-woi.width);
}
return canvas;
}
//===================== Moved from Aberration_Calibration
public float[][] simulateGridAll (
int width, // extend to full image, width, height - original (not scaled) image size
int height,
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulParameters simulParameters,
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
// SimulationPattern simulationPattern=new SimulationPattern(simulParameters);
float [][] simArray0=simulateGridAll (
matchSimulatedPattern,
// patternGrid, // should be aligned to gridFrac
gridFrac, // number of grid steps per pattern full period
simulParameters,
// simulationPattern,
threadsMax,
updateStatus,
globalDebugLevel,
debug_level);
Rectangle woi=matchSimulatedPattern.getWOI();
if ((woi.x==0) && (woi.y==0) && (woi.width==width) && (woi.height==height)) return simArray0;
int k=simulParameters.subdiv/2;
Rectangle scaledWoi=new Rectangle(k*woi.x, k*woi.y, k*woi.width, k*woi.height);
float [][] simArray=new float [2][];
simArray[0]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[0]);
simArray[1]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[1]);
if (globalDebugLevel>1) SDFA_INSTANCE.showArrays(simArray,width*k,height*k,true, "full-simulation");
return simArray;
}
public float[][] simulateGridAll (
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulationPattern.SimulParameters simulParameters,
// SimulationPattern simulationPattern, // or null
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
long startTime=System.nanoTime();
double [][] xy0={{simulParameters.offsetX,simulParameters.offsetY},{simulParameters.offsetX-0.5,simulParameters.offsetY-0.5}} ;
// if (simulationPattern==null) simulationPattern=new SimulationPattern(simulParameters);
float[][] simArray=new float[2][];
simArray[0]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[0], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
simArray[1]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[1], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simArray,matchSimulatedPattern.getWOI().width*simulParameters.subdiv/2,matchSimulatedPattern.getWOI().height*simulParameters.subdiv/2,true, "a-simulation");
if (globalDebugLevel>1) System.out.println("Grid simulation is finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return simArray;
}
//========================
public float [] simulateGrid (
final double [][][][] patternGrid, // should be aligned to gridFrac
final int gridFrac, // number of grid steps per pattern full period: black+white
final SimulParameters simulParameters, // Try to use null here for maskOnly
final Rectangle woi,
final int subdiv, // subdivide output array from woi (normally 2)
double[] shift_xy, // add to patterGrid xy, null OK
// final boolean maskOnly, // just mark defined cells
final int threadsMax,
final boolean updateStatus,
final int debug_level){// debug level used inside loops
double []xy_zero={0.0,0.0};
if (patternGrid==null) return null;
final double [] xy0=(shift_xy==null)?xy_zero:shift_xy;
if ((simulParameters!=null) && (this.bPattern==null)){
System.out.println("simulateGrid(), running patternGenerator(simulParameters )");
patternGenerator(simulParameters ); // generate bPattern if it was not done yet
}
final Rectangle woiOut=new Rectangle(subdiv*woi.x,subdiv*woi.y,subdiv*woi.width,subdiv*woi.height);
final float [] pixels=new float[woiOut.width*woiOut.height];
final float [] pixelsDenom=new float[woiOut.width*woiOut.height];
for (int i=0;i<pixels.length;i++ ){
pixels[i]= 0.0F;
pixelsDenom[i]= 0.0F;
}
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger cellNum = new AtomicInteger(0);
final int [] series = new int[1];
final int uvhwidth=(patternGrid[0].length+1)/2;
final int uvwidth= patternGrid[0].length;
final int uvhheight=(patternGrid.length+1)/2;
final int numInSeries=(uvhwidth-1)*(uvhheight-1);
final AtomicInteger debugCellNum = new AtomicInteger(0);
final AtomicInteger finishedAtomic = new AtomicInteger(1);
final int cellsToProcess=numInSeries*4;
final int debugCellNum0=0;
IJ.showStatus("Generating simulated pattern...");
for (series[0]=0;series[0]<4;series[0]++) { // split processing in 4 series (odd/even row/column to avoid races between threads
if (debug_level>2)System.out.println("**** series[0]="+series[0]);
cellNum.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
public void run() {
// String dbgStr="";
int [][][] iUV=new int [2][2][2];
double [][][] dUV=new double [2][2][2];
double [][][] xy=new double [2][2][2];
boolean invPattern;
double [] pixDXY={1.0,1.0};
for (int ncell=cellNum.getAndIncrement(); ncell<numInSeries;ncell=cellNum.getAndIncrement()){
iUV[0][0][0]=2*(ncell%(uvhwidth-1))+ (series[0] & 1);
iUV[0][0][1]=2*(ncell/(uvhwidth-1))+ ((series[0]>>1) & 1);
if ((updateStatus) && (debugLevel>1)) IJ.showStatus("Generating simulated pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
if (debugLevel>2) System.out.println("Generating pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
iUV[0][1][0]=iUV[0][0][0]+1;
iUV[0][1][1]=iUV[0][0][1];
iUV[1][0][0]=iUV[0][0][0];
iUV[1][0][1]=iUV[0][0][1]+1;
iUV[1][1][0]=iUV[0][0][0]+1;
iUV[1][1][1]=iUV[0][0][1]+1;
if ((isCellValid(patternGrid,iUV[0][0])) &&
(isCellValid(patternGrid,iUV[0][1])) &&
(isCellValid(patternGrid,iUV[1][0])) &&
(isCellValid(patternGrid,iUV[1][1]))){
// All 4 corners are valid
invPattern=((iUV[0][0][0]%gridFrac)>=(gridFrac/2))^((iUV[0][0][1]%gridFrac)>=(gridFrac/2));
if (debug_level>2)System.out.println("iUV[0][0][1]="+iUV[0][0][1]+" iUV[0][0][0]="+iUV[0][0][0]+" invert="+invPattern);
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
xy[i][j][k]=subdiv*patternGrid[iUV[i][j][1]][iUV[i][j][0]][0][k]+xy0[k];
}
for (int k=0;k<2;k++) {
dUV[0][0][k]=((double) (iUV[0][0][k]%(gridFrac/2)))/(gridFrac/2);
}
dUV[0][1][0]=dUV[0][0][0]+1.0/(gridFrac/2);
dUV[0][1][1]=dUV[0][0][1];
dUV[1][0][0]=dUV[0][0][0];
dUV[1][0][1]=dUV[0][0][1]+1.0/(gridFrac/2);
dUV[1][1][0]=dUV[0][1][0];
dUV[1][1][1]=dUV[1][0][1];
double [] minXY={xy[0][0][0],xy[0][0][1]};
double [] maxXY={xy[0][0][0],xy[0][0][1]};
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
if (minXY[k]>xy[i][j][k]) minXY[k]=xy[i][j][k];
if (maxXY[k]<xy[i][j][k]) maxXY[k]=xy[i][j][k];
}
Rectangle rcell=new Rectangle((int)minXY[0], // contains all pixels
(int)minXY[1],
((int) Math.ceil(maxXY[0]))-((int)minXY[0]) ,
((int) Math.ceil(maxXY[1]))-((int)minXY[1]));
double [] cornersDUV={1.0/(gridFrac/2),1.0/(gridFrac/2)};
boolean debugNow=debugCellNum.getAndIncrement()==debugCellNum0;
if (woiOut.intersects (rcell)) // do not bother if no
for (int iy=rcell.y;iy<(rcell.y+rcell.height);iy++) for (int ix=rcell.x;ix<(rcell.x+rcell.width);ix++)
if (woiOut.contains (ix,iy))
{
double [] pixXY={(double) ix,(double) iy};
double [] pixData=recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
simulParameters,
pixXY, // top-left corner
pixDXY, // increments to other corners
xy, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
dUV[0][0], // UV value for the top-left corner (matching cornersXY[0][0])
cornersDUV, // distances to the opposite corner in UV
// maskOnly, // just mark defined cells
debugNow?debug_level: debug_level-2
);
// int index=woiOut.width*iy+ix;
int index=woiOut.width*(iy-woiOut.y)+(ix-woiOut.x);
// pixels[index]+=((invPattern || maskOnly)?1.0:-1.0)*pixData[0];
if (index>pixels.length){
// final float [] pixels=new float[woiOut.width*woiOut.height];
System.out.println("simulateGrid(), pixels.length="+pixels.length+
" index="+index+
" iy="+iy+" ix="+ix+
" ncell="+ncell+
" subdiv="+subdiv+
" woiOut.x="+woiOut.x+
" woiOut.y="+woiOut.y+
" woiOut.width="+woiOut.width+
" woiOut.height="+woiOut.height+
" woi.x="+woi.x+
" woi.y="+woi.y+
" woi.width="+woi.width+
" woi.height="+woi.height+
" rcell.x="+rcell.x+
" rcell.y="+rcell.y+
" rcell.width="+rcell.width+
" rcell.height="+rcell.height);
}
// if (maskOnly) pixels[index]=patternGrid.length*iUV[0][0][1]+iUV[0][0][0]; // out of bounds
// OLD NASTY BUG!
// if (maskOnly) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
if (simulParameters==null) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
else pixels[index]+=(invPattern?1.0:-1.0)*pixData[0];
pixelsDenom[index]+=pixData[1];
}
}
final int numFinished=finishedAtomic.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() {
public void run() {
IJ.showProgress(numFinished,cellsToProcess);
}
});
}
}
};
}
startAndJoin(threads);
} }
for (int i=0;i<pixels.length;i++ ) { i1+=(width-woi.width);
// /(simulParameters!=null) }
// if (maskOnly) { return canvas;
if (simulParameters==null) { }
if (pixelsDenom[i]==0.0F) pixels[i]=-1;
} else { public double [] combineWithCanvas(
if (pixelsDenom[i]!=0.0F){ double canvasFill,
pixels[i]/= pixelsDenom[i]; int width,
pixels[i]=(float) ((pixels[i]+1.0)/2); // convert from -1..+1 to 0..1.0 int height,
Rectangle woi,
double [] selection ){
double []canvas=new double[width*height];
for (int i=0;i<canvas.length;i++)canvas[i]= canvasFill;
return combineWithCanvas(canvas, width, woi, selection );
}
public double [] combineWithCanvas(
double [] canvas,
int width,
Rectangle woi,
double [] selection ){
if (selection.length!=(woi.width*woi.height)) throw new IllegalArgumentException ("selection.length="+selection.length+", woi.width="+woi.width+", woi.height="+woi.height);
int i0=0;
int i1=width*woi.y+woi.x;
for (int y=0;y<woi.height;y++){
for (int x=0;x<woi.width;x++) canvas[i1++]=selection[i0++];
i1+=(width-woi.width);
}
return canvas;
}
//===================== Moved from Aberration_Calibration
public float[][] simulateGridAll (
int width, // extend to full image, width, height - original (not scaled) image size
int height,
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulParameters simulParameters,
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
// SimulationPattern simulationPattern=new SimulationPattern(simulParameters);
float [][] simArray0=simulateGridAll (
matchSimulatedPattern,
// patternGrid, // should be aligned to gridFrac
gridFrac, // number of grid steps per pattern full period
simulParameters,
// simulationPattern,
threadsMax,
updateStatus,
globalDebugLevel,
debug_level);
Rectangle woi=matchSimulatedPattern.getWOI();
if ((woi.x==0) && (woi.y==0) && (woi.width==width) && (woi.height==height)) return simArray0;
int k=simulParameters.subdiv/2;
Rectangle scaledWoi=new Rectangle(k*woi.x, k*woi.y, k*woi.width, k*woi.height);
float [][] simArray=new float [2][];
simArray[0]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[0]);
simArray[1]=(new SimulationPattern(simulParameters)).combineWithCanvas(0.0, k*width, k*height, scaledWoi,simArray0[1]);
if (globalDebugLevel>1) SDFA_INSTANCE.showArrays(simArray,width*k,height*k,true, "full-simulation");
return simArray;
}
public float[][] simulateGridAll (
MatchSimulatedPattern matchSimulatedPattern,
// double [][][][] patternGrid, // should be aligned to gridFrac
int gridFrac, // number of grid steps per pattern full period
SimulationPattern.SimulParameters simulParameters,
// SimulationPattern simulationPattern, // or null
int threadsMax,
boolean updateStatus,
int globalDebugLevel,
int debug_level){// debug level used inside loops
long startTime=System.nanoTime();
double [][] xy0={{simulParameters.offsetX,simulParameters.offsetY},{simulParameters.offsetX-0.5,simulParameters.offsetY-0.5}} ;
// if (simulationPattern==null) simulationPattern=new SimulationPattern(simulParameters);
float[][] simArray=new float[2][];
simArray[0]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[0], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
simArray[1]= simulateGrid (
matchSimulatedPattern.getDArray(),
2, // gridFrac, // number of grid steps per pattern full period
simulParameters,
matchSimulatedPattern.getWOI(),
simulParameters.subdiv/2,
xy0[1], // add to patterGrid xy
threadsMax,
updateStatus,
debug_level); // debug level
if (globalDebugLevel>2) SDFA_INSTANCE.showArrays(simArray,matchSimulatedPattern.getWOI().width*simulParameters.subdiv/2,matchSimulatedPattern.getWOI().height*simulParameters.subdiv/2,true, "a-simulation");
if (globalDebugLevel>1) System.out.println("Grid simulation is finished at "+ IJ.d2s(0.000000001*(System.nanoTime()-startTime),3));
return simArray;
}
//========================
public float [] simulateGrid (
final double [][][][] patternGrid, // should be aligned to gridFrac
final int gridFrac, // number of grid steps per pattern full period: black+white
final SimulParameters simulParameters, // Try to use null here for maskOnly
final Rectangle woi,
final int subdiv, // subdivide output array from woi (normally 2)
double[] shift_xy, // add to patterGrid xy, null OK
// final boolean maskOnly, // just mark defined cells
final int threadsMax,
final boolean updateStatus,
final int debug_level){// debug level used inside loops
double []xy_zero={0.0,0.0};
if (patternGrid==null) return null;
final double [] xy0=(shift_xy==null)?xy_zero:shift_xy;
if ((simulParameters!=null) && (this.bPattern==null)){
System.out.println("simulateGrid(), running patternGenerator(simulParameters )");
patternGenerator(simulParameters ); // generate bPattern if it was not done yet
}
final Rectangle woiOut=new Rectangle(subdiv*woi.x,subdiv*woi.y,subdiv*woi.width,subdiv*woi.height);
final float [] pixels=new float[woiOut.width*woiOut.height];
final float [] pixelsDenom=new float[woiOut.width*woiOut.height];
for (int i=0;i<pixels.length;i++ ){
pixels[i]= 0.0F;
pixelsDenom[i]= 0.0F;
}
final Thread[] threads = newThreadArray(threadsMax);
final AtomicInteger cellNum = new AtomicInteger(0);
final int [] series = new int[1];
final int uvhwidth=(patternGrid[0].length+1)/2;
final int uvwidth= patternGrid[0].length;
final int uvhheight=(patternGrid.length+1)/2;
final int numInSeries=(uvhwidth-1)*(uvhheight-1);
final AtomicInteger debugCellNum = new AtomicInteger(0);
final AtomicInteger finishedAtomic = new AtomicInteger(1);
final int cellsToProcess=numInSeries*4;
final int debugCellNum0=0;
IJ.showStatus("Generating simulated pattern...");
for (series[0]=0;series[0]<4;series[0]++) { // split processing in 4 series (odd/even row/column to avoid races between threads
if (debug_level>2)System.out.println("**** series[0]="+series[0]);
cellNum.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
// String dbgStr="";
int [][][] iUV=new int [2][2][2];
double [][][] dUV=new double [2][2][2];
double [][][] xy=new double [2][2][2];
boolean invPattern;
double [] pixDXY={1.0,1.0};
for (int ncell=cellNum.getAndIncrement(); ncell<numInSeries;ncell=cellNum.getAndIncrement()){
iUV[0][0][0]=2*(ncell%(uvhwidth-1))+ (series[0] & 1);
iUV[0][0][1]=2*(ncell/(uvhwidth-1))+ ((series[0]>>1) & 1);
if ((updateStatus) && (debugLevel>1)) IJ.showStatus("Generating simulated pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
if (debugLevel>2) System.out.println("Generating pattern, series "+series[0]+" (of 4), row "+(iUV[0][0][1]/2+1)+"(of "+(uvhheight-1)+")");
iUV[0][1][0]=iUV[0][0][0]+1;
iUV[0][1][1]=iUV[0][0][1];
iUV[1][0][0]=iUV[0][0][0];
iUV[1][0][1]=iUV[0][0][1]+1;
iUV[1][1][0]=iUV[0][0][0]+1;
iUV[1][1][1]=iUV[0][0][1]+1;
if ((isCellValid(patternGrid,iUV[0][0])) &&
(isCellValid(patternGrid,iUV[0][1])) &&
(isCellValid(patternGrid,iUV[1][0])) &&
(isCellValid(patternGrid,iUV[1][1]))){
// All 4 corners are valid
invPattern=((iUV[0][0][0]%gridFrac)>=(gridFrac/2))^((iUV[0][0][1]%gridFrac)>=(gridFrac/2));
if (debug_level>2)System.out.println("iUV[0][0][1]="+iUV[0][0][1]+" iUV[0][0][0]="+iUV[0][0][0]+" invert="+invPattern);
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
xy[i][j][k]=subdiv*patternGrid[iUV[i][j][1]][iUV[i][j][0]][0][k]+xy0[k];
}
for (int k=0;k<2;k++) {
dUV[0][0][k]=((double) (iUV[0][0][k]%(gridFrac/2)))/(gridFrac/2);
}
dUV[0][1][0]=dUV[0][0][0]+1.0/(gridFrac/2);
dUV[0][1][1]=dUV[0][0][1];
dUV[1][0][0]=dUV[0][0][0];
dUV[1][0][1]=dUV[0][0][1]+1.0/(gridFrac/2);
dUV[1][1][0]=dUV[0][1][0];
dUV[1][1][1]=dUV[1][0][1];
double [] minXY={xy[0][0][0],xy[0][0][1]};
double [] maxXY={xy[0][0][0],xy[0][0][1]};
for (int i=0;i<2;i++) for (int j=0;j<2;j++) for (int k=0;k<2;k++) {
if (minXY[k]>xy[i][j][k]) minXY[k]=xy[i][j][k];
if (maxXY[k]<xy[i][j][k]) maxXY[k]=xy[i][j][k];
}
Rectangle rcell=new Rectangle((int)minXY[0], // contains all pixels
(int)minXY[1],
((int) Math.ceil(maxXY[0]))-((int)minXY[0]) ,
((int) Math.ceil(maxXY[1]))-((int)minXY[1]));
double [] cornersDUV={1.0/(gridFrac/2),1.0/(gridFrac/2)};
boolean debugNow=debugCellNum.getAndIncrement()==debugCellNum0;
if (woiOut.intersects (rcell)) // do not bother if no
for (int iy=rcell.y;iy<(rcell.y+rcell.height);iy++) for (int ix=rcell.x;ix<(rcell.x+rcell.width);ix++)
if (woiOut.contains (ix,iy))
{
double [] pixXY={ix,iy};
double [] pixData=recursiveFillPixels ( // invert pattern in the caller, return signed value (-1..1 - pattern is 0..1)
simulParameters,
pixXY, // top-left corner
pixDXY, // increments to other corners
xy, // xy pairs for the 4 corners of the square in UV (pattern) coordinates (u0v0,u1v0,u0v1,u1v1)
dUV[0][0], // UV value for the top-left corner (matching cornersXY[0][0])
cornersDUV, // distances to the opposite corner in UV
// maskOnly, // just mark defined cells
debugNow?debug_level: debug_level-2
);
// int index=woiOut.width*iy+ix;
int index=woiOut.width*(iy-woiOut.y)+(ix-woiOut.x);
// pixels[index]+=((invPattern || maskOnly)?1.0:-1.0)*pixData[0];
if (index>pixels.length){
// final float [] pixels=new float[woiOut.width*woiOut.height];
System.out.println("simulateGrid(), pixels.length="+pixels.length+
" index="+index+
" iy="+iy+" ix="+ix+
" ncell="+ncell+
" subdiv="+subdiv+
" woiOut.x="+woiOut.x+
" woiOut.y="+woiOut.y+
" woiOut.width="+woiOut.width+
" woiOut.height="+woiOut.height+
" woi.x="+woi.x+
" woi.y="+woi.y+
" woi.width="+woi.width+
" woi.height="+woi.height+
" rcell.x="+rcell.x+
" rcell.y="+rcell.y+
" rcell.width="+rcell.width+
" rcell.height="+rcell.height);
}
// if (maskOnly) pixels[index]=patternGrid.length*iUV[0][0][1]+iUV[0][0][0]; // out of bounds
// OLD NASTY BUG!
// if (maskOnly) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
if (simulParameters==null) pixels[index]=uvwidth*iUV[0][0][1]+iUV[0][0][0]; // Should be width, not height!
else pixels[index]+=(invPattern?1.0:-1.0)*pixData[0];
pixelsDenom[index]+=pixData[1];
}
}
final int numFinished=finishedAtomic.getAndIncrement();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
IJ.showProgress(numFinished,cellsToProcess);
}
});
}
} }
};
}
startAndJoin(threads);
}
for (int i=0;i<pixels.length;i++ ) {
// /(simulParameters!=null)
// if (maskOnly) {
if (simulParameters==null) {
if (pixelsDenom[i]==0.0F) pixels[i]=-1;
} else {
if (pixelsDenom[i]!=0.0F){
pixels[i]/= pixelsDenom[i];
pixels[i]=(float) ((pixels[i]+1.0)/2); // convert from -1..+1 to 0..1.0
} }
} }
return pixels;
}
/* Create a Thread[] array as large as the number of processors available.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
private Thread[] newThreadArray(int maxCPUs) {
int n_cpus = Runtime.getRuntime().availableProcessors();
if (n_cpus>maxCPUs)n_cpus=maxCPUs;
return new Thread[n_cpus];
} }
return pixels;
}
/* Create a Thread[] array as large as the number of processors available.
* From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/
private Thread[] newThreadArray(int maxCPUs) {
int n_cpus = Runtime.getRuntime().availableProcessors();
if (n_cpus>maxCPUs)n_cpus=maxCPUs;
return new Thread[n_cpus];
}
/* Start all given threads and wait on each of them until all are done. /* Start all given threads and wait on each of them until all are done.
* From Stephan Preibisch's Multithreading.java class. See: * From Stephan Preibisch's Multithreading.java class. See:
* http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD * http://repo.or.cz/w/trakem2.git?a=blob;f=mpi/fruitfly/general/MultiThreading.java;hb=HEAD
*/ */
private static void startAndJoin(Thread[] threads) private static void startAndJoin(Thread[] threads)
{
for (int ithread = 0; ithread < threads.length; ++ithread)
{ {
for (int ithread = 0; ithread < threads.length; ++ithread) threads[ithread].setPriority(Thread.NORM_PRIORITY);
{ threads[ithread].start();
threads[ithread].setPriority(Thread.NORM_PRIORITY);
threads[ithread].start();
}
try
{
for (int ithread = 0; ithread < threads.length; ++ithread)
threads[ithread].join();
} catch (InterruptedException ie)
{
throw new RuntimeException(ie);
}
} }
/* ======================================================================== */ try
/* make it faster when outSubdiv =2*n (usually so) */ {
/* TODO: cleanup shifts - they seem now to work correctly */ for (int ithread = 0; ithread < threads.length; ++ithread)
public double [][] extractSimulPatterns ( threads[ithread].join();
SimulParameters simulParameters, } catch (InterruptedException ie)
int outSubdiv, // subdivide output pixels {
int size, // number of Bayer cells in width of the square selection (half number of pixels) throw new RuntimeException(ie);
double x0, // selection center, X (in pixels)
double y0) {
return extractSimulPatterns (
this.barray,
simulParameters,
outSubdiv, // subdivide output pixels
size, // number of Bayer cells in width of the square selection (half number of pixels)
x0, // selection center, X (in pixels)
y0);
} }
}
public double [][] extractSimulPatterns (
double [] localbArray, /* ======================================================================== */
SimulParameters simulParameters, /* make it faster when outSubdiv =2*n (usually so) */
int outSubdiv, // subdivide output pixels /* TODO: cleanup shifts - they seem now to work correctly */
int size, // number of Bayer cells in width of the square selection (half number of pixels) public double [][] extractSimulPatterns (
double x0, // selection center, X (in pixels) SimulParameters simulParameters,
double y0) { int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
return extractSimulPatterns (
this.barray,
simulParameters,
outSubdiv, // subdivide output pixels
size, // number of Bayer cells in width of the square selection (half number of pixels)
x0, // selection center, X (in pixels)
y0);
}
public double [][] extractSimulPatterns (
double [] localbArray,
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv); int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv);
int sampleN=sampleWidth*sampleWidth; int sampleN=sampleWidth*sampleWidth;
if (sampleWidth<1) sampleWidth=1; if (sampleWidth<1) sampleWidth=1;
...@@ -949,7 +959,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -949,7 +959,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
} }
} else { // just reuse available greens } else { // just reuse available greens
if (this.debugLevel>2)System.out.println("Generating combined greens pattern from individual greens"); if (this.debugLevel>2)System.out.println("Generating combined greens pattern from individual greens");
/* now combine greens - same as in splitBayer() */ /* now combine greens - same as in splitBayer() */
int base, base_b; int base, base_b;
base_b=0; base_b=0;
...@@ -984,6 +994,69 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -984,6 +994,69 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
return simul_pixels; return simul_pixels;
} }
public double [] extractSimulMono (
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
return extractSimulMono (
this.barray,
simulParameters,
outSubdiv, // subdivide output pixels
size, // number of Bayer cells in width of the square selection (half number of pixels)
x0, // selection center, X (in pixels)
y0);
}
public double [] extractSimulMono ( // TODO: can use twice smaller barray
double [] localbArray,
SimulParameters simulParameters,
int outSubdiv, // subdivide output pixels - now 4
int size, // number of Bayer cells in width of the square selection (half number of pixels)
double x0, // selection center, X (in pixels)
double y0) {
int sampleWidth=(int) (Math.sqrt(simulParameters.fill)*simulParameters.subdiv);
int sampleN=sampleWidth*sampleWidth;
if (sampleWidth<1) sampleWidth=1;
else if (sampleWidth>simulParameters.subdiv)sampleWidth=simulParameters.subdiv;
double sampleAverage=0.5*sampleN;
int fullSize=(int) Math.sqrt(localbArray.length);
double [] simul_pixels=new double [size*size];
int ix,iy, iy0,ix0,px,py;
double s;
double span=((double) size)/outSubdiv;
int sampLow=-sampleWidth/2;
int sampHigh=sampLow+sampleWidth;
for (iy=0;iy<size;iy++) {
iy0=(fullSize/2) + (int) (( -span/2 + y0 + 0.5 + 1.0 * iy / outSubdiv)*simulParameters.subdiv);
for (ix=0;ix<size;ix++) {
ix0=(fullSize/2) + (int) ((-span/2 + x0 + 0.5 + 1.0 * ix / outSubdiv)*simulParameters.subdiv);
s=0.0;
for (py=iy0+sampLow;py<iy0+sampHigh;py++) for (px=ix0+sampLow;px<ix0+sampHigh;px++) {
try {
s+=localbArray[py*fullSize+px];
} catch (Exception e){
System.out.println("Bug in extractSimulMono(): px="+px+" py="+py+" fullSize="+fullSize+" size="+size+" x0="+x0+" y0="+y0);
e.printStackTrace();
return null;
}
}
simul_pixels[iy*size+ix]= (s-sampleAverage)/sampleAverage;
}
}
if (this.debugLevel>2) {
System.out.println("extractSimulMono, x0="+x0+" y0="+y0+" fullSize="+fullSize+" size="+size+" subdiv="+simulParameters.subdiv+" outSubdiv="+outSubdiv);
System.out.println(" sampLow="+sampLow+" sampHigh="+sampHigh+" span="+span+" size="+size);
s=0.0;
for (int i=0;i<simul_pixels.length;i++) s+=simul_pixels[i];
System.out.println("sum of pixels="+s);
}
if (this.debugLevel>2) SDFA_INSTANCE.showArrays(simul_pixels,size,size, "SIMUL");
return simul_pixels;
}
private double [] matrix2x2_mul(double [][] a, double [] b ){ private double [] matrix2x2_mul(double [][] a, double [] b ){
double [] rslt={a[0][0]*b[0]+a[0][1]*b[1], double [] rslt={a[0][0]*b[0]+a[0][1]*b[1],
a[1][0]*b[0]+a[1][1]*b[1]}; a[1][0]*b[0]+a[1][1]*b[1]};
...@@ -1019,8 +1092,8 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1019,8 +1092,8 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
if (colorComp==4) { // checkerboard greens if (colorComp==4) { // checkerboard greens
r.y+=r.width/2; // now it is the "top left" corner of the diagonal greens r.y+=r.width/2; // now it is the "top left" corner of the diagonal greens
for (index=0;index<result.length;index++){ for (index=0;index<result.length;index++){
// int iy=r.y+(index / r.width); // int iy=r.y+(index / r.width);
// int ix=r.x+(index % r.width); // int ix=r.x+(index % r.width);
int iyi=index / r.width; int iyi=index / r.width;
int ixi=index % r.width; int ixi=index % r.width;
int iy=r.y+(iyi+ixi)/2 -ixi; int iy=r.y+(iyi+ixi)/2 -ixi;
...@@ -1048,11 +1121,11 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1048,11 +1121,11 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
else if (ix>=full_width) iy=full_width-1; else if (ix>=full_width) iy=full_width-1;
result[index]=spixels[0][iy*full_width+ix]; result[index]=spixels[0][iy*full_width+ix];
} }
} }
return result; return result;
} }
//===================== //=====================
public static class SimulParameters { public static class SimulParameters {
public int patternSize; public int patternSize;
public int pattern_type; public int pattern_type;
...@@ -1072,7 +1145,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1072,7 +1145,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
public double bitmapNonuniforityThreshold; // subdivide pixels until difference between the corners is below this value public double bitmapNonuniforityThreshold; // subdivide pixels until difference between the corners is below this value
public double offsetX; // debug - add to X during simulation, in pixels public double offsetX; // debug - add to X during simulation, in pixels
public double offsetY; // debug - add to Y during simulation, in pixels public double offsetY; // debug - add to Y during simulation, in pixels
public SimulParameters( public SimulParameters(
int patternSize, int patternSize,
...@@ -1093,7 +1166,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1093,7 +1166,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
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
double offsetX, // debug - add to X during simulation, in pixels double offsetX, // debug - add to X during simulation, in pixels
double offsetY // debug - add to Y during simulation, in pixels double offsetY // debug - add to Y during simulation, in pixels
) { ) {
this.patternSize= patternSize; this.patternSize= patternSize;
this.pattern_type= pattern_type; this.pattern_type= pattern_type;
...@@ -1115,6 +1188,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1115,6 +1188,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
this.offsetY= offsetY; this.offsetY= offsetY;
} }
@Override
public SimulParameters clone() { public SimulParameters clone() {
return new SimulParameters( return new SimulParameters(
this.patternSize, this.patternSize,
...@@ -1135,7 +1209,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1135,7 +1209,7 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
this.bitmapNonuniforityThreshold, this.bitmapNonuniforityThreshold,
this.offsetX, this.offsetX,
this.offsetY this.offsetY
); );
} }
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
...@@ -1178,6 +1252,6 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy) ...@@ -1178,6 +1252,6 @@ Cv=(Cy*x-Cx*y)+(-Cy*Dx+Cx*Dy)
if (properties.getProperty(prefix+"offsetX")!=null) this.offsetX=Double.parseDouble(properties.getProperty(prefix+"offsetX")); if (properties.getProperty(prefix+"offsetX")!=null) this.offsetX=Double.parseDouble(properties.getProperty(prefix+"offsetX"));
if (properties.getProperty(prefix+"offsetY")!=null) this.offsetY=Double.parseDouble(properties.getProperty(prefix+"offsetY")); if (properties.getProperty(prefix+"offsetY")!=null) this.offsetY=Double.parseDouble(properties.getProperty(prefix+"offsetY"));
} }
} }
} }
...@@ -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;
*/
} }
/** /**
...@@ -387,7 +303,7 @@ public class DoubleFHT { ...@@ -387,7 +303,7 @@ public class DoubleFHT {
else return phaseCorrelate (first, second, phaseCoeff,filter); else return phaseCorrelate (first, second, phaseCoeff,filter);
} }
//asymmetrical - will divide by squared second amplitude (pattern to match) //asymmetrical - will divide by squared second amplitude (pattern to match)
public double [] phaseCorrelate ( public double [] phaseCorrelate ( // old
double [] first, double [] first,
double [] second, double [] second,
double phaseCoeff, double phaseCoeff,
...@@ -408,6 +324,104 @@ public class DoubleFHT { ...@@ -408,6 +324,104 @@ 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 [] phaseCorrelate (
double [] first,
double [] second,
double phaseCoeff,
double highPassSigma,
double lowPassSigma,
double [] first_save,
double [] second_save ){ //null-OK
updateMaxN(first);
double [] filter = null;
if ((highPassSigma >0) || (lowPassSigma > 0)) {
filter = createFrequencyFilter(highPassSigma, lowPassSigma);
}
return phaseCorrelate (
first,
second,
phaseCoeff,
filter, // high/low pass filtering
first_save,
second_save );
}
public double [] phaseCorrelate ( // new
double [] first,
double [] second,
double phaseCoeff,
double [] filter, // high/low pass filtering
double [] first_save,
double [] second_save ){ //null-OK
if (first.length!=second.length) {
IJ.showMessage("Error","Correlation arrays should be the same size");
return null;
}
updateMaxN(first);
swapQuadrants(first);
swapQuadrants(second);
if (!transform(first,false)) return null; // direct FHT
if (!transform(second,false)) return null; // direct FHT
if (first_save != null) System.arraycopy(first, 0, first_save, 0, first.length);
if (second_save != null) System.arraycopy(second, 0, second_save, 0, second.length);
first= phaseMultiplyNorm(first, second, 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 +2038,7 @@ public class DoubleFHT { ...@@ -2024,6 +2038,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 +2056,54 @@ public class DoubleFHT { ...@@ -2041,6 +2056,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 +2157,17 @@ public class DoubleFHT { ...@@ -2094,6 +2157,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 +2207,6 @@ public class DoubleFHT { ...@@ -2133,8 +2207,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;
......
...@@ -1358,7 +1358,11 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970 ...@@ -1358,7 +1358,11 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970
itr=set.iterator(); itr=set.iterator();
while(itr.hasNext()) { while(itr.hasNext()) {
str = (String) itr.next(); str = (String) itr.next();
imp_dst.setProperty(str,prop.getProperty(str)); try {
imp_dst.setProperty(str,prop.getProperty(str));
} catch (Exception e) {
imp_dst.setProperty(str,"");
}
} }
} }
} }
...@@ -1407,7 +1411,12 @@ Exception in thread "Thread-3564" java.lang.ArrayIndexOutOfBoundsException: 8970 ...@@ -1407,7 +1411,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,15 @@ ...@@ -26,10 +26,15 @@
*/ */
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.ImagePlus;
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 +54,8 @@ public class LwirReaderParameters { ...@@ -49,6 +54,8 @@ 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 int max_lwir_width = 1024; //
/* /*
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};
...@@ -73,11 +80,19 @@ public class LwirReaderParameters { ...@@ -73,11 +80,19 @@ public class LwirReaderParameters {
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
protected boolean show_images = false; protected boolean show_images = false;
// --- interface methods // --- interface methods
public boolean is_LWIR(int width) {
return width <= max_lwir_width;
}
public boolean is_LWIR(ImagePlus imp){
return is_LWIR(imp.getWidth());
}
public int getDebugLevel() { public int getDebugLevel() {
return this.debug_level; return this.debug_level;
} }
public void setDebugLevel(int level) { public void setDebugLevel(int level) {
this.debug_level = level; this.debug_level = level;
} }
...@@ -110,9 +125,9 @@ public class LwirReaderParameters { ...@@ -110,9 +125,9 @@ 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));
properties.setProperty(prefix+"show_images", this.show_images+""); properties.setProperty(prefix+"show_images", this.show_images+"");
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
...@@ -140,8 +155,8 @@ public class LwirReaderParameters { ...@@ -140,8 +155,8 @@ 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"));
if (properties.getProperty(prefix+"show_images")!=null) this.show_images= Boolean.parseBoolean(properties.getProperty(prefix+"show_images")); if (properties.getProperty(prefix+"show_images")!=null) this.show_images= Boolean.parseBoolean(properties.getProperty(prefix+"show_images"));
parameters_updated = true; parameters_updated = true;
} }
@Override @Override
...@@ -171,6 +186,7 @@ public class LwirReaderParameters { ...@@ -171,6 +186,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();
lrp.show_images = this.show_images; lrp.show_images = this.show_images;
return lrp; return lrp;
} }
...@@ -208,6 +224,7 @@ public class LwirReaderParameters { ...@@ -208,6 +224,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) &&
(java.util.Arrays.equals(lrp.selected_channels, this.selected_channels)) &&
(lrp.show_images == this.show_images); (lrp.show_images == this.show_images);
} }
...@@ -235,6 +252,7 @@ public class LwirReaderParameters { ...@@ -235,6 +252,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();
...@@ -251,7 +269,7 @@ public class LwirReaderParameters { ...@@ -251,7 +269,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");
...@@ -266,7 +284,8 @@ public class LwirReaderParameters { ...@@ -266,7 +284,8 @@ 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)");
gd.addCheckbox ("Show images", this.show_images, "Show acquired images after averaging)"); gd.addCheckbox ("Show images", this.show_images, "Show acquired images after averaging)");
} }
...@@ -295,8 +314,8 @@ public class LwirReaderParameters { ...@@ -295,8 +314,8 @@ 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());
this.show_images = gd.getNextBoolean(); this.show_images = gd.getNextBoolean();
parameters_updated = true; parameters_updated = true;
} }
...@@ -320,6 +339,80 @@ public class LwirReaderParameters { ...@@ -320,6 +339,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) {
...@@ -334,6 +427,23 @@ public class LwirReaderParameters { ...@@ -334,6 +427,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) {
...@@ -362,4 +472,22 @@ public class LwirReaderParameters { ...@@ -362,4 +472,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