Commit 50de1233 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

preparing for the goniometer with LWIR

parent 47b15645
Loading
Loading
Loading
Loading
+492 −338

File changed.

Preview size limit exceeded, changes collapsed.

+144 −119
Original line number Diff line number Diff line
@@ -29,12 +29,10 @@ package com.elphel.imagej.calibration;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;

import com.elphel.imagej.calibration.CalibrationHardwareInterface.CamerasInterface;
import com.elphel.imagej.calibration.CalibrationHardwareInterface.GoniometerMotors;
import com.elphel.imagej.calibration.SimulationPattern.SimulParameters;
import com.elphel.imagej.cameras.EyesisCameraParameters;
import com.elphel.imagej.common.ShowDoubleFloatArrays;
import com.elphel.imagej.common.WindowTools;
import com.elphel.imagej.lwir.LwirReader;

import ij.IJ;
import ij.ImagePlus;
@@ -53,6 +51,7 @@ horizontal axis:
																				// for
																				// debugging
	public CalibrationHardwareInterface.CamerasInterface cameras = null;
	LwirReader lwirReader = null;
	// public CalibrationHardwareInterface.LaserPointers lasers = null;
	// public static CalibrationHardwareInterface.FocusingMotors motorsS=null;
	// public DistortionProcessConfiguration
@@ -81,7 +80,6 @@ horizontal axis:

	public Goniometer(CalibrationHardwareInterface.CamerasInterface cameras,
			MatchSimulatedPattern.DistortionParameters distortionParametersDefault,
//			MatchSimulatedPattern.DistortionParameters distortion,
			MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
			EyesisCameraParameters eyesisCameraParameters,
			MatchSimulatedPattern.LaserPointer laserPointers,
@@ -98,9 +96,34 @@ horizontal axis:
		this.simulParametersDefault=simulParametersDefault;
		this.goniometerParameters=goniometerParameters;
		this.distortionProcessConfiguration=distortionProcessConfiguration;
	}

	public Goniometer(
			LwirReader lwirReader,
//			CalibrationHardwareInterface.CamerasInterface cameras,
			MatchSimulatedPattern.DistortionParameters distortionParametersDefault,
			MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
			EyesisCameraParameters eyesisCameraParameters,
			MatchSimulatedPattern.LaserPointer laserPointers,
			SimulationPattern.SimulParameters simulParametersDefault,
			Goniometer.GoniometerParameters goniometerParameters,
			DistortionProcessConfiguration distortionProcessConfiguration
			) {
		this.lwirReader= lwirReader;
//		this.cameras = cameras;
		this.distortionParametersDefault = distortionParametersDefault;
//		this.distortion = distortion;
		this.patternDetectParameters=patternDetectParameters;
		this.eyesisCameraParameters = eyesisCameraParameters;
		this.laserPointers = laserPointers;
		this.simulParametersDefault=simulParametersDefault;
		this.goniometerParameters=goniometerParameters;
		this.distortionProcessConfiguration=distortionProcessConfiguration;
	}




	//goniometerMotors
	private enum MOT_ACT {
		MOVE_SPEC,
@@ -222,6 +245,8 @@ horizontal axis:
		if (!OK) System.out.println("motorsMove()->false");
		return true; // OK; // So will re-open dialog even after abort
	}


	public boolean scanAndAcquire(
			double targetAngleHorizontal,
			double targetAngleVertical,
@@ -276,7 +301,6 @@ horizontal axis:
			double cosMinAbsTilt=Math.cos(minAbsTilt*Math.PI/180.0);
			if (this.debugLevel>2) System.out.println("tilt="+IJ.d2s(tilt,2)+"tiltL="+IJ.d2s(tiltL,2)+", tiltH="+IJ.d2s(tiltH,2)+
					", minAbsTilt="+IJ.d2s(minAbsTilt,2)+", cosMinAbsTilt="+IJ.d2s(cosMinAbsTilt,2));
//			double axialRange=
			double scanStep=scanStepAxial;
			double overlap=scanOverlapHorizontal;
			int numAxialSteps=(int) Math.ceil((scanLimitAxialHigh-scanLimitAxialLow)*cosMinAbsTilt/scanStepAxial);
@@ -296,8 +320,6 @@ horizontal axis:

			// spread evenly
			if (numAxialSteps>0){ // increase vertical overlap to make it same for all images
//				scanStep=(scanLimitAxialHigh-scanLimitAxialLow)*cosMinAbsTilt/numAxialSteps;
//				overlap=1.0-(scanStep/targetAngleHorizontal);
				scanStep=(scanLimitAxialHigh-scanLimitAxialLow)/numAxialSteps;
				overlap=1.0-(scanStep*cosMinAbsTilt/targetAngleHorizontal);
			}
@@ -322,14 +344,8 @@ horizontal axis:
			  System.out.println();
		  }
		}
//		return true;
		
//	motorsSimultaneous	
// show current tilt/axial
//		double absTiltRange=Math.abs(this.goniometerParameters.scanLimitTiltStart-this.goniometerParameters.scanLimitTiltStart);

		GenericDialog gd = new GenericDialog("Start scanning");
		//	    		this.serialNumber, // camera serial number string
		gd.addMessage("About to start scanning and recording images, parameters are set in the \"Configure Goniometer\" dialog");
		gd.addMessage("Please make sure goniometer motors are set that 0,0 corresponds to the camera in the initial position -");
		gd.addMessage("vertical and cables are not entangled, camera exposure is set correctly.");
@@ -389,7 +405,6 @@ horizontal axis:
			if (this.debugLevel>0) System.out.println(status);
			if (updateStatus) IJ.showStatus(status);
			this.goniometerParameters.motorsSimultaneous=false; // not yet implemented
			//			if (!this.goniometerParameters.motorsSimultaneous){
			OK= this.goniometerParameters.goniometerMotors.moveMotorSetETA(tiltMotor, tiltMotorPosition);
			if (!OK) {
				String msg="Could not set motor "+(tiltMotor+1)+" to move to "+tiltMotorPosition+" - may be out of limit";
@@ -433,10 +448,19 @@ horizontal axis:
				}
				// update motor positions in the image properties, acquire and save images.
				// TODO: Make acquisition/decoding/laser identification multi-threaded

				if (cameras != null) {
					this.cameras.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations
					this.cameras.reportTiming=debugTiming;

					this.cameras.acquire(this.distortionProcessConfiguration.sourceDirectory,true, updateStatus); // true - use lasers, updateStatus - make false?
				} else if (lwirReader != null) {
					this.lwirReader.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations
					this.lwirReader.reportTiming=debugTiming;
					this.lwirReader.acquire(this.distortionProcessConfiguration.sourceDirectory); // true - use lasers, updateStatus - make false?
				} else {
					System.out.println("Neignter traditional camera/rig, no LWIR rig are initialized, dry run");
				}

				this.lastScanStep++;
				if (stopRequested.get()>1){
					if (this.debugLevel>0) System.out.println("User interrupt");
@@ -1185,6 +1209,7 @@ horizontal axis:
			this.scanBidirectional=scanBidirectional;
			this.motorsSimultaneous=motorsSimultaneous;
    	}
    	@Override
		public GoniometerParameters clone(){
    		return new GoniometerParameters(
    				this.goniometerMotors,
+2 −2
Original line number Diff line number Diff line
@@ -4873,10 +4873,10 @@ private Panel panel1,
		if (LWIR_READER == null) {
			LWIR_READER =  new LwirReader(CLT_PARAMETERS.lwir);
		}
        ImagePlus [] imps = LWIR_READER.acquire();
        ImagePlus [] imps = LWIR_READER.acquire("/data_ssd/imagej-elphel/attic/camera_img/test"); // directory to save
		if (imps != null) {
			for (ImagePlus imp: imps) {
				imp.show();
//				imp.show();
			}
		}

+64 −5
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
 */
package com.elphel.imagej.lwir;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Properties;
@@ -40,9 +41,13 @@ import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.elphel.imagej.readers.ImagejJp4Tiff;
import com.elphel.imagej.readers.ImagejJp4TiffMulti;

import ij.IJ;
import ij.ImagePlus;
import ij.Prefs;
import ij.io.FileSaver;
import ij.process.FloatProcessor;
import ij.process.ImageProcessor;
import loci.formats.FormatException;
@@ -68,7 +73,7 @@ public class LwirReader {
	public static final int LWIR_HEIGHT = 120;
	public static final int LWIR_TELEMETRY_LINES = 2;

	public static final int FRAMES_SKIP = 3;
	public static final int FRAMES_SKIP = 4;
	public static final int MAX_THREADS = 100; // combine from all classes?

	/** Logger for this class. */
@@ -82,6 +87,10 @@ public class LwirReader {
	private LwirReaderParameters lwirReaderParameters = null;
	private LwirReaderParameters last_programmed = null;


	private int [] motorsPosition = null;
	public boolean reportTiming=false;

	// -- constructors

	public LwirReader() {
@@ -99,6 +108,15 @@ public class LwirReader {
	}


   	public void setMotorsPosition (int [] position) {
   		this.motorsPosition=position;
   	}

   	public int [] getMotorsPosition() {
   		return this.motorsPosition;  // may be null
   	}


	// TODO: create
	public boolean reSyncNeeded() {
		return out_of_sync;
@@ -220,6 +238,10 @@ public class LwirReader {
				imps_avg[chn].setProperty(key, properties0.getProperty(key));
			}
			imps_avg[chn].setProperty("average", ""+num_frames);
			if (motorsPosition!=null) for (int m=0;m<motorsPosition.length;m++ ) {
				imps_avg[chn].setProperty("MOTOR"+(m+1), ""+motorsPosition[m]);
			}
			ImagejJp4Tiff.encodeProperiesToInfo(imps_avg[chn]);
			// TODO: Overwrite some properties?
		}

@@ -333,10 +355,12 @@ public class LwirReader {
		for (int c : lrp.lwir_channels) {
			channels |= 1 << c;
		}
		String hex_chan = String.format("%x", channels);
		String hex_chan = String.format("0x%x", channels);

		String url = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+
				"&SENSOR_REGS67=0!"+hex_chan;
//		String url = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+
//				"&SENSOR_REGS67=0&*SENSOR_REGS67="+hex_chan;
		Document dom=null;
		LOGGER.warn("calibrate(): Perform calibration (instead of 15 frames), url="+url);
		try {
@@ -415,12 +439,12 @@ public class LwirReader {
		return true;
	}

	public ImagePlus [] acquire() {
		return acquire(lwirReaderParameters);
	public ImagePlus [] acquire(String dirpath) {
		return acquire(lwirReaderParameters, dirpath);
	}


	public ImagePlus [] acquire(LwirReaderParameters lrp) {
	public ImagePlus [] acquire(LwirReaderParameters lrp, String dirpath) {
		if (!condProgramLWIRCamera(lrp)) {
			LOGGER.error("acquire(): failed to program cameras");
			return null;
@@ -439,6 +463,20 @@ public class LwirReader {
			return null;
		}
		LOGGER.debug("LWIR_ACQUIRE: got "+imps.length+" image sets");
// Verify fresh FFC for all channels
		double [] after_ffc = new double [lrp.lwir_channels.length];
		for (int chn = 0; chn < after_ffc.length; chn++) {
			double uptime = Double.NaN, ffctime = Double.NaN;
			try {
				uptime =  Double.parseDouble(((String) imps[0][chn].getProperty("TLM_UPTIME")));
				ffctime = Double.parseDouble(((String) imps[0][chn].getProperty("TLM_FFC_TIME")));
				after_ffc[chn] = uptime-ffctime;
			} catch (Exception e) {
				LOGGER.warn("acquire(): TLM_UPTIME and/or TLM_FFC_TIME properties are not available for"+imps[0][chn].getTitle());
			}
			LOGGER.warn(String.format("LWIR channel %d time from FFC: %.3f", chn, after_ffc[chn]));
		}

		int [] lags = new int [lrp.lwir_channels.length + lrp.vnir_channels.length];
		for (int i = 0; i < lags.length; i++) {
			lags[i] = (i >= lrp.lwir_channels.length) ? lrp.vnir_lag : 0;
@@ -464,6 +502,27 @@ public class LwirReader {
			}
		}
		ImagePlus [] imps_avg = averageMultiFrames(imps_sync);



		if (dirpath != null) {
			File  f_dir = new File(dirpath);
			// get series path from the first channel file title
			String first_name = imps_sync[0][0].getTitle();
			String set_name = first_name.substring(0, first_name.lastIndexOf('_'));
			String set_path = dirpath+Prefs.getFileSeparator()+set_name;
			File  set_dir = new File(set_path);
			set_dir.mkdirs(); // including parent
			for (ImagePlus imp:imps_avg) {
				String fname = imp.getTitle();
				fname = fname.substring(0, fname.lastIndexOf('_')) + ".tiff"; // remove _average
   				FileSaver fs=new FileSaver(imp);
   				String path=set_path+Prefs.getFileSeparator()+fname;
   				IJ.showStatus("Saving "+path);
   				LOGGER.debug("LWIR_ACQUIRE: 'Saving "+path+ " (and other with the same timestamp)" );
   				fs.saveAsTiff(path);
			}
		}
		return imps_avg;
	}