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

preparing for the goniometer with LWIR

parent 47b15645
...@@ -29,12 +29,10 @@ package com.elphel.imagej.calibration; ...@@ -29,12 +29,10 @@ package com.elphel.imagej.calibration;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; 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.cameras.EyesisCameraParameters;
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.lwir.LwirReader;
import ij.IJ; import ij.IJ;
import ij.ImagePlus; import ij.ImagePlus;
...@@ -53,6 +51,7 @@ horizontal axis: ...@@ -53,6 +51,7 @@ horizontal axis:
// for // for
// debugging // debugging
public CalibrationHardwareInterface.CamerasInterface cameras = null; public CalibrationHardwareInterface.CamerasInterface cameras = null;
LwirReader lwirReader = null;
// public CalibrationHardwareInterface.LaserPointers lasers = null; // public CalibrationHardwareInterface.LaserPointers lasers = null;
// public static CalibrationHardwareInterface.FocusingMotors motorsS=null; // public static CalibrationHardwareInterface.FocusingMotors motorsS=null;
// public DistortionProcessConfiguration // public DistortionProcessConfiguration
...@@ -81,7 +80,6 @@ horizontal axis: ...@@ -81,7 +80,6 @@ horizontal axis:
public Goniometer(CalibrationHardwareInterface.CamerasInterface cameras, public Goniometer(CalibrationHardwareInterface.CamerasInterface cameras,
MatchSimulatedPattern.DistortionParameters distortionParametersDefault, MatchSimulatedPattern.DistortionParameters distortionParametersDefault,
// MatchSimulatedPattern.DistortionParameters distortion,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters, MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EyesisCameraParameters eyesisCameraParameters, EyesisCameraParameters eyesisCameraParameters,
MatchSimulatedPattern.LaserPointer laserPointers, MatchSimulatedPattern.LaserPointer laserPointers,
...@@ -98,9 +96,34 @@ horizontal axis: ...@@ -98,9 +96,34 @@ horizontal axis:
this.simulParametersDefault=simulParametersDefault; this.simulParametersDefault=simulParametersDefault;
this.goniometerParameters=goniometerParameters; this.goniometerParameters=goniometerParameters;
this.distortionProcessConfiguration=distortionProcessConfiguration; 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 //goniometerMotors
private enum MOT_ACT { private enum MOT_ACT {
MOVE_SPEC, MOVE_SPEC,
...@@ -222,6 +245,8 @@ horizontal axis: ...@@ -222,6 +245,8 @@ horizontal axis:
if (!OK) System.out.println("motorsMove()->false"); if (!OK) System.out.println("motorsMove()->false");
return true; // OK; // So will re-open dialog even after abort return true; // OK; // So will re-open dialog even after abort
} }
public boolean scanAndAcquire( public boolean scanAndAcquire(
double targetAngleHorizontal, double targetAngleHorizontal,
double targetAngleVertical, double targetAngleVertical,
...@@ -276,7 +301,6 @@ horizontal axis: ...@@ -276,7 +301,6 @@ horizontal axis:
double cosMinAbsTilt=Math.cos(minAbsTilt*Math.PI/180.0); 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)+ 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)); ", minAbsTilt="+IJ.d2s(minAbsTilt,2)+", cosMinAbsTilt="+IJ.d2s(cosMinAbsTilt,2));
// double axialRange=
double scanStep=scanStepAxial; double scanStep=scanStepAxial;
double overlap=scanOverlapHorizontal; double overlap=scanOverlapHorizontal;
int numAxialSteps=(int) Math.ceil((scanLimitAxialHigh-scanLimitAxialLow)*cosMinAbsTilt/scanStepAxial); int numAxialSteps=(int) Math.ceil((scanLimitAxialHigh-scanLimitAxialLow)*cosMinAbsTilt/scanStepAxial);
...@@ -296,8 +320,6 @@ horizontal axis: ...@@ -296,8 +320,6 @@ horizontal axis:
// spread evenly // spread evenly
if (numAxialSteps>0){ // increase vertical overlap to make it same for all images 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; scanStep=(scanLimitAxialHigh-scanLimitAxialLow)/numAxialSteps;
overlap=1.0-(scanStep*cosMinAbsTilt/targetAngleHorizontal); overlap=1.0-(scanStep*cosMinAbsTilt/targetAngleHorizontal);
} }
...@@ -322,14 +344,8 @@ horizontal axis: ...@@ -322,14 +344,8 @@ horizontal axis:
System.out.println(); 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"); 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("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("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."); gd.addMessage("vertical and cables are not entangled, camera exposure is set correctly.");
...@@ -389,7 +405,6 @@ horizontal axis: ...@@ -389,7 +405,6 @@ horizontal axis:
if (this.debugLevel>0) System.out.println(status); if (this.debugLevel>0) System.out.println(status);
if (updateStatus) IJ.showStatus(status); if (updateStatus) IJ.showStatus(status);
this.goniometerParameters.motorsSimultaneous=false; // not yet implemented this.goniometerParameters.motorsSimultaneous=false; // not yet implemented
// if (!this.goniometerParameters.motorsSimultaneous){
OK= this.goniometerParameters.goniometerMotors.moveMotorSetETA(tiltMotor, tiltMotorPosition); OK= this.goniometerParameters.goniometerMotors.moveMotorSetETA(tiltMotor, tiltMotorPosition);
if (!OK) { if (!OK) {
String msg="Could not set motor "+(tiltMotor+1)+" to move to "+tiltMotorPosition+" - may be out of limit"; String msg="Could not set motor "+(tiltMotor+1)+" to move to "+tiltMotorPosition+" - may be out of limit";
...@@ -433,10 +448,19 @@ horizontal axis: ...@@ -433,10 +448,19 @@ horizontal axis:
} }
// update motor positions in the image properties, acquire and save images. // update motor positions in the image properties, acquire and save images.
// TODO: Make acquisition/decoding/laser identification multi-threaded // 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.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations
this.cameras.reportTiming=debugTiming; this.cameras.reportTiming=debugTiming;
this.cameras.acquire(this.distortionProcessConfiguration.sourceDirectory,true, updateStatus); // true - use lasers, updateStatus - make false? 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++; this.lastScanStep++;
if (stopRequested.get()>1){ if (stopRequested.get()>1){
if (this.debugLevel>0) System.out.println("User interrupt"); if (this.debugLevel>0) System.out.println("User interrupt");
...@@ -1185,6 +1209,7 @@ horizontal axis: ...@@ -1185,6 +1209,7 @@ horizontal axis:
this.scanBidirectional=scanBidirectional; this.scanBidirectional=scanBidirectional;
this.motorsSimultaneous=motorsSimultaneous; this.motorsSimultaneous=motorsSimultaneous;
} }
@Override
public GoniometerParameters clone(){ public GoniometerParameters clone(){
return new GoniometerParameters( return new GoniometerParameters(
this.goniometerMotors, this.goniometerMotors,
......
...@@ -4873,10 +4873,10 @@ private Panel panel1, ...@@ -4873,10 +4873,10 @@ private Panel panel1,
if (LWIR_READER == null) { if (LWIR_READER == null) {
LWIR_READER = new LwirReader(CLT_PARAMETERS.lwir); 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) { if (imps != null) {
for (ImagePlus imp: imps) { for (ImagePlus imp: imps) {
imp.show(); // imp.show();
} }
} }
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
*/ */
package com.elphel.imagej.lwir; package com.elphel.imagej.lwir;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.util.Properties; import java.util.Properties;
...@@ -40,9 +41,13 @@ import org.slf4j.LoggerFactory; ...@@ -40,9 +41,13 @@ import org.slf4j.LoggerFactory;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import com.elphel.imagej.readers.ImagejJp4Tiff;
import com.elphel.imagej.readers.ImagejJp4TiffMulti; import com.elphel.imagej.readers.ImagejJp4TiffMulti;
import ij.IJ;
import ij.ImagePlus; import ij.ImagePlus;
import ij.Prefs;
import ij.io.FileSaver;
import ij.process.FloatProcessor; import ij.process.FloatProcessor;
import ij.process.ImageProcessor; import ij.process.ImageProcessor;
import loci.formats.FormatException; import loci.formats.FormatException;
...@@ -68,7 +73,7 @@ public class LwirReader { ...@@ -68,7 +73,7 @@ public class LwirReader {
public static final int LWIR_HEIGHT = 120; public static final int LWIR_HEIGHT = 120;
public static final int LWIR_TELEMETRY_LINES = 2; 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? public static final int MAX_THREADS = 100; // combine from all classes?
/** Logger for this class. */ /** Logger for this class. */
...@@ -82,6 +87,10 @@ public class LwirReader { ...@@ -82,6 +87,10 @@ public class LwirReader {
private LwirReaderParameters lwirReaderParameters = null; private LwirReaderParameters lwirReaderParameters = null;
private LwirReaderParameters last_programmed = null; private LwirReaderParameters last_programmed = null;
private int [] motorsPosition = null;
public boolean reportTiming=false;
// -- constructors // -- constructors
public LwirReader() { public LwirReader() {
...@@ -99,6 +108,15 @@ public class 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 // TODO: create
public boolean reSyncNeeded() { public boolean reSyncNeeded() {
return out_of_sync; return out_of_sync;
...@@ -220,6 +238,10 @@ public class LwirReader { ...@@ -220,6 +238,10 @@ public class LwirReader {
imps_avg[chn].setProperty(key, properties0.getProperty(key)); imps_avg[chn].setProperty(key, properties0.getProperty(key));
} }
imps_avg[chn].setProperty("average", ""+num_frames); 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? // TODO: Overwrite some properties?
} }
...@@ -333,10 +355,12 @@ public class LwirReader { ...@@ -333,10 +355,12 @@ public class LwirReader {
for (int c : lrp.lwir_channels) { for (int c : lrp.lwir_channels) {
channels |= 1 << c; 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+ String url = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+
"&SENSOR_REGS67=0!"+hex_chan; "&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; Document dom=null;
LOGGER.warn("calibrate(): Perform calibration (instead of 15 frames), url="+url); LOGGER.warn("calibrate(): Perform calibration (instead of 15 frames), url="+url);
try { try {
...@@ -415,12 +439,12 @@ public class LwirReader { ...@@ -415,12 +439,12 @@ public class LwirReader {
return true; return true;
} }
public ImagePlus [] acquire() { public ImagePlus [] acquire(String dirpath) {
return acquire(lwirReaderParameters); return acquire(lwirReaderParameters, dirpath);
} }
public ImagePlus [] acquire(LwirReaderParameters lrp) { public ImagePlus [] acquire(LwirReaderParameters lrp, String dirpath) {
if (!condProgramLWIRCamera(lrp)) { if (!condProgramLWIRCamera(lrp)) {
LOGGER.error("acquire(): failed to program cameras"); LOGGER.error("acquire(): failed to program cameras");
return null; return null;
...@@ -439,6 +463,20 @@ public class LwirReader { ...@@ -439,6 +463,20 @@ public class LwirReader {
return null; return null;
} }
LOGGER.debug("LWIR_ACQUIRE: got "+imps.length+" image sets"); 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]; int [] lags = new int [lrp.lwir_channels.length + lrp.vnir_channels.length];
for (int i = 0; i < lags.length; i++) { for (int i = 0; i < lags.length; i++) {
lags[i] = (i >= lrp.lwir_channels.length) ? lrp.vnir_lag : 0; lags[i] = (i >= lrp.lwir_channels.length) ? lrp.vnir_lag : 0;
...@@ -464,6 +502,27 @@ public class LwirReader { ...@@ -464,6 +502,27 @@ public class LwirReader {
} }
} }
ImagePlus [] imps_avg = averageMultiFrames(imps_sync); 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; return imps_avg;
} }
......
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