Commit 3272bf8a authored by Andrey Filippov's avatar Andrey Filippov
Browse files

X-cam alignment calculation

parent 739921ca
Loading
Loading
Loading
Loading
+1134 −1117
Original line number Diff line number Diff line
@@ -25,27 +25,59 @@
 **
 */
import ij.*;
import ij.io.*;
import ij.process.*;
import ij.gui.*;
import ij.plugin.frame.*;
import ij.text.TextWindow;
import java.awt.*;
import java.awt.event.*;
import java.io.*; // FIle
import java.util.Properties;
import javax.swing.*; // TODO: modify methods that depend on it, use class CalibrationFileManagement
import java.util.*; 
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
// FIle
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// TODO: modify methods that depend on it, use class CalibrationFileManagement
import javax.swing.JFileChooser;
import Jama.Matrix;  // Download here: http://math.nist.gov/javanumerics/jama/
import ij.IJ;
import ij.ImageJ;
import ij.ImagePlus;
import ij.ImageStack;
import ij.Prefs;
import ij.WindowManager;
import ij.gui.GUI;
import ij.gui.GenericDialog;
import ij.gui.Overlay;
import ij.gui.Roi;
import ij.io.FileSaver;
import ij.io.OpenDialog;
import ij.io.Opener;
import ij.plugin.frame.PlugInFrame;
import ij.process.FloatProcessor;
import ij.process.ImageConverter;
import ij.process.ImageProcessor;
import ij.text.TextWindow;
public class Aberration_Calibration extends PlugInFrame implements ActionListener {
	private static final long serialVersionUID = 1040236897357482595L;
@@ -707,6 +739,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
		addButton("Configure Distortion/Location",panelLens,color_configure);
		addButton("Configure Eyesis4pi",panelLens,color_configure);
		addButton("List Eyesis4pi",panelLens,color_report);
		addButton("List X-cam",panelLens,color_report);
		addButton("Process Lens Distortion",panelLens);
		addButton("Configure Lasers",panelLens,color_configure);
		addButton("Manual laser pointers",panelLens,color_debug);
@@ -997,6 +1030,7 @@ if (MORE_BUTTONS) {
		b.addKeyListener(IJ.getInstance());
		panel.add(b);
	}
	@Override
	public void processWindowEvent(WindowEvent e) {
		super.processWindowEvent(e);
		if (e.getID()==WindowEvent.WINDOW_CLOSING) {
@@ -1004,6 +1038,7 @@ if (MORE_BUTTONS) {
		}
	}
	@Override
	public void actionPerformed(ActionEvent e) {
		String label = e.getActionCommand();
		if        (label.equals("Abort")) {
@@ -1133,13 +1168,6 @@ if (MORE_BUTTONS) {
	    				UPDATE_STATUS,
	    				DEBUG_LEVEL
	    		);
/*// Not needed, controlled by parameters	    		
	    		if (ABERRATIONS_PARAMETERS.autoLoadPaths()[3]!=null) {
	    			// Re-read configuration file to overwrite camera parameters restored with calibration files
	    			if (DEBUG_LEVEL>0) System.out.println("Re-reading configuration to overwrite camera parameters restored from the sensor calibration files");
	    			loadProperties(confPath,PROCESS_PARAMETERS.kernelsDirectory,PROCESS_PARAMETERS.useXML, PROPERTIES);
	    		}
*/	    		
	    		if (dcdUpdated) DISTORTION_CALIBRATION_DATA=LENS_DISTORTIONS.fittingStrategy.distortionCalibrationData;
		    	if (ABERRATIONS_PARAMETERS.autoReCalibrate){
					if (LENS_DISTORTIONS.fittingStrategy==null) {
@@ -1243,8 +1271,6 @@ if (MORE_BUTTONS) {
									imp_sel); // reuse the same image window
// Remove for old method?
							matchSimulatedPattern= new MatchSimulatedPattern(DISTORTION.FFTSize);
//							   matchSimulatedPattern.invalidateFlatFieldForGrid(); //It is already reset, no need to do it again
//							   matchSimulatedPattern.invalidateFocusMask();
							matchSimulatedPattern.calculateDistortions(
									DISTORTION, //
@@ -1263,17 +1289,6 @@ if (MORE_BUTTONS) {
									DISTORTION.loop_debug_level, // debug level
									noMessageBoxes);
/*
  							SIM_ARRAY=	simulateGridAll (
 									imp_sel.getWidth(),
									imp_sel.getHeight(),
									matchSimulatedPattern.getDArray(),
									2, // gridFrac, // number of grid steps per pattern full period
									SIMUL,
									THREADS_MAX,
									UPDATE_STATUS,
									DISTORTION.loop_debug_level); // debug level
*/
							SIM_ARRAY=	(new SimulationPattern(SIMUL)).simulateGridAll (
									imp_sel.getWidth(),
									imp_sel.getHeight(),
@@ -1288,7 +1303,6 @@ if (MORE_BUTTONS) {
							createPSFMap(
									matchSimulatedPattern,
									matchSimulatedPattern.applyFlatField (imp_sel), // if grid is flat-field calibrated, apply it
//									imp_sel, // linearized Bayer mosaic image form the camera, GR/BG
									null,     //  int [][][] sampleList, // optional (or null) 2-d array: list of coordinate pairs (2d - to match existent  PSF_KERNEL_MAP structure)
									MULTIFILE_PSF.overexposedMaxFraction,
									SIMUL, //simulation parameters
@@ -2295,7 +2309,7 @@ if (MORE_BUTTONS) {
			return;
		}
/* ======================================================================== */
		if       (label.equals("List Eyesis4pi")) {
		if (label.equals("List Eyesis4pi") || label.equals("List X-cam")) {
			DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
			System.out.println("DISTORTION_CALIBRATION_DATA="+((DISTORTION_CALIBRATION_DATA==null)?"null":" NOT null"));
			System.out.println("+++++++++++ EYESIS_CAMERA_PARAMETERS.numStations="+EYESIS_CAMERA_PARAMETERS.numStations+
@@ -2309,10 +2323,9 @@ if (MORE_BUTTONS) {
				new DistortionCalibrationData(EYESIS_CAMERA_PARAMETERS);
			if (DEBUG_LEVEL>1) System.out.println("+++++++++++ dcd.eyesisCameraParameters.numStations="+dcd.eyesisCameraParameters.numStations+
					" +dcd.eyesisCameraParameters.goniometerHorizontal.length="+dcd.eyesisCameraParameters.goniometerHorizontal.length);
			dcd.listCameraParameters();
			dcd.listCameraParameters(label.equals("List X-cam"));
			return;
		}
		
/* ======================================================================== */
		if       (label.equals("Process Lens Distortion")) {
			DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
@@ -12450,7 +12463,7 @@ if (MORE_BUTTONS) {
			ImagePlus imp_psf = new ImagePlus(psfTitle, mergedStack);
			imp_psf.getProcessor().resetMinAndMax();
			imp_psf.setProperty("comment",focusMeasurementParameters.comment);
			imp_psf.setProperty("timestamp", (String) imp_sel.getProperty("timestamp"));
			imp_psf.setProperty("timestamp", imp_sel.getProperty("timestamp"));
			if (!Double.isNaN(focusMeasurementParameters.sensorTemperature))
				imp_psf.setProperty("sensorTemperature", ""+focusMeasurementParameters.sensorTemperature);
			imp_psf.setProperty("px0", ""+lensDistortionParameters.px0);
@@ -15744,6 +15757,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
			    prefix=   pref;
			    pattern = str;
		  }
		  @Override
		public boolean accept (File dir, String name) {
			if (prefix!=null) return (name.startsWith(prefix)) && (name.toLowerCase().endsWith(pattern.toLowerCase()));
		    return name.toLowerCase().endsWith(pattern.toLowerCase());
@@ -16264,6 +16278,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
		final int numberOfKernelsInChn=tilesY*tilesX;
		for (int ithread = 0; ithread < threads.length; ithread++) {
			threads[ithread] = new Thread() {
				@Override
				public void run() {
					float [] pixels=null;
					double [] kernel= new double[inverseParameters.dSize*inverseParameters.dSize];
@@ -16476,6 +16491,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
		for (int ithread = 0; ithread < threads.length; ithread++) {
			// Concurrently run in as many threads as CPUs
			threads[ithread] = new Thread() {
				@Override
				public void run() {
					// Each thread processes a few items in the total list
@@ -16640,6 +16656,7 @@ private double [][] jacobianByJacobian(double [][] jacobian, boolean [] mask) {
		for (int ithread = 0; ithread < threads.length; ithread++) {
			// Concurrently run in as many threads as CPUs
			threads[ithread] = new Thread() {
				@Override
				public void run() {
					// Each thread processes a few items in the total list
@@ -18541,11 +18558,11 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
		if (debug) {
			SDFA_INSTANCE.showArrays(debugPixels, title+"_mask_PSF");
			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(pixelsPSFWeight,      title+"_PSF_bin_weight");
			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");
		}
		return pixelsPSF;
@@ -19138,7 +19155,7 @@ if (DEBUG_LEVEL>1) System.out.println("findClusterOnPSF: ix="+ix+" iy="+iy);
			ImageProcessor ip = new FloatProcessor(size,size);
			float [] floatPixels = new float [size*size];
			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.resetMinAndMax();
@@ -19368,7 +19385,7 @@ returns integer array (same dimensions as input) with 1 - selected, 0 - not sele
					iy=-iy;
				}
				ix= (ix+size) % size;
				floatPixels[i]=(float) clusterMap[iy][ix];
				floatPixels[i]=clusterMap[iy][ix];
			}
			ip.setPixels(floatPixels);
			ip.resetMinAndMax();
@@ -20460,8 +20477,8 @@ use the result to create a rejectiobn mask - if the energy was high, (multiplica
			row2=(fftsize-row1) %fftsize;
			for (col1=0;col1 < fftsize;col1++) {
				col2=(fftsize-col1) %fftsize;
				fht_pixels[row1*fftsize+col1]=(double) (fft[row1][col1][0]-fft[row1][col1][1]);
				fht_pixels[row2*fftsize+col2]=(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]=fft[row1][col1][0]+fft[row1][col1][1];
			}
		}
		return fht_pixels;
+428 −232
Original line number Diff line number Diff line
@@ -22,17 +22,6 @@
 **
 */

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 ij.text.TextWindow;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
@@ -45,6 +34,17 @@ import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.XMLConfiguration;

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 ij.text.TextWindow;

//import EyesisCameraParameters;
//import Distortions.EyesisSubCameraParameters;
//import LensDistortionParameters;
@@ -712,6 +712,22 @@ import org.apache.commons.configuration.XMLConfiguration;

        }

        public void listCameraParameters(boolean xcam){
        	int numSubCameras=getNumSubCameras();
        	if (this.gIP!=null) {
        		int maxChn=0;
        		for (int i=0;i<this.gIP.length;i++) if ((this.gIP[i]!=null) && (this.gIP[i].channel>maxChn)){
        			maxChn=this.gIP[i].channel;
        		}
        		numSubCameras=maxChn+1;
        	}

        	if (xcam && (numSubCameras == 4)) {
        		listCameraParametersXcam();
        	} else {
        		listCameraParameters();
        	}
        }
        public void listCameraParameters(){
            int numSubCameras=getNumSubCameras();
            if (this.gIP!=null) {
@@ -778,6 +794,186 @@ import org.apache.commons.configuration.XMLConfiguration;
     	    new TextWindow("Camera parameters", header, sb.toString(), 85*(numSubCameras+3),600);
         }

        public void listCameraParametersXcam(){ // getNumSubCameras() should be 4!
        	double rollDegPerTurn =  -0.45/33.5*180/Math.PI; //  -0.769644799429464 deg/turn, CW screw increases roll, degrees per 1 screw turn
        	double headDegPerTurn = 0.45/34.5*180/Math.PI; //  0.7473362545184652  deg/turn, both screws CW decreases heading (degree/turn)
        	double elevDegPerTurn = 0.45/14*180/Math.PI; //  1.8416500557776463 deg/turn, top CW, bottom CCW decreases elevation (degree/turn)


            int numSubCameras=getNumSubCameras();
            if (this.gIP!=null) {
            	int maxChn=0;
            	for (int i=0;i<this.gIP.length;i++) if ((this.gIP[i]!=null) && (this.gIP[i].channel>maxChn)){
            		maxChn=this.gIP[i].channel;
            	}
            	numSubCameras=maxChn+1;
            }
        	String header="Name\tUnits";
        	StringBuffer sb = new StringBuffer();
        	for (int i=0;i<numSubCameras;i++) header+="\t"+i;
        	for (int stationNumber=0;stationNumber<this.eyesisCameraParameters.numStations;stationNumber++){
        		if (this.eyesisCameraParameters.numStations>1){
        			sb.append("Station "+stationNumber+" W="+(100*this.eyesisCameraParameters.stationWeight[stationNumber])+"%");  for (int i=-1;i<numSubCameras;i++) sb.append("\t===");  sb.append("\n");
        		}

        		int [] lensDistortionModels=new int [numSubCameras];
        		for (int i=0;i<numSubCameras;i++) lensDistortionModels[i]=eyesisCameraParameters.getLensDistortionModel(stationNumber,i);
//        		sb.append("Lens Distortion Model\t");
//        		for (int i=0;i<numSubCameras;i++) sb.append("\t"+lensDistortionModels[i]);
//        		sb.append("\n");
        		double [][] cameraPars=new double [numSubCameras][];

            	for (int i=0;i<numSubCameras;i++) cameraPars[i]=eyesisCameraParameters.getParametersVector(stationNumber,i);

            	// calculate average height average right
            	double [] subcamRight =      new double[numSubCameras];
            	double [] subcamHeight =     new double[numSubCameras];
            	double [] subcamCorrRight =  new double[numSubCameras]; // in rotated C.S.
            	double [] subcamCorrHeight = new double[numSubCameras]; // in rotated C.S.
            	double [] subcamHeading =    new double[numSubCameras];
            	double [] subcamElevation =  new double[numSubCameras];
            	double subcamRightCenter =     0.0;
            	double subcamHeightCenter =    0.0;
            	double subcamHeadingCenter =   0.0;
            	double subcamElevationCenter = 0.0;
            	double [] subcamRelRot =        new double[numSubCameras];
            	double [] subcamRelHeading =    new double[numSubCameras];
            	double [] subcamRelElevation =  new double[numSubCameras];

            	double [] rollCorrTurns =       new double[numSubCameras];
            	double [] topCorrTurns =        new double[numSubCameras];
            	double [] botCorrTurns =        new double[numSubCameras];
            	for (int i=0;i<numSubCameras;i++) {
            		subcamRight[i] =     cameraPars[i][getParameterIndexByName("subcamRight")];
            		subcamHeight[i] =    cameraPars[i][getParameterIndexByName("subcamHeight")];
            		subcamHeading[i] =   cameraPars[i][getParameterIndexByName("subcamHeading")];
            		subcamElevation[i] = cameraPars[i][getParameterIndexByName("subcamElevation")];
            		subcamRightCenter +=     subcamRight[i];
            		subcamHeightCenter +=    subcamHeight[i];
            		subcamHeadingCenter +=   subcamHeading[i];
            		subcamElevationCenter += subcamElevation[i];
            	}
            	subcamRightCenter /= numSubCameras;
            	subcamHeightCenter /= numSubCameras;
            	subcamHeadingCenter /= numSubCameras;
            	subcamElevationCenter /= numSubCameras;
            	double [] subcamNominalDirs = {135.0,45.0, -135.0, -45.0};
            	double [] subcamDirsDeg = new double[numSubCameras];
            	double commonRot = 0.0;
            	for (int i=0;i<numSubCameras;i++) {
            		subcamDirsDeg[i]=180.0/Math.PI*Math.atan2(subcamHeight[i]-subcamHeightCenter, subcamRight[i]-subcamRightCenter);
            		commonRot += subcamNominalDirs[i]-subcamDirsDeg[i];
            	}
            	commonRot /= numSubCameras;
            	for (int i=0;i<numSubCameras;i++) {
            		subcamRelRot[i] =       cameraPars[i][getParameterIndexByName("subcamRoll")] - commonRot;
            		subcamRelHeading[i] =   subcamHeading[i] - subcamHeadingCenter;
            		subcamRelElevation[i] =   subcamElevation[i] - subcamElevationCenter;

            		double r = Math.sqrt((subcamHeight[i]-subcamHeightCenter)*(subcamHeight[i]-subcamHeightCenter)+
            				(subcamRight[i]-subcamRightCenter)*(subcamRight[i]-subcamRightCenter));
            		subcamCorrRight[i] = r*Math.cos(Math.PI/180.0*(subcamDirsDeg[i]+commonRot));
            		subcamCorrHeight[i] = r*Math.sin(Math.PI/180.0*(subcamDirsDeg[i]+commonRot));

            		rollCorrTurns[i] = subcamRelRot[i] * rollDegPerTurn;
            		topCorrTurns[i] =  subcamRelHeading[i] * headDegPerTurn + subcamRelElevation[i] * elevDegPerTurn;
            		botCorrTurns[i] =  subcamRelHeading[i] * headDegPerTurn - subcamRelElevation[i] * elevDegPerTurn;

            	}
/*
            	// parameters same order as in this
            	for (int n=0;n<cameraPars[0].length;n++) if (isSubcameraParameter(n) && isIntrinsicParameter(n)){
            		sb.append(getParameterName(n)+"\t"+getParameterUnits(n));
            		for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(cameraPars[i][n],3));
            		sb.append("\n");
            	}
*/
//            	sb.append("---");  for (int i=-1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");
            	int flindex =getParameterIndexByName("subcamFocalLength");
        		sb.append(getParameterName(flindex)+"\t"+getParameterUnits(flindex));
        		for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(cameraPars[i][flindex],3));
        		sb.append("\n");

            	sb.append("Camera roll"+"\t"+"degrees"+"\t"+IJ.d2s(commonRot,3));
            	for (int i=1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");

            	sb.append("Camera heading"+"\t"+"degrees"+"\t"+IJ.d2s(subcamHeadingCenter,3));
            	for (int i=1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");

            	sb.append("Camera elevation"+"\t"+"degrees"+"\t"+IJ.d2s(subcamElevationCenter,3));
            	for (int i=1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");

            	sb.append("Rel roll"+"\t"+"degrees");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(subcamRelRot[i],3));
            	sb.append("\n");


            	sb.append("Rel heading"+"\t"+"degrees");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(subcamRelHeading[i],3));
            	sb.append("\n");

            	sb.append("Rel elevation"+"\t"+"degrees");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(subcamRelElevation[i],3));
            	sb.append("\n");

            	sb.append("Corr right"+"\t"+"mm");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(subcamCorrRight[i],3));
            	sb.append("\n");

            	sb.append("Corr height"+"\t"+"mm");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(subcamCorrHeight[i],3));
            	sb.append("\n");

            	sb.append("---");  for (int i=-1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");
            	sb.append("Screw roll"+"\t"+"turns CW");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(rollCorrTurns[i],2));
            	sb.append("\n");

            	sb.append("Screw top"+"\t"+"turns CW");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(topCorrTurns[i],2));
            	sb.append("\n");

            	sb.append("Screw bottom"+"\t"+"turns CW");
            	for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(botCorrTurns[i],2));
            	sb.append("\n");

            	sb.append("---");  for (int i=-1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");

            	for (int n=0;n<cameraPars[0].length;n++) if (isSubcameraParameter(n) && !isIntrinsicParameter(n)){
            		sb.append(getParameterName(n)+"\t"+getParameterUnits(n));
            		for (int i=0;i<numSubCameras;i++) sb.append("\t"+IJ.d2s(cameraPars[i][n],3));
            		sb.append("\n");
            	}
            	sb.append("---");  for (int i=-1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");
            	/*
            	for (int n=0;n<cameraPars[0].length;n++) if (
            			!isSubcameraParameter(n)&&
            			!isLocationParameter(n)&&
            			!isOrientationParameter(n)){
            		sb.append(getParameterName(n)+"\t"+getParameterUnits(n));
            		sb.append("\t"+IJ.d2s(cameraPars[0][n],3));
            		for (int i=1;i<numSubCameras;i++) sb.append("\t---");
            		sb.append("\n");
            	}
            	sb.append("---");  for (int i=-1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");
            	for (int n=0;n<cameraPars[0].length;n++) if (isLocationParameter(n)){
            		sb.append(getParameterName(n)+"\t"+getParameterUnits(n));
            		sb.append("\t"+IJ.d2s(cameraPars[0][n],3));
            		for (int i=1;i<numSubCameras;i++) sb.append("\t---");
            		sb.append("\n");
            	}
            	sb.append("---");  for (int i=-1;i<numSubCameras;i++) sb.append("\t");  sb.append("\n");
            	for (int n=0;n<cameraPars[0].length;n++) if (isOrientationParameter(n)){
            		sb.append(getParameterName(n)+"\t"+getParameterUnits(n));
            		sb.append("\t"+IJ.d2s(cameraPars[0][n],3));
            		for (int i=1;i<numSubCameras;i++) sb.append("\t---");
            		sb.append("\n");
            	}
*/
            }
     	    new TextWindow("Camera parameters", header, sb.toString(), 85*(numSubCameras+3),600);
         }


        public void setImages(
        		ImagePlus [] images,  // images in the memory
@@ -2055,8 +2251,8 @@ import org.apache.commons.configuration.XMLConfiguration;
//    		int numOfGridNodes=0;
//    		int numOfGridNodes_extra=0;
        	for (int i=0;i<pixels[0].length;i++) if ((pixels[0][i]>=0) && (pixels[1][i]>=0) && (pixels[0][i]<sensorWidth) && (pixels[1][i]<sensorHeight)){
        		int u=(int) Math.round(pixels[2][i]);
        		int v=(int) Math.round(pixels[3][i]);
        		int u=Math.round(pixels[2][i]);
        		int v=Math.round(pixels[3][i]);
    			int u1= reMap[0][0]*u + reMap[0][1]*v + reMap[0][2]; // u
    			int v1= reMap[1][0]*u + reMap[1][1]*v + reMap[1][2]; // v;
//        		if (patternParameters.getXYZM(u,v,this.debugLevel>1)!=null) size++;
@@ -2079,8 +2275,8 @@ import org.apache.commons.configuration.XMLConfiguration;
//			this.gIP[fileNumber].flatFieldAvailable=pixels.length>=8;
//        	if (disableNoFlatfield && !this.gIP[fileNumber].flatFieldAvailable) this.gIP[fileNumber].enabled=false; // just to use old mixed data
        	for (int i=0;i<pixels[0].length;i++) if ((pixels[0][i]>=0) && (pixels[1][i]>=0) && (pixels[0][i]<sensorWidth) && (pixels[1][i]<sensorHeight)) {
        		int u=(int) Math.round(pixels[2][i]);
        		int v=(int) Math.round(pixels[3][i]);
        		int u=Math.round(pixels[2][i]);
        		int v=Math.round(pixels[3][i]);
    			int u1= reMap[0][0]*u + reMap[0][1]*v + reMap[0][2]; // u
    			int v1= reMap[1][0]*u + reMap[1][1]*v + reMap[1][2]; // v;