Commit 016b8b7c authored by Andrey Filippov's avatar Andrey Filippov

Acquiring images sets with LWIR16

parent 57a60fb7
...@@ -27,6 +27,14 @@ ...@@ -27,6 +27,14 @@
<description>A Maven project implementing imagej-elphel plugin</description> <description>A Maven project implementing imagej-elphel plugin</description>
<dependencies> <dependencies>
<!-- ssh support - see https://www.baeldung.com/java-ssh-connection -->
<!-- https://mvnrepository.com/artifact/org.apache.sshd/sshd-core -->
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency> <dependency>
<groupId>net.imagej</groupId> <groupId>net.imagej</groupId>
<artifactId>ij</artifactId> <artifactId>ij</artifactId>
......
...@@ -73,6 +73,7 @@ import com.elphel.imagej.common.PolynomialApproximation; ...@@ -73,6 +73,7 @@ import com.elphel.imagej.common.PolynomialApproximation;
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 com.elphel.imagej.lwir.Lwir16Reader;
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 com.elphel.imagej.readers.EyesisTiff;
...@@ -108,6 +109,7 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene ...@@ -108,6 +109,7 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
private Panel panelGoniometer; private Panel panelGoniometer;
private Panel panelPixelMapping, panelStereo,panelStereo1; private Panel panelPixelMapping, panelStereo,panelStereo1;
private Panel panelLWIR; private Panel panelLWIR;
private Panel panelLWIR16;
private ShowDoubleFloatArrays SDFA_INSTANCE; // just for debugging? private ShowDoubleFloatArrays SDFA_INSTANCE; // just for debugging?
JP46_Reader_camera JP4_INSTANCE; JP46_Reader_camera JP4_INSTANCE;
...@@ -289,6 +291,7 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene ...@@ -289,6 +291,7 @@ public class Aberration_Calibration extends PlugInFrame implements ActionListene
); );
public static LwirReader LWIR_READER = null; public static LwirReader LWIR_READER = null;
public static Lwir16Reader LWIR16_READER = null;
public static ProcessCalibrationFilesParameters PROCESS_PARAMETERS = new ProcessCalibrationFilesParameters( public static ProcessCalibrationFilesParameters PROCESS_PARAMETERS = new ProcessCalibrationFilesParameters(
...@@ -650,9 +653,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi ...@@ -650,9 +653,7 @@ public static MatchSimulatedPattern.DistortionParameters DISTORTION =new MatchSi
public static Goniometer GONIOMETER=null; public static Goniometer GONIOMETER=null;
public static LwirReaderParameters LWIR_PARAMETERS=new LwirReaderParameters(); public static LwirReaderParameters LWIR_PARAMETERS = new LwirReaderParameters();
// new CalibrationHardwareInterface.LaserPointers(); // new CalibrationHardwareInterface.LaserPointers();
public class SyncCommand{ public class SyncCommand{
...@@ -1030,6 +1031,11 @@ if (MORE_BUTTONS) { ...@@ -1030,6 +1031,11 @@ if (MORE_BUTTONS) {
panelLWIR.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap panelLWIR.setLayout(new GridLayout(1, 0, 5, 5)); // rows, columns, vgap, hgap
addButton("LWIR Configure", panelLWIR,color_configure); addButton("LWIR Configure", panelLWIR,color_configure);
addButton("LWIR_TEST", panelLWIR, color_conf_process); addButton("LWIR_TEST", panelLWIR, color_conf_process);
addButton("CMPRS_STOP", panelLWIR, color_stop);
addButton("CMPRS_START", panelLWIR, color_process);
addButton("LWIR_FFC", panelLWIR, color_conf_process);
addButton("RST BUFs", panelLWIR, color_stop);
addButton("LWIR_ACQUIRE", panelLWIR, color_conf_process); addButton("LWIR_ACQUIRE", panelLWIR, color_conf_process);
addButton("Configure Goniometer", panelLWIR,color_configure); addButton("Configure Goniometer", panelLWIR,color_configure);
addButton("Goniometer Move", panelLWIR,color_debug); addButton("Goniometer Move", panelLWIR,color_debug);
...@@ -1041,8 +1047,8 @@ if (MORE_BUTTONS) { ...@@ -1041,8 +1047,8 @@ if (MORE_BUTTONS) {
addButton("EO Offsets", panelLWIR,color_process); addButton("EO Offsets", panelLWIR,color_process);
addButton("LWIR to EO", panelLWIR,color_process); addButton("LWIR to EO", panelLWIR,color_process);
addButton("Manual hint", panelLWIR,color_configure); addButton("Manual hint", panelLWIR,color_configure);
add(panelLWIR); add(panelLWIR);
pack(); pack();
GUI.center(this); GUI.center(this);
setVisible(true); setVisible(true);
...@@ -9284,30 +9290,96 @@ if (MORE_BUTTONS) { ...@@ -9284,30 +9290,96 @@ if (MORE_BUTTONS) {
LWIR_PARAMETERS.showJDialog(); LWIR_PARAMETERS.showJDialog();
return; return;
} }
//startStopCompressor(LwirReaderParameters lrp, boolean start, double delay)
//condProgramLWIRCamera()
/* ======================================================================== */
if (label.equals("CMPRS_START") || label.equals("CMPRS_STOP")) {
boolean start = label.equals("CMPRS_START");
if (LWIR_PARAMETERS.isLwir16()) {
if (LWIR16_READER == null) {
LWIR16_READER = new Lwir16Reader(LWIR_PARAMETERS);
}
LWIR16_READER.condProgramLWIRCamera();
double delay = 3.0;
LWIR16_READER.startStopCompressor(LWIR_PARAMETERS, start, delay);
}
return;
}
/* ======================================================================== */
if (label.equals("LWIR_FFC")) {
if (LWIR_PARAMETERS.isLwir16()) {
if (LWIR16_READER == null) {
LWIR16_READER = new Lwir16Reader(LWIR_PARAMETERS);
}
LWIR16_READER.condProgramLWIRCamera();
int skip_frames = 0; // 300; // 5 second to come to the camera, remove later
if (skip_frames > 0) {
LWIR16_READER.skipMasterFrames(new String[] {LWIR_PARAMETERS.getLwirIP(0)}, skip_frames);
}
LWIR16_READER.runFFC(LWIR_PARAMETERS);
}
return;
}
/* ======================================================================== */
if (label.equals("RST BUFs")) {
if (LWIR_PARAMETERS.isLwir16()) {
if (LWIR16_READER == null) {
LWIR16_READER = new Lwir16Reader(LWIR_PARAMETERS);
}
LWIR16_READER.condProgramLWIRCamera();
LWIR16_READER.resetFrameBuffers(LWIR_PARAMETERS);
}
return;
}
/* ======================================================================== */ /* ======================================================================== */
//
if (label.equals("LWIR_TEST")) { if (label.equals("LWIR_TEST")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// public static LwirReader LWIR_READER = null; // public static LwirReader LWIR_READER = null;
if (LWIR_READER == null) { ImagePlus [][] imps;
LWIR_READER = new LwirReader(LWIR_PARAMETERS); if (LWIR_PARAMETERS.isLwir16()) {
} if (LWIR16_READER == null) {
ImagePlus [][] imps = LWIR_READER.readAllMultiple( LWIR16_READER = new Lwir16Reader(LWIR_PARAMETERS);
}
LWIR16_READER.programLWIRCamera(LWIR_PARAMETERS);
if (DEBUG_LEVEL <1000) {
return;
}
imps = LWIR16_READER.readAllMultiple(
LWIR_PARAMETERS.getNumFrames(), // 10, // final int num_frames, LWIR_PARAMETERS.getNumFrames(), // 10, // final int num_frames,
// true, // use LWIR telemetry // true, // use LWIR telemetry
true, // final boolean show, true, // final boolean show,
false); // true); // final boolean scale) false); // true); // final boolean scale)
} else {
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS);
}
imps = LWIR_READER.readAllMultiple(
LWIR_PARAMETERS.getNumFrames(), // 10, // final int num_frames,
// true, // use LWIR telemetry
true, // final boolean show,
false); // true); // final boolean scale)
}
for (ImagePlus imp: imps[0]) { for (ImagePlus imp: imps[0]) {
imp.show(); imp.show();
} }
System.out.println("LWIR_TEST: got "+imps.length+" image sets"); System.out.println("LWIR_TEST: got "+imps.length+" image sets");
ImagePlus [][] imps_sync = LWIR_READER.matchSets(imps, 0.001, 3); // double max_mismatch) if (LWIR_PARAMETERS.isLwir16()) {
if (imps_sync != null) { // will probably not needed for Bosons
ImagePlus [] imps_avg = LWIR_READER.averageMultiFrames(imps_sync); ImagePlus [][] imps_sync = LWIR16_READER.matchSets(imps, 0.001, 3); // double max_mismatch)
for (ImagePlus imp: imps_avg) { if (imps_sync != null) {
imp.show(); ImagePlus [] imps_avg = LWIR16_READER.averageMultiFrames(imps_sync);
for (ImagePlus imp: imps_avg) {
imp.show();
}
}
} else {
ImagePlus [][] imps_sync = LWIR_READER.matchSets(imps, 0.001, 3); // double max_mismatch)
if (imps_sync != null) {
ImagePlus [] imps_avg = LWIR_READER.averageMultiFrames(imps_sync);
for (ImagePlus imp: imps_avg) {
imp.show();
}
} }
} }
return; return;
...@@ -9315,43 +9387,62 @@ if (MORE_BUTTONS) { ...@@ -9315,43 +9387,62 @@ if (MORE_BUTTONS) {
/* ======================================================================== */ /* ======================================================================== */
if (label.equals("LWIR_ACQUIRE")) { if (label.equals("LWIR_ACQUIRE")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
// public static LwirReader LWIR_READER = null; ImagePlus [][] imps;
if (LWIR_READER == null) { if (LWIR_PARAMETERS.isLwir16()) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS); if (LWIR16_READER == null) {
LWIR16_READER = new Lwir16Reader(LWIR_PARAMETERS);
}
// ImagePlus [] imps =
LWIR16_READER.acquire(DISTORTION_PROCESS_CONFIGURATION.sourceDirectory); // directory to save
// ImagePlus [] imps = LWIR_READER.acquire("attic/lwir_test_images"); // directory to save
} else {
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS);
}
// ImagePlus [] imps =
LWIR_READER.acquire(DISTORTION_PROCESS_CONFIGURATION.sourceDirectory); // directory to save
// ImagePlus [] imps = LWIR_READER.acquire("attic/lwir_test_images"); // directory to save
} }
// ImagePlus [] imps =
LWIR_READER.acquire(DISTORTION_PROCESS_CONFIGURATION.sourceDirectory); // directory to save
// ImagePlus [] imps = LWIR_READER.acquire("attic/lwir_test_images"); // directory to save
return; return;
} }
/* ======================================================================== */ /* ======================================================================== */
if (label.equals("LWIR Goniometer")) { if (label.equals("LWIR Goniometer")) {
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
if ((GONIOMETER==null) || (LWIR_PARAMETERS.isLwir16()?(GONIOMETER.lwir16Reader == null):(GONIOMETER.lwirReader == null))) {
if (LWIR_PARAMETERS.isLwir16()) {
if (LWIR16_READER == null) {
LWIR16_READER = new Lwir16Reader(LWIR_PARAMETERS);
}
GONIOMETER= new Goniometer(
LWIR16_READER,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
DISTORTION_PROCESS_CONFIGURATION);
} else {
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS);
}
GONIOMETER= new Goniometer(
LWIR_READER,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
DISTORTION_PROCESS_CONFIGURATION);
// CAMERAS.setNumberOfThreads(THREADS_MAX);
// CAMERAS.debugLevel=DEBUG_LEVEL;
if ((GONIOMETER==null) || (GONIOMETER.lwirReader == null)) {
if (LWIR_READER == null) {
LWIR_READER = new LwirReader(LWIR_PARAMETERS);
} }
GONIOMETER= new Goniometer(
LWIR_READER,
// CAMERAS, // CalibrationHardwareInterface.CamerasInterface cameras,
DISTORTION, //MatchSimulatedPattern.DistortionParameters distortion,
PATTERN_DETECT, //MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EYESIS_CAMERA_PARAMETERS, //EyesisCameraParameters eyesisCameraParameters,
LASER_POINTERS, // MatchSimulatedPattern.LaserPointer laserPointers
SIMUL, //SimulationPattern.SimulParameters simulParametersDefault,
GONIOMETER_PARAMETERS, //LensAdjustment.FocusMeasurementParameters focusMeasurementParameters,
DISTORTION_PROCESS_CONFIGURATION
);
if (DEBUG_LEVEL>1){ if (DEBUG_LEVEL>1){
System.out.println("Initiaslizing Goniometer class"); System.out.println("Initialized Goniometer class for "+LWIR_PARAMETERS.getCameraName());
} }
} else if (DEBUG_LEVEL>1){ } else if (DEBUG_LEVEL>1){
System.out.println("GONIOMETER was initialized"); System.out.println("GONIOMETER was initialized for "+LWIR_PARAMETERS.getCameraName());
} }
// calculate angular size of the target as visible from the camera // calculate angular size of the target as visible from the camera
...@@ -9435,9 +9526,8 @@ if (MORE_BUTTONS) { ...@@ -9435,9 +9526,8 @@ if (MORE_BUTTONS) {
lwirToEo(); lwirToEo();
return; return;
} }
/* ======================================================================== */ /* ======================================================================== */
IJ.showMessage("Not yet implemented"); IJ.showMessage("Not yet implemented");
DEBUG_LEVEL=MASTER_DEBUG_LEVEL; DEBUG_LEVEL=MASTER_DEBUG_LEVEL;
return; return;
...@@ -34,6 +34,7 @@ import com.elphel.imagej.calibration.hardware.GoniometerMotors; ...@@ -34,6 +34,7 @@ import com.elphel.imagej.calibration.hardware.GoniometerMotors;
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.Lwir16Reader;
import com.elphel.imagej.lwir.LwirReader; import com.elphel.imagej.lwir.LwirReader;
import ij.IJ; import ij.IJ;
...@@ -53,7 +54,8 @@ horizontal axis: ...@@ -53,7 +54,8 @@ horizontal axis:
// for // for
// debugging // debugging
public CamerasInterface cameras = null; public CamerasInterface cameras = null;
public LwirReader lwirReader = null; public LwirReader lwirReader = null;
public Lwir16Reader lwir16Reader = 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
...@@ -123,6 +125,28 @@ horizontal axis: ...@@ -123,6 +125,28 @@ horizontal axis:
this.distortionProcessConfiguration=distortionProcessConfiguration; this.distortionProcessConfiguration=distortionProcessConfiguration;
} }
public Goniometer(
Lwir16Reader lwir16Reader,
// CalibrationHardwareInterface.CamerasInterface cameras,
MatchSimulatedPattern.DistortionParameters distortionParametersDefault,
MatchSimulatedPattern.PatternDetectParameters patternDetectParameters,
EyesisCameraParameters eyesisCameraParameters,
LaserPointer laserPointers,
SimulationPattern.SimulParameters simulParametersDefault,
Goniometer.GoniometerParameters goniometerParameters,
DistortionProcessConfiguration distortionProcessConfiguration
) {
this.lwir16Reader= lwir16Reader;
// 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;
}
...@@ -459,6 +483,10 @@ horizontal axis: ...@@ -459,6 +483,10 @@ horizontal axis:
this.lwirReader.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations this.lwirReader.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations
this.lwirReader.reportTiming=debugTiming; this.lwirReader.reportTiming=debugTiming;
this.lwirReader.acquire(this.distortionProcessConfiguration.sourceDirectory); // true - use lasers, updateStatus - make false? this.lwirReader.acquire(this.distortionProcessConfiguration.sourceDirectory); // true - use lasers, updateStatus - make false?
} else if (lwir16Reader != null) {
this.lwir16Reader.setMotorsPosition(this.goniometerParameters.goniometerMotors.getTargetPositions()); // Used target, not current to prevent minor variations
this.lwir16Reader.reportTiming=debugTiming;
this.lwir16Reader.acquire(this.distortionProcessConfiguration.sourceDirectory); // true - use lasers, updateStatus - make false?
} else { } else {
System.out.println("Neignter traditional camera/rig, no LWIR rig are initialized, dry run"); System.out.println("Neignter traditional camera/rig, no LWIR rig are initialized, dry run");
} }
......
...@@ -4793,7 +4793,7 @@ public class MatchSimulatedPattern { ...@@ -4793,7 +4793,7 @@ public class MatchSimulatedPattern {
// process // process
final double[] bPattern, final double[] windowFunction, final double[] windowFunctionCorr, final double[] bPattern, final double[] windowFunction, final double[] windowFunctionCorr,
final double[] windowFunctionCorr2, final double[] windowFunctionCorr4, final double[][] locsNeib, // which final double[] windowFunctionCorr2, final double[] windowFunctionCorr4, final double[][] locsNeib, // which
// neibors // neighbors
// to // to
// try // try
// (here // (here
...@@ -6919,6 +6919,8 @@ public class MatchSimulatedPattern { ...@@ -6919,6 +6919,8 @@ public class MatchSimulatedPattern {
noMessageBoxes); noMessageBoxes);
} }
// ====== end of calculateDistortions() // ====== end of calculateDistortions()
// ============================================== // ==============================================
/** /**
......
...@@ -318,7 +318,7 @@ public class GenericJTabbedDialog implements ActionListener { ...@@ -318,7 +318,7 @@ public class GenericJTabbedDialog implements ActionListener {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand()); // System.out.println(e.getActionCommand());
if (e.getActionCommand().equals("Cancel")) { if (e.getActionCommand().equals("Cancel")) {
result = e.getActionCommand(); result = e.getActionCommand();
jd.dispose(); jd.dispose();
...@@ -409,7 +409,7 @@ public class GenericJTabbedDialog implements ActionListener { ...@@ -409,7 +409,7 @@ public class GenericJTabbedDialog implements ActionListener {
} }
System.out.println(combo.getSelectedItem()); // System.out.println(combo.getSelectedItem());
// for (int i = 0; i < selectedItem.length; i++){ // for (int i = 0; i < selectedItem.length; i++){
// System.out.println(String.format("item %s = %s", i, selectedItem[i])); // System.out.println(String.format("item %s = %s", i, selectedItem[i]));
// } // }
......
/**
** -----------------------------------------------------------------------------**
** Lwir16Reader.java
**
** Multithreaded reading cameras - visible and LWIR
**
**
** Copyright (C) 2019 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** Lwir16Reader.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package com.elphel.imagej.lwir;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
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;
public class Lwir16Reader {
public static String [] BASE_URLS= {
"http://192.168.0.41:2323/bchn0",
"http://192.168.0.41:2324/bchn0",
"http://192.168.0.41:2325/bchn0",
"http://192.168.0.41:2326/bchn0",
"http://192.168.0.42:2323/bchn4",
"http://192.168.0.42:2324/bchn4",
"http://192.168.0.42:2325/bchn4",
"http://192.168.0.42:2326/bchn4",
"http://192.168.0.43:2323/bchn8",
"http://192.168.0.43:2324/bchn8",
"http://192.168.0.43:2325/bchn8",
"http://192.168.0.43:2326/bchn8",
"http://192.168.0.44:2323/bchn12",
"http://192.168.0.44:2324/bchn12",
"http://192.168.0.44:2325/bchn12",
"http://192.168.0.44:2326/bchn12",
"http://192.168.0.45:2323/bchn16",
"http://192.168.0.45:2324/bchn16",
"http://192.168.0.45:2325/bchn16",
"http://192.168.0.45:2326/bchn16",
};
public static final int [] IMGSRV_PORTS = {2323,2324,2325,2326};
public static final String IMAGE_URL_STATUS="/pointers"; // get current status
public static final String IMAGE_URL_RESET= "/towp/save/xframe"; // reset read pointer while compressors are stopped
// public static final String IMAGE_URL_META= "/torp/next/wait/meta"; // wait for frame at current read poiter and read meta
// public static final String IMAGE_URL_NEXT= "/torp/next/wait/img/save"; // same image name, same image number/time
public static final String IMAGE_URL_NEXT= "/torp/wait/img/next/save"; // same image name, same image number/time
public static final String SCRIPT_CAPTURE= "capture_range.php"; // capture synchronized images
public static final String SCRIPT_RESET= "reset_frames.php"; // Reset frame numbers
public static final String SCRIPT_WAIT= "wait_frame.php"; // wait for absolute frame (positive) or skip frames (nefative)
// will remove later
public static final String IMAGE_URL_FIRST="/towp/wait/img/save"; // next image name, same image number/time
public static final String SKIP_FRAME_URL= "/towp/wait/meta"; // Wait for the next frame, return meta data
public static final String REG_FFC_FRAMES= "SENSOR_REGS4"; // Register for the number of FFC frames to integrate
public static final String REG_FFC_RUN= "SENSOR_REGS26"; // Register to trigger FFC
// public static final String SKIP_FRAME_URL= "/towp/wait/meta"; // Wait for the next frame, return meta data
public static final int COLOR_JP4 = 5;
public static final int COLOR_RAW = 15;
public static final int LWIR_HEIGHT = 512;
public static final int LWIR_TELEMETRY_LINES = 1;
public static final int FRAMES_SKIP = 4;
public static final int MAX_THREADS = 100; // combine from all classes?
public static final int FRAMES_AHEAD = 5;
/** Logger for this class. */
private static final Logger LOGGER =
LoggerFactory.getLogger(LwirReader.class);
private ImagejJp4TiffMulti imagejJp4TiffMulti;
private boolean out_of_sync = false;
/** Configuration parameters */
private LwirReaderParameters lwirReaderParameters = null;
private LwirReaderParameters last_programmed = null;
private int [] motorsPosition = null;
public boolean reportTiming=false;
// -- constructors
public Lwir16Reader() {
this.lwirReaderParameters = new LwirReaderParameters(LwirReaderParameters.NAME_LWIR16); // default
imagejJp4TiffMulti = null;
}
public Lwir16Reader(LwirReaderParameters lwirReaderParameters) {
if (lwirReaderParameters == null) {
this.lwirReaderParameters = new LwirReaderParameters(LwirReaderParameters.NAME_LWIR16); // default
} else {
this.lwirReaderParameters = lwirReaderParameters;
}
imagejJp4TiffMulti = null;
}
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;
}
public ImagePlus[][] readAllMultiple(
final int num_frames,
// final boolean telemetry,
final boolean show,
final boolean scale) {
return readAllMultiple(num_frames, show, scale, "STD_");
// return readAllMultiple(num_frames, telemetry, show, scale, "STD_");
}
public ImagePlus[][] readAllMultiple(
final int num_frames,
// final boolean telemetry,
final boolean show,
final boolean scale,
final String std)
{
String [] urls0 = new String[BASE_URLS.length];
String [] urls1 = new String[BASE_URLS.length];
ImagePlus [][] imps = new ImagePlus[num_frames][BASE_URLS.length];
for (int i = 0; i < BASE_URLS.length; i++) {
urls0[i] = BASE_URLS[i] + IMAGE_URL_FIRST;
urls1[i] = BASE_URLS[i] + IMAGE_URL_NEXT;
}
if (imagejJp4TiffMulti == null) {
imagejJp4TiffMulti = new ImagejJp4TiffMulti();
for (int i = 0; i < 2; i++) {
try {
// imagejJp4TiffMulti.getMultiImages(urls0, imps[0], telemetry, scale, std);
imagejJp4TiffMulti.getMultiImages(urls0, imps[0], scale, std);
} catch (IOException e) {
LOGGER.error("readAllMultiple0: IOException, priming" );
} catch (FormatException e) {
LOGGER.error("readAllMultiple0:FormatException, priming");
}
LOGGER.info("priming..."+(i+1));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
for (int n = 0; n < num_frames; n++) {
LOGGER.info("---- Acquiring frame set "+n);
try {
// imagejJp4TiffMulti.getMultiImages( (n==0)? urls0:urls1, imps[n], telemetry, scale, std);
imagejJp4TiffMulti.getMultiImages( (n==0)? urls0:urls1, imps[n], scale, std);
} catch (IOException e) {
LOGGER.error("readAllMultiple0: IOException, n = " + n);
} catch (FormatException e) {
LOGGER.error("readAllMultiple0:FormatException, n = " + n);
}
}
double [][] img_seconds = new double [num_frames][BASE_URLS.length];
int [][] img_numbers = new int [num_frames][BASE_URLS.length];
String [][] img_names = new String [num_frames][BASE_URLS.length];
for (int n = 0; n < num_frames; n++) {
for (int i = 0; i < imps[n].length; i++) {
String dt = null;
try {
dt = (String) imps[n][i].getProperty("DATE_TIME");
} catch (Exception e) {
LOGGER.error("Something is wrong!");
}
if (dt==null) {
System.out.println("n="+n+", i="+i+", dt is NULL! (may need to reduce number of acquire images to "+(n-1));
}
// System.out.println("n="+n+", i="+i+", dt="+dt);
img_seconds[n][i] = Double.parseDouble(dt.substring(dt.lastIndexOf(":")+1));
try {
img_numbers[n][i] = Integer.parseInt((String) imps[n][i].getProperty("STD_Image_Number"));
} catch (Exception e) {
img_numbers[n][i] = -1;
}
img_names[n][i] = (String) imps[n][i].getProperty("CONTENT_FILENAME");
LOGGER.warn("Seconds for" + n+":"+i+" - "+img_seconds[n][i]+", number"+img_numbers[n][i]+", name "+img_names[n][i]);
}
}
for (ImagePlus [] imp_sets :imps) {
for (ImagePlus imp: imp_sets) {
// imp.show();
}
}
return imps;
}
public ImagePlus [] averageMultiFrames(
final ImagePlus [][] sets) {
final int num_frames = sets.length;
final int num_channels = sets[0].length;
final ImagePlus [] imps_avg = new ImagePlus [num_channels];
final Thread[] threads = newThreadArray(MAX_THREADS);
final AtomicInteger indxAtomic = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int chn = indxAtomic.getAndIncrement(); chn < num_channels; chn = indxAtomic.getAndIncrement())
{
int width = sets[0][chn].getWidth();
int height = sets[0][chn].getHeight();
String title = sets[0][chn].getTitle()+"_average"+num_frames;
float [] pixels_avg = (float []) sets[0][chn].getProcessor().getPixels(); //null pointer
for (int n = 1; n < num_frames; n++) {
float [] pixels = (float []) sets[n][chn].getProcessor().getPixels();
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] += pixels[i];
}
}
double scale = 1.0/num_frames;
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] *= scale;
}
ImageProcessor ip=new FloatProcessor(width,height);
ip.setPixels(pixels_avg);
ip.resetMinAndMax();
imps_avg[chn]= new ImagePlus(title, ip);
Properties properties0 = sets[0][chn].getProperties();
for (String key:properties0.stringPropertyNames()) {
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]);
}
}
};
}
startAndJoin(threads);
/*
for (int chn = 0; chn < num_channels; chn++) {
int width = sets[0][chn].getWidth();
int height = sets[0][chn].getHeight();
String title = sets[0][chn].getTitle()+"_average"+num_frames;
float [] pixels_avg = (float []) sets[0][chn].getProcessor().getPixels(); //null pointer
for (int n = 1; n < num_frames; n++) {
float [] pixels = (float []) sets[n][chn].getProcessor().getPixels();
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] += pixels[i];
}
}
double scale = 1.0/num_frames;
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] *= scale;
}
ImageProcessor ip=new FloatProcessor(width,height);
ip.setPixels(pixels_avg);
ip.resetMinAndMax();
imps_avg[chn]= new ImagePlus(title, ip);
Properties properties0 = sets[0][chn].getProperties();
for (String key:properties0.stringPropertyNames()) {
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?
}
*/
return imps_avg;
}
public ImagePlus [][] matchSets(ImagePlus [][] sets, double max_mismatch, int max_frame_diff){
return matchSets(sets, max_mismatch, max_frame_diff, null);
}
public ImagePlus [][] matchSets(ImagePlus [][] sets, double max_mismatch, int max_frame_diff, int [] lags){
int num_frames = sets.length;
int num_channels = sets[0].length;
double [][] img_seconds = new double [num_frames][num_channels];
int [] frame_offsets = new int[num_channels];
double [] time_offsets = new double [num_channels];
boolean some_notsynced = false;
int fr_min = 0, fr_max = 0;
frame_offsets[0] = 0;
for (int n = 0; n < num_frames; n++) {
for (int i = 0; i < num_channels; i++) {
String dt = (String) sets[n][i].getProperty("DATE_TIME");
img_seconds[n][i] = Double.parseDouble(dt.substring(dt.lastIndexOf(":")+1));
}
}
for (int i = 1; i < num_channels; i++) { // compare all to the first channel
frame_offsets[i] = 0;
time_offsets[i] = secOffs(img_seconds[0][0], img_seconds[0][i]);
if (num_frames > max_frame_diff) {
if (time_offsets[i] > max_mismatch) {
for (int fr_diff = 1; fr_diff <= max_frame_diff; fr_diff++) {
double aoff = secOffs(img_seconds[fr_diff][0], img_seconds[0][i]);
if (aoff < time_offsets[i]) {
time_offsets[i] = aoff;
frame_offsets[i] = fr_diff; // second channel starts later, than [0]
}
if (time_offsets[i] <=max_mismatch) break;
aoff = secOffs(img_seconds[0][0], img_seconds[fr_diff][i]);
if (aoff < time_offsets[i]) {
time_offsets[i] = aoff;
frame_offsets[i] = -fr_diff; // second channel starts earlier, than [0]
}
if (time_offsets[i] <=max_mismatch) break;
}
}
}
if (time_offsets[i] > max_mismatch) {
some_notsynced = true;
}
if (frame_offsets[i] > fr_max) fr_max = frame_offsets[i];
if (frame_offsets[i] < fr_min) fr_min = frame_offsets[i];
}
if (some_notsynced) {
LOGGER.error("*** Some channels are not synchronized, reboot or sensors re-start is needed ***");
out_of_sync = true;
for (int i = 0; i < num_channels; i++) {
LOGGER.error("Channel "+ i+" frame offset="+frame_offsets[i]+ ", time offset = "+time_offsets[i]+" sec");
}
return null;
}
if (((fr_max - fr_min) > max_frame_diff) || ((fr_max - fr_min) > (num_frames - 1))) {
out_of_sync = true;
LOGGER.error("*** Earliest/latest channels differ by more than "+max_frame_diff+" frames, that should not happen! ***");
for (int i = 0; i < num_channels; i++) {
LOGGER.error("Channel "+ i+" frame offset="+frame_offsets[i]+ ", time offset = "+time_offsets[i]+" sec");
}
return null;
}
out_of_sync = false;
for (int i = 0; i < num_channels; i++) {
// change to info later:
LOGGER.warn("Channel "+ i+" frame offset="+frame_offsets[i]+ ", time offset = "+time_offsets[i]+" sec");
}
// if (lags == null) lags = new int [num_channels];
// recalculate frame_offsets, fr_max, fr_min considering provided lags (>0 - channel images are acquired later)
if (lags != null) {
fr_max = lags[0];
fr_min = lags[0];
for (int i = 0; i < num_channels; i++ ) {
frame_offsets[i] += lags[i];
if (frame_offsets[i] > fr_max) fr_max = frame_offsets[i];
if (frame_offsets[i] < fr_min) fr_min = frame_offsets[i];
}
}
ImagePlus [][] imps_synced = null;
imps_synced = new ImagePlus [num_frames - fr_max + fr_min][num_channels];
for (int n = 0; n < imps_synced.length; n++) {
for (int i = 0; i < num_channels; i++) {
imps_synced[n][i]= sets[n + fr_max -frame_offsets[i]][i];
}
}
return imps_synced;
}
public boolean calibrate(LwirReaderParameters lrp) {
// FFC takes 15 frames that are not output (so no need to check operation is over)
if (lrp.lwir_channels.length == 0) {
LOGGER.error("calibrate(): No LWIR channels are configured");
return false;
}
// Skipping frame to synchronize setting calibration command
if (!skipFrame(lrp)) {
LOGGER.error("programLWIRCamera():Failed to skip frame");
}
int chn = lrp.lwir_channels[0];
int channels = 0;
for (int c : lrp.lwir_channels) {
channels |= 1 << c;
}
String hex_chan = String.format("0x%x", channels);
String url = "http://"+lrp.lwir_ips[0]+"/parsedit.php?immediate&sensor_port="+chn+
"&SENSOR_REGS67=0*"+FRAMES_AHEAD+"!"+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 {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
dom = db.parse(url);
if (!dom.getDocumentElement().getNodeName().equals("parameters")) {
LOGGER.error("programLWIRCamera() in " + url+
": Root element: expected 'parameters', got \"" + dom.getDocumentElement().getNodeName()+"\"");
return false;
}
} catch(MalformedURLException e){
LOGGER.error("programLWIRCamera() in " + url+ ": " + e.toString());
return false;
} catch(IOException e1){
LOGGER.error("programLWIRCamera() in " + url+ " - camera did not respond: " + e1.toString());
return false;
}catch(ParserConfigurationException pce) {
LOGGER.error("programLWIRCamera() in " + url+ " - PCE error: " + pce.toString());
return false;
}catch(SAXException se) {
LOGGER.error("programLWIRCamera() in " + url+ " - SAX error: " + se.toString());
return false;
}
for (int i = 0; i < (FRAMES_SKIP+FRAMES_AHEAD); i++) {
if (!skipFrame(lrp)) {
LOGGER.error("programLWIRCamera():Failed to skip frame");
}
}
return true;
}
private double secOffs(double sec1, double sec2) {
double aoff = Math.abs(sec2 - sec1);
if (aoff > 30) {
aoff = Math.abs(aoff - 30);
}
return aoff;
}
public boolean skipFrame() {
return skipFrame(lwirReaderParameters);
}
public boolean skipFrame(LwirReaderParameters lrp) {
if (lrp.lwir_channels.length == 0) {
LOGGER.error("skipFrame(): No LWIR channels are configured");
return false;
}
int chn = lrp.lwir_channels[0];
String url = "http://"+lrp.lwir_ips[0]+":"+IMGSRV_PORTS[chn] +SKIP_FRAME_URL;
Document dom=null;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
dom = db.parse(url);
if (!dom.getDocumentElement().getNodeName().equals("meta")) {
LOGGER.error("skipFrame() in " + url+
": Root element: expected 'me3ta', got \"" + dom.getDocumentElement().getNodeName()+"\"");
return false;
}
} catch(MalformedURLException e){
LOGGER.error("skipFrame() in " + url+ ": " + e.toString());
return false;
} catch(IOException e1){
LOGGER.error("skipFrame() in " + url+ " - camera did not respond: " + e1.toString());
return false;
}catch(ParserConfigurationException pce) {
LOGGER.error("skipFrame() in " + url+ " - PCE error: " + pce.toString());
return false;
}catch(SAXException se) {
LOGGER.error("skipFrame() in " + url+ " - SAX error: " + se.toString());
return false;
}
return true;
}
public ImagePlus [] acquire(String dirpath) {
return acquire(lwirReaderParameters, dirpath);
}
public ImagePlus [] acquire_lepton(LwirReaderParameters lrp, String dirpath) {
if (!condProgramLWIRCamera(lrp)) {
LOGGER.error("acquire(): failed to program cameras");
return null;
}
if (lrp.lwir_ffc) {
calibrate(lrp); // seems to work. test calibration duration and if any images are sent during calibration
}
int num_frames = lrp.avg_number + lrp.eo_lag + 2 * lrp.max_frame_diff;
if (num_frames > lrp.num_frames) {
LOGGER.warn("acquire(): Wanted to acquire "+num_frames+", but hard limit is set to "+lrp.num_frames+
" TDOD: stop EO compressor after acquisition of the required number of frames") ;
num_frames = lrp.num_frames;
}
ImagePlus [][] imps = readAllMultiple(
num_frames,
// lrp.lwir_telemetry,
false, // final boolean show,
lrp.eo_scale);
if (imps == null) {
LOGGER.error("acquire(): failed to acquire images");
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.eo_channels.length];
for (int i = 0; i < lags.length; i++) {
lags[i] = (i >= lrp.lwir_channels.length) ? lrp.eo_lag : 0;
}
ImagePlus [][] imps_sync = matchSets(
imps,
lrp.max_mismatch_ms * 0.001, // 0.001,
lrp.max_frame_diff,// 3); // double max_mismatch)
lags);
if (imps_sync == null) {
return null;
}
int num_keep = imps_sync.length;
if (!lrp.avg_all && (lrp.avg_number < imps_sync.length)) {
num_keep = lrp.avg_number;
}
LOGGER.debug("LWIR_ACQUIRE: got "+imps_sync.length+", requested "+lrp.avg_number+", keeping " + num_keep);
if (num_keep < imps_sync.length) {
ImagePlus [][] imps_sync0 = imps_sync;
imps_sync = new ImagePlus[num_keep][];
for (int i = 0; i < num_keep; i++) {
imps_sync[i] = imps_sync0[i];
}
}
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
LOGGER.warn("Saving image set to: "+set_dir.getAbsolutePath());
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.info("LWIR_ACQUIRE: 'Saving "+path );
fs.saveAsTiff(path);
}
}
if (lrp.isShowImages()) {
if (imps_avg != null) {
for (ImagePlus imp: imps_avg) {
imp.show();
}
}
}
return imps_avg;
}
// TODO: Implement LWIR restart
// Program cameras only if parameters had changed (including those, that do not actually need to be programmed)
public boolean condProgramLWIRCamera() {
return condProgramLWIRCamera(lwirReaderParameters);
}
public boolean condProgramLWIRCamera(LwirReaderParameters lrp) {
boolean ok = true;
if ((last_programmed == null) || !last_programmed.equals(lrp)) {
ok = programLWIRCamera(lrp);
if (ok) {
last_programmed = lrp.clone();
}
}
return ok;
}
//actually (unconditionally) program cameras parameters
public boolean programLWIRCamera() {
return programLWIRCamera(lwirReaderParameters);
}
public Document [] collectXmlResponses(String [] urls) {
final Document [] documents = new Document[urls.length];
final Thread[] threads = newThreadArray(MAX_THREADS);
final AtomicInteger indxAtomic = new AtomicInteger(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int indx = indxAtomic.getAndIncrement(); indx < urls.length; indx = indxAtomic.getAndIncrement()) {
documents[indx] = collectXmlResponse(urls[indx]);
}
}
};
}
startAndJoin(threads);
return documents;
}
public Document collectXmlResponse(String url) {
Document document = null;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
document = db.parse(url);
} catch(MalformedURLException e){
LOGGER.error("collectXmlResponse() MalformedURLException in " + url+ ": " + e.toString());
return null;
} catch(IOException e1){
LOGGER.error("collectXmlResponse() in " + url+ " - camera did not respond: " + e1.toString());
return null;
}catch(ParserConfigurationException pce) {
LOGGER.error("collectXmlResponse() in " + url+ " - PCE error: " + pce.toString());
return null;
}catch(SAXException se) {
LOGGER.error("collectXmlResponse() in " + url+ " - SAX error: " + se.toString());
return null;
}
return document;
}
public boolean resetAllFrames(LwirReaderParameters lrp) {
String [] all_ips = lrp.getAllIPs() ;
String [] urls = new String [all_ips.length];
boolean OK = true;
for (int i = 0; i < all_ips.length; i++) {
// urls[i] = "http://"+all_ips[i]+"/"+SCRIPT_RESET; // +"?frame=-2";
urls[i] = "http://"+all_ips[i]+"/"+SCRIPT_RESET+"?frame=-2";// works even with default -1
}
Document [] docs = collectXmlResponses(urls);
for (int i = 0; i < urls.length; i++) {
if (docs[i] == null) {
OK=false;
} else {
if (!docs[i].getDocumentElement().getNodeName().equals("reset_frames")) {
LOGGER.error("resetAllFrames() in " + urls[i]+
": Root element: expected 'reset_frames', got \"" + docs[i].getDocumentElement().getNodeName()+"\"");
OK = false;
}
}
}
return OK;
}
public boolean skipMasterFrames(String [] ips, int nskip) {
boolean OK = true;
String [] urls = new String[ips.length];
for (int i = 0; i < ips.length; i++) {
urls[i] = "http://"+ips[i]+"/"+SCRIPT_WAIT+"?frame="+(-nskip);
}
Document [] docs = collectXmlResponses(urls);
for (int i = 0; i < urls.length; i++) {
if (docs[i] == null) {
OK=false;
} else {
if (!docs[i].getDocumentElement().getNodeName().equals("wait_frames")) {
LOGGER.error("resetAllFrames() in " + urls[i]+
": Root element: expected 'wait_frames', got \"" + docs[i].getDocumentElement().getNodeName()+"\"");
OK = false;
}
}
}
return OK;
}
public void printXmlDocument(Document doc) {
if (doc==null) {
System.out.println ("***document=null***");
}
NodeList allNodes=doc.getDocumentElement().getElementsByTagName("*");
for (int i=0;i<allNodes.getLength();i++) {
String name= allNodes.item(i).getNodeName();
String value="";
try {
value=allNodes.item(i).getFirstChild().getNodeValue();
} catch(Exception e) {
}
System.out.println(name+": "+value);
}
}
public double getFutureTimestamnp (String ip, double delay) { // delay in seconds from master
if (lwirReaderParameters.getDebugLevel() > 0) {
System.out.println("Increasing delay by 3.0s when there is some printing");
delay += 3.0;
}
String url= String.format("http://%s/%s?sensor_port=0",ip,SCRIPT_CAPTURE);
if (lwirReaderParameters.getDebugLevel() > 0) System.out.println("getFutureTimestamnp(): "+url);
Document doc = collectXmlResponse(url);
if (doc == null) return Double.NaN;
if (!doc.getDocumentElement().getNodeName().equals("capture_range")) {
IJ.showMessage("Root element: expected 'capture_range', got'" + doc.getDocumentElement().getNodeName()+"'");
return Double.NaN;
}
if (lwirReaderParameters.getDebugLevel() > 0) printXmlDocument(doc);
double this_ts = Double.parseDouble(((Node)
(((Node) doc.getDocumentElement().getElementsByTagName("this_timestamp").item(0)).getChildNodes().item(0))).getNodeValue());
if (lwirReaderParameters.getDebugLevel() > 0) System.out.println(String.format("this_ts=%18.6f",this_ts));
double late_ts = this_ts + delay; // may point to a fraction of frame
url= String.format("http://%s/%s?sensor_port=0&ts=%f",ip,SCRIPT_CAPTURE, late_ts);
doc = collectXmlResponse(url);
if (lwirReaderParameters.getDebugLevel() > 0) {
System.out.println("getFutureTimestamnp(): "+url);
printXmlDocument(doc);
}
if (doc == null) return Double.NaN;
if (!doc.getDocumentElement().getNodeName().equals("capture_range")) {
IJ.showMessage("Root element: expected 'capture_range', got'" + doc.getDocumentElement().getNodeName()+"'");
return Double.NaN;
}
double target_ts = Double.parseDouble(((Node)
(((Node) doc.getDocumentElement().getElementsByTagName("timestamp").item(0)).getChildNodes().item(0))).getNodeValue());
if (lwirReaderParameters.getDebugLevel() > 0) System.out.println(String.format("getFutureTimestamnp(): target_ts=%18.6f",target_ts));
return target_ts;
}
public int [] getPortMasks(LwirReaderParameters lrp) {
boolean [] selected_channels = lrp.getSelectedChannels();
int [] port_masks= new int [selected_channels.length / 4]; // {15,15,15,15,15}; // get
for (int i = 0; i < port_masks.length; i++) {
port_masks[i]=0;
for (int j = 0; j < 4; j++) {
if (selected_channels[i * 4 + j]) {
port_masks[i] += 1 << j;
}
}
}
return port_masks;
}
/**
*
* @param lrp
* @param delay
* @param duration -1 - start only, 0 - stop only, >0 - start+stop (LWIR cameras)
* @param duration_eo -1 - start only, 0 - stop only, >0 - start+stop (EO cameras)
* @return <0 - error, >0 last frame of the master camera/port in sequence
*/
public int captureRange(LwirReaderParameters lrp, double delay, int duration, int duration_eo) {
int lwir_master_index = 0;
int num_lwir = lrp.getLwirIPs().length;
int [] port_masks= getPortMasks(lrp);
double target_ts = getFutureTimestamnp (lrp.getLwirIP(lwir_master_index), delay);
if (Double.isNaN(target_ts)) {
return -1;
}
String [] all_ips = lrp.getAllIPs();
String [] urls = new String [all_ips.length];
for (int i = 0; i < urls.length; i++) {
int dur = (i>= num_lwir)?duration_eo:duration;
urls[i]=String.format("http://%s/%s?sensor_port=0&ts=%f&m=%d&d=%d", all_ips[i], SCRIPT_CAPTURE, target_ts, port_masks[i], dur);
}
boolean OK = true;
Document [] docs = collectXmlResponses(urls);
if (lrp.getDebugLevel() > 0) {
for (int i = 0; i < urls.length; i++) {
System.out.println(i+": "+urls[i]);
}
for (Document doc:docs) {
printXmlDocument(doc);
}
}
for (int i = 0; i < urls.length; i++) {
if (docs[i] == null) {
OK=false;
} else {
if (!docs[i].getDocumentElement().getNodeName().equals("capture_range")) {
LOGGER.error("captureRange() in " + urls[i]+
": Root element: expected 'capture_range', got \"" + docs[i].getDocumentElement().getNodeName()+"\"");
OK = false;
// is there error?
NodeList allNodes=docs[i].getDocumentElement().getElementsByTagName("error");
if (allNodes.getLength()>0) {
String err = ((Node)
(((Node) docs[i].getDocumentElement().getElementsByTagName("error").item(0)).getChildNodes().item(0))).getNodeValue();
LOGGER.error("captureRange() in " + urls[i]+
": Got error: \"" + err+"\"");
OK = false;
}
}
}
}
if (!OK) {
return -1;
}
int master_frame = Integer.parseInt(((Node)
(((Node) docs[lwir_master_index].getDocumentElement().getElementsByTagName("frame").item(0)).getChildNodes().item(0))).getNodeValue());
if (lrp.getDebugLevel() > 0) System.out.println(String.format("master_frame=%d(0x%x)", master_frame,master_frame));
return master_frame;
}
public boolean startStopCompressor(LwirReaderParameters lrp, boolean start, double delay) {
if (lrp.getDebugLevel() > 0) System.out.println("startStopCompressor() start="+start);
int duration = start? -1: 0;
int end_frame = captureRange(lrp, delay, duration, duration);
if (end_frame < 0) return false;
// end frame -> master_ts -> eo_frame -> increment -> wait eo_frame
return true;
}
public boolean runFFC (LwirReaderParameters lrp) {
int [] port_masks= getPortMasks(lrp);
int ffc_groups = lrp.getFFCGroups();
String [] lwir_IPs = lrp.getLwirIPs();
boolean OK = true;
int [] group_masks = new int [ffc_groups];
if (ffc_groups == 1) {
group_masks = new int [] {15};
} else if (ffc_groups == 2) {
group_masks = new int [] {5, 10};
} else if (ffc_groups == 4) {
group_masks = new int [] {1, 2, 4, 8};
} else {
throw new IllegalArgumentException ("Invalid number of FFC groups:"+ffc_groups+". Only 1,2 and 4 are supportded");
}
ArrayList<String> url_list = new ArrayList<String>();
for (int ig = 0; ig < ffc_groups; ig++) {
url_list.clear();
int ip0 = -1;
for (int i = 0; i < lwir_IPs.length; i++) { // start urls for 4 of lwir port0 and eo - ports 0-3 (total 8 URLs)
int mask = port_masks[i] & group_masks[ig];
if (mask != 0) {
int p=0;
for (;((1 << p) & mask) == 0; p++); // find lowest non-zero bit
url_list.add(String.format("http://%s/parsedit.php?immediate&sensor_port=%d&%s=1&*%s=%d",lwir_IPs[i],p,REG_FFC_RUN,REG_FFC_RUN,mask));
if (ip0 < 0) {
ip0 = i; // first used ip index
}
}
}
if (!url_list.isEmpty()) {
String[] urls = url_list.toArray(new String[url_list.size()]);
// Print all urls
if (lrp.getDebugLevel() > 0) {
System.out.println("Performing FFC cycle with:");
for (int i = 0; i < urls.length; i++) {
System.out.println(i+": "+urls[i]);
}
}
// run all programming not including TRIG=4
Document [] docs = collectXmlResponses(urls);
for (int i = 0; i < urls.length; i++) {
if (docs[i] == null) {
OK=false;
} else {
if (!docs[i].getDocumentElement().getNodeName().equals("parameters")) {
LOGGER.error("runFFC() in " + urls[i]+
": Root element: expected 'parameters', got \"" + docs[i].getDocumentElement().getNodeName()+"\"");
OK = false;
}
}
}
int skip_frames = 2 * lrp.getFFCFrames() + lrp.getFFCWaitFrames();
skipMasterFrames(new String[] {lwir_IPs[ip0]}, skip_frames); // make sure all previous parameters are applied
}
}
return OK;
}
/**
* Reset circbuf frames in each camera channel
* @param lrp
* @return
*/
public boolean resetFrameBuffers(LwirReaderParameters lrp) {
int [] port_masks= getPortMasks(lrp);
ArrayList<String> url_list = new ArrayList<String>();
String [] all_IPs = lrp.getAllIPs();
for (int i = 0; i < all_IPs.length; i++) {
for (int port = 0; port < IMGSRV_PORTS.length; port++) {
if ((port_masks[i] & (1 << port)) != 0) {
url_list.add(String.format("http://%s:%d%s", all_IPs[i],IMGSRV_PORTS[port],IMAGE_URL_RESET));
}
}
}
String[] urls = url_list.toArray(new String[url_list.size()]);
boolean OK=true;
if (lrp.getDebugLevel() > 0) {
System.out.println("Resetting circbuf buffers with:");
for (int i = 0; i < urls.length; i++) {
System.out.println(i+": "+urls[i]);
}
}
// run all programming not including TRIG=4
Document [] docs = collectXmlResponses(urls);
for (int i = 0; i < urls.length; i++) {
if (docs[i] == null) {
OK=false;
} else {
if (!docs[i].getDocumentElement().getNodeName().equals("frames")) {
LOGGER.error("resetFrameBuffers() in " + urls[i]+
": Root element: expected 'frames', got \"" + docs[i].getDocumentElement().getNodeName()+"\"");
OK = false;
}
}
}
return OK;
}
public boolean isCompressorStopped(LwirReaderParameters lrp) {
int [] port_masks= getPortMasks(lrp);
String [] all_IPs = lrp.getAllIPs();
int ip_index = 0;
for (; (ip_index < port_masks.length) && (port_masks[ip_index] == 0); ip_index++);
if (ip_index >= port_masks.length) {
throw new IllegalArgumentException ("No channels selected in isCompressing()");
}
String url = "";
for (int port = 0; port < IMGSRV_PORTS.length; port++) {
if ((port_masks[ip_index] & (1 << port)) != 0) {
url = (String.format("http://%s:%d%s", all_IPs[ip_index],IMGSRV_PORTS[port],IMAGE_URL_STATUS));
break;
}
}
if (lrp.getDebugLevel() > 0) {
System.out.println("Performing isCompressing");
System.out.println(url);
}
Document doc = collectXmlResponse(url);
String compressor_state = ((Node)
(((Node) doc.getDocumentElement().getElementsByTagName("compressor_state").item(0)).getChildNodes().item(0))).getNodeValue();
// compressor_state = compressor_state.replace ("/(^\")|(\"$)/g", ""); // replace leading/trailing "
compressor_state = compressor_state.replace ("\"", ""); // replace leading/trailing "
return compressor_state.equals("COMPRESSOR_RUN_STOP");
}
public ImagePlus[] acquire (LwirReaderParameters lrp, String dirpath) {
String std = "STD_";
boolean scale = false;
condProgramLWIRCamera();
if (lrp.runFFCBeforeMeasurments()) {
runFFC(lrp);
}
if (!isCompressorStopped(lrp)) {
startStopCompressor(lrp, false, lrp.getAcquireDelay());
resetFrameBuffers(lrp); //only needed after stopping
}
resetFrameBuffers(lrp); // actually only needed after stopping, here just in case
// start capturing frames into each camera buffer
int end_frame = captureRange(lrp, lrp.getAcquireDelay(), lrp.getAvgNumberLwir(),lrp.getAvgNumberEO());
// public static final String IMAGE_URL_NEXT= "/torp/next/wait/img/save"; // same image name, same image number/time
// public static final String IMAGE_URL_NEXT= "/torp/wait/img/next/save"; // same image name, same image number/time
int [] port_masks= getPortMasks(lrp);
String [] all_IPs = lrp.getAllIPs();
final int num_lwir = lrp.getLwirIPs().length;
final int avg_lwir = lrp.getAvgNumberLwir();
final int avg_eo = lrp.getAvgNumberEO();
int avg_num = (avg_lwir > avg_eo)? avg_lwir : avg_eo;
final Thread[] threads = newThreadArray(MAX_THREADS);
final AtomicInteger indxAtomic = new AtomicInteger(0);
ImagePlus [] imgs = readImageSet(
lrp,
(avg_lwir> 0), // boolean get_lwir,
(avg_eo > 0), // boolean get_eo,
false, // lrp.isShowImages(), // boolean show,
scale, // boolean scale,
std, // String std,
""+0); // String dbgtxt)
final int num_channels = imgs.length;
for (int nmeas = 1; nmeas < avg_num; nmeas++) {
boolean use_lwir = nmeas < avg_lwir;
boolean use_eo = nmeas < avg_eo;
ImagePlus [] imgs1 = readImageSet(
lrp,
use_lwir, // boolean get_lwir,
use_eo, // boolean get_eo,
false, // lrp.isShowImages(), // boolean show,
scale, // boolean scale,
std, // String std,
""+nmeas); // String dbgtxt)
// add img1 to img in a multi-threaded way
indxAtomic.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int chn = indxAtomic.getAndIncrement(); chn < num_channels; chn = indxAtomic.getAndIncrement()) {
if (imgs1[chn] != null) {
// int width = imgs[chn].getWidth();
// int height = imgs[chn].getHeight();
// String title = sets[0][chn].getTitle()+"_average"+num_frames;
float [] pixels_avg = (float []) imgs [chn].getProcessor().getPixels();
float [] pixels = (float []) imgs1[chn].getProcessor().getPixels();
// double scale = 1.0/num_frames;
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] += pixels[i];
}
// imgs [chn].getProcessor().setPixels(pixels_avg); // or it is not needes as it is already in-place?
/*
ImageProcessor ip=new FloatProcessor(width,height);
imps[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]);
*/
}
}
}
};
}
startAndJoin(threads);
}
// now divide average by number of measurements and finalize
indxAtomic.set(0);
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int chn = indxAtomic.getAndIncrement(); chn < num_channels; chn = indxAtomic.getAndIncrement()) {
if (imgs[chn] != null) {
int num_frames = (chn < (num_lwir*IMGSRV_PORTS.length))? avg_lwir : avg_eo;
if (num_frames > 0) {
float [] pixels_avg = (float []) imgs[chn].getProcessor().getPixels();
double scale = 1.0/num_frames;
for (int i = 0; i < pixels_avg.length; i++) {
pixels_avg[i] *=scale;
}
imgs[chn].getProcessor().resetMinAndMax();
// imgs [chn].getProcessor().setPixels(pixels_avg); // or it is not needes as it is already in-place?
// ImageProcessor ip=new FloatProcessor(width,height);
imgs[chn].setProperty("average", ""+num_frames);
if (motorsPosition!=null) for (int m=0;m<motorsPosition.length;m++ ) {
imgs[chn].setProperty("MOTOR"+(m+1), ""+motorsPosition[m]);
}
ImagejJp4Tiff.encodeProperiesToInfo(imgs[chn]);
}
}
}
}
};
}
startAndJoin(threads);
if (lrp.isShowImages()) {
for (ImagePlus imp: imgs) {
imp.show();
}
}
return null;
}
public ImagePlus[] readImageSet(
LwirReaderParameters lrp,
boolean get_lwir,
boolean get_eo,
boolean show,
boolean scale,
String std,
String dbgtxt)
{
int [] port_masks= getPortMasks(lrp);
ArrayList<String> url_list = new ArrayList<String>();
String [] all_IPs = lrp.getAllIPs();
String [] lwir_IPs = lrp.getLwirIPs();
for (int i = 0; i < all_IPs.length; i++) {
if ((i < lwir_IPs.length)? get_lwir:get_eo) {
for (int port = 0; port < IMGSRV_PORTS.length; port++) if ((port_masks[i] & (1 << port)) != 0) {
url_list.add(String.format("http://%s:%d/bchn%d%s",all_IPs[i],IMGSRV_PORTS[port],i*IMGSRV_PORTS.length,IMAGE_URL_NEXT));
}
}
}
String[] urls = url_list.toArray(new String[url_list.size()]);
ImagePlus [] imps = new ImagePlus[urls.length];
if (imagejJp4TiffMulti == null) {
imagejJp4TiffMulti = new ImagejJp4TiffMulti();
}
LOGGER.info("---- Acquiring frame set "+dbgtxt);
try {
imagejJp4TiffMulti.getMultiImages(urls, imps, scale, std);
} catch (IOException e) {
LOGGER.error("readAllMultiple0: IOException, " + dbgtxt);
} catch (FormatException e) {
LOGGER.error("readAllMultiple0:FormatException, " + dbgtxt);
}
double [] img_seconds = new double [urls.length];
int [] img_numbers = new int [urls.length];
String []img_names = new String [urls.length];
for (int i = 0; i < imps.length; i++) {
String dt = null;
try {
dt = (String) imps[i].getProperty("DATE_TIME");
} catch (Exception e) {
LOGGER.error("Something is wrong!, no DATE_TIME in the image "+urls[i]);
}
if (dt==null) {
System.out.println("i="+i+", dt is NULL!");
}
img_seconds[i] = Double.parseDouble(dt.substring(dt.lastIndexOf(":")+1));
try {
img_numbers[i] = Integer.parseInt((String) imps[i].getProperty("STD_Image_Number"));
} catch (Exception e) {
img_numbers[i] = -1;
}
img_names[i] = (String) imps[i].getProperty("CONTENT_FILENAME");
LOGGER.warn("Seconds for "+i+" - "+img_seconds[i]+", number"+img_numbers[i]+", name "+img_names[i]);
}
// Make a sparse array for all lwir+eo channels with nulls for channels that are not measured.
ImagePlus [] imps_all = new ImagePlus [all_IPs.length * IMGSRV_PORTS.length];
int indx = 0;
for (int i = 0; i < all_IPs.length; i++) {
if ((i < lwir_IPs.length)? get_lwir:get_eo) {
for (int port = 0; port < IMGSRV_PORTS.length; port++) if ((port_masks[i] & (1 << port)) != 0) {
imps_all[i* IMGSRV_PORTS.length + port] = imps[indx++];
}
}
}
if (show) {
for (ImagePlus imp: imps) {
imp.show();
}
}
return imps_all; // imps;
}
public boolean programLWIRCamera(LwirReaderParameters lrp) {
String [] all_IPs = lrp.getAllIPs();
String [] lwir_IPs = lrp.getLwirIPs();
String eo_ip = lrp.getEOIP();
String [] two_IPs= {lwir_IPs[0], eo_ip};
String [] urls;
// int eo_master_port = 0;
skipMasterFrames(two_IPs, 16); // make sure LWIR and EO (slow) flushed frame sequencer (overkill)
boolean OK = resetAllFrames(lrp);
skipMasterFrames(two_IPs, 1);
/// prepare trigger parameters (common for all)
urls = new String[all_IPs.length+3]; // for EO - per port individual
for (int i = 0; i < urls.length; i++) { // start urls for 4 of lwir port0 and eo - ports 0-3 (total 8 URLs)
int ip = (i < all_IPs.length)?i:(all_IPs.length-1);
int port = i-ip;
urls[i] = "http://"+all_IPs[ip]+"/parsedit.php?immediate&sensor_port="+port;
}
for (int i = 0; i < all_IPs.length; i++) { // apply to all IPs port0 (LWIR and EO)
urls[i] += "&TRIG_OUT=0x66555"+
"&TRIG_CONDITION=0x95555"+
// "&TRIG_DELAY="+lrp.lwir_trig_dly+
"&TRIG_BITLENGTH=31"+
"&EXTERN_TIMESTAMP=1"+
"&XMIT_TIMESTAMP=1";
}
for (int i = 0; i < lwir_IPs.length; i++) { // Alpply to only 4 lwir cameras, port 0 (some to all ports)
urls[i] += "&TRIG_DELAY="+lrp.lwir_trig_dly+"&*TRIG_DELAY=15"+ // apply to all ports
"&BITS=16&*BITS=15"+
"&COLOR="+COLOR_RAW +"&*COLOR=15"+
"&WOI_HEIGHT="+(LWIR_HEIGHT + (lrp.lwir_telemetry?LWIR_TELEMETRY_LINES:0))+"&*WOI_HEIGHT=15"+
"&"+REG_FFC_FRAMES+"="+lrp.getFFCFrames() +"&*"+REG_FFC_FRAMES+"=15"; // apply to all channels
}
for (int chn:lrp.eo_channels) { // add color settings to all EO channels
int minExposure=10; // usec
int maxExposure=1000000; //usec
int minGain=(int) (0x10000*1.0);
int maxGain=(int) (0x10000*15.75);
int minScale=0;
int maxScale=(int) (0x10000*4.0);
int exposure= (int) (Math.round(1000*lrp.eo_exposure_ms * lrp.eo_exp_corr[chn]));
int autoExposureMax= (int) (Math.round(1000*lrp.eo_max_autoexp_ms));
int gain= (int) (Math.round(0x10000*lrp.eo_gain_g));
int rScale= (int) (Math.round(0x10000*lrp.eo_gain_rg*lrp.eo_gcorr_rbgb[3*chn+0]));
int bScale= (int) (Math.round(0x10000*lrp.eo_gain_bg*lrp.eo_gcorr_rbgb[3*chn+1]));
int gScale= (int) (Math.round(0x10000* lrp.eo_gcorr_rbgb[3*chn+2]));
int autoExp= lrp.eo_autoexp?1:0;
int autoWB= lrp.eo_whitebal?1:0;
if (exposure<minExposure) exposure=minExposure; else if (exposure>maxExposure) exposure=maxExposure;
if (autoExposureMax<minExposure) autoExposureMax=minExposure; else if (autoExposureMax>maxExposure) autoExposureMax=maxExposure;
if (gain<minGain) gain= minGain ; else if (gain> maxGain) gain= maxGain;
if (rScale<minScale) rScale= minScale ; else if (rScale> maxScale) rScale= maxScale;
if (bScale<minScale) bScale= minScale ; else if (bScale> maxScale) bScale= maxScale;
if (gScale<minScale) gScale= minScale ; else if (gScale> maxScale) gScale= maxScale;
urls[all_IPs.length-1+chn] +=
"&COLOR="+COLOR_JP4+ // "*1"+ // JP4 always
"&QUALITY="+lrp.eo_quality+ // "*0"+
"&EXPOS="+exposure+ // "*0"+
"&AUTOEXP_EXP_MAX="+autoExposureMax+//"*0"+
"&AUTOEXP_ON="+autoExp+//"*0"+
"&GAING="+gain+//"*0"+
"&RSCALE="+rScale+//"*0"+
"&BSCALE="+bScale+//"*0"+
"&GSCALE="+gScale+//"*0"+ // GB/G ratio
"&WB_EN="+autoWB+//"*0"+
"&DAEMON_EN_TEMPERATURE=1";//"*0";
if (lrp.eo_full_window) {
urls[all_IPs.length-1+chn] +=
"&WOI_LEFT=0"+
"&WOI_TOP=0"+
"&WOI_WIDTH=2592"+
"&WOI_HEIGHT=1936";
}
}
// run all programming not including TRIG=4
Document [] docs = collectXmlResponses(urls);
// Print all urls
if (lrp.getDebugLevel() > 0) {
System.out.println("Configuring cameras with:");
for (int i = 0; i < urls.length; i++) {
System.out.println(i+": "+urls[i]);
}
}
for (int i = 0; i < urls.length; i++) {
if (docs[i] == null) {
OK=false;
} else {
if (!docs[i].getDocumentElement().getNodeName().equals("parameters")) {
LOGGER.error("programLWIRCamera() in " + urls[i]+
": Root element: expected 'parameters', got \"" + docs[i].getDocumentElement().getNodeName()+"\"");
OK = false;
}
}
}
skipMasterFrames(two_IPs, 3); // make sure all previous parameters are applied
// set external trigger mode for all LWIR and EO cameras
urls = new String[all_IPs.length];
for (int i = 0; i < urls.length; i++) {
urls[i] = "http://"+all_IPs[i]+"/parsedit.php?immediate&sensor_port=0&TRIG=4&*TRIG=15";
}
docs = collectXmlResponses(urls);
// Print all urls
if (lrp.getDebugLevel() > 0) {
System.out.println("\nSetting trigger mode = 4 on all cameras/ports");
for (int i = 0; i < urls.length; i++) {
System.out.println(i+": "+urls[i]);
}
}
for (int i = 0; i < urls.length; i++) {
if (docs[i] == null) {
OK=false;
} else {
if (!docs[i].getDocumentElement().getNodeName().equals("parameters")) {
LOGGER.error("resetAllFrames() in " + urls[i]+
": Root element: expected 'parameters', got \"" + docs[i].getDocumentElement().getNodeName()+"\"");
OK = false;
}
}
}
skipMasterFrames(two_IPs, 4); // make sure all previous parameters are applied
// second reset after cameras running synchronously
OK &= resetAllFrames(lrp);
skipMasterFrames(two_IPs, 1);
if (OK) {
last_programmed = lrp.clone();
}
return OK;
}
public boolean programLWIRCamera_lepton(LwirReaderParameters lrp) {
int lwir_master_port = 0;
int eo_master_port = 0;
int num_lwir = lrp.lwir_channels.length;
int num_eo = lrp.eo_channels.length;
final String [] urls = new String [num_lwir + num_eo];
for (int chn:lrp.lwir_channels) {
urls[chn] = "http://"+lrp.getLwirIP()+"/parsedit.php?immediate&sensor_port="+chn+
"&BITS=16"+
"&COLOR="+COLOR_RAW+ // +"*0"; // raw mode - delay 0 - breaks compressor
"&WOI_HEIGHT="+(LWIR_HEIGHT + (lrp.lwir_telemetry?LWIR_TELEMETRY_LINES:0));
if (chn == lwir_master_port) {
urls[chn] +="&TRIG=0*0"+
"&TRIG_DELAY="+lrp.lwir_trig_dly+"*0"+
"&TRIG_OUT=419157*0"+
"&TRIG_BITLENGTH=31*0"+
"&EXTERN_TIMESTAMP=1*0"+
"&XMIT_TIMESTAMP=1*0";
}
}
for (int chn:lrp.eo_channels) {
int minExposure=10; // usec
int maxExposure=1000000; //usec
int minGain=(int) (0x10000*1.0);
int maxGain=(int) (0x10000*15.75);
int minScale=0;
int maxScale=(int) (0x10000*4.0);
int exposure= (int) (Math.round(1000*lrp.eo_exposure_ms * lrp.eo_exp_corr[chn]));
int autoExposureMax= (int) (Math.round(1000*lrp.eo_max_autoexp_ms));
int gain= (int) (Math.round(0x10000*lrp.eo_gain_g));
int rScale= (int) (Math.round(0x10000*lrp.eo_gain_rg*lrp.eo_gcorr_rbgb[3*chn+0]));
int bScale= (int) (Math.round(0x10000*lrp.eo_gain_bg*lrp.eo_gcorr_rbgb[3*chn+1]));
int gScale= (int) (Math.round(0x10000* lrp.eo_gcorr_rbgb[3*chn+2]));
int autoExp= lrp.eo_autoexp?1:0;
int autoWB= lrp.eo_whitebal?1:0;
if (exposure<minExposure) exposure=minExposure; else if (exposure>maxExposure) exposure=maxExposure;
if (autoExposureMax<minExposure) autoExposureMax=minExposure; else if (autoExposureMax>maxExposure) autoExposureMax=maxExposure;
if (gain<minGain) gain= minGain ; else if (gain> maxGain) gain= maxGain;
if (rScale<minScale) rScale= minScale ; else if (rScale> maxScale) rScale= maxScale;
if (bScale<minScale) bScale= minScale ; else if (bScale> maxScale) bScale= maxScale;
if (gScale<minScale) gScale= minScale ; else if (gScale> maxScale) gScale= maxScale;
urls[num_lwir+chn] = "http://"+lrp.eo_ip+"/parsedit.php?immediate&sensor_port="+chn+
"&COLOR="+COLOR_JP4+ // "*1"+ // JP4 always
"&QUALITY="+lrp.eo_quality+ // "*0"+
"&EXPOS="+exposure+ // "*0"+
"&AUTOEXP_EXP_MAX="+autoExposureMax+//"*0"+
"&AUTOEXP_ON="+autoExp+//"*0"+
"&GAING="+gain+//"*0"+
"&RSCALE="+rScale+//"*0"+
"&BSCALE="+bScale+//"*0"+
"&GSCALE="+gScale+//"*0"+ // GB/G ratio
"&WB_EN="+autoWB+//"*0"+
"&DAEMON_EN_TEMPERATURE=1";//"*0";
if (lrp.eo_full_window) {
urls[num_lwir+chn] +=
"&WOI_LEFT=0"+
"&WOI_TOP=0"+
"&WOI_WIDTH=2592"+
"&WOI_HEIGHT=1936";
}
if (chn == eo_master_port) {
urls[num_lwir+chn] += "&TRIG=4*0"+
"&TRIG_CONDITION=611669*0"+ // external input
"&TRIG_BITLENGTH=31*0"+
"&EXTERN_TIMESTAMP=1*0";
}
}
for (int i = 0; i < urls.length; i++) {
LOGGER.debug("programLWIRCamera(): reading url " + urls[i]);
}
// multithreaded camera access:
final Thread[] threads = newThreadArray(MAX_THREADS);
final AtomicInteger indxAtomic = new AtomicInteger(0);
final boolean [] get_success = new boolean [urls.length];
for (int ithread = 0; ithread < threads.length; ithread++) {
threads[ithread] = new Thread() {
@Override
public void run() {
for (int indx = indxAtomic.getAndIncrement(); indx < urls.length; indx = indxAtomic.getAndIncrement()) {
Document dom=null;
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
dom = db.parse(urls[indx]);
if (!dom.getDocumentElement().getNodeName().equals("parameters")) {
LOGGER.error("programLWIRCamera() in " + urls[indx]+
": Root element: expected 'parameters', got \"" + dom.getDocumentElement().getNodeName()+"\"");
get_success[indx] = false;
continue;
}
} catch(MalformedURLException e){
LOGGER.error("programLWIRCamera() in " + urls[indx]+ ": " + e.toString());
get_success[indx] = false;
continue;
} catch(IOException e1){
LOGGER.error("programLWIRCamera() in " + urls[indx]+ " - camera did not respond: " + e1.toString());
get_success[indx] = false;
continue;
}catch(ParserConfigurationException pce) {
LOGGER.error("programLWIRCamera() in " + urls[indx]+ " - PCE error: " + pce.toString());
get_success[indx] = false;
continue;
}catch(SAXException se) {
LOGGER.error("programLWIRCamera() in " + urls[indx]+ " - SAX error: " + se.toString());
get_success[indx] = false;
continue;
}
get_success[indx] = true;
}
}
};
}
startAndJoin(threads);
// See if there are any errors
boolean allOK = true;
for (boolean OK:get_success) {
allOK &= OK;
}
if (allOK){
lrp.reset_updated();
for (int i = 0; i < FRAMES_SKIP; i++) {
if (!skipFrame(lrp)) {
LOGGER.error("programLWIRCamera():Failed to skip frame");
}
}
}
return allOK;
}
/* 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.
* 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 static void startAndJoin(Thread[] threads)
{
for (int ithread = 0; ithread < threads.length; ++ithread)
{
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);
}
}
}
...@@ -96,13 +96,13 @@ public class LwirReader { ...@@ -96,13 +96,13 @@ public class LwirReader {
// -- constructors // -- constructors
public LwirReader() { public LwirReader() {
this.lwirReaderParameters = new LwirReaderParameters(); // default this.lwirReaderParameters = new LwirReaderParameters(LwirReaderParameters.NAME_TALON); // default
imagejJp4TiffMulti = null; imagejJp4TiffMulti = null;
} }
public LwirReader(LwirReaderParameters lwirReaderParameters) { public LwirReader(LwirReaderParameters lwirReaderParameters) {
if (lwirReaderParameters == null) { if (lwirReaderParameters == null) {
this.lwirReaderParameters = new LwirReaderParameters(); // default this.lwirReaderParameters = new LwirReaderParameters(LwirReaderParameters.NAME_TALON); // default
} else { } else {
this.lwirReaderParameters = lwirReaderParameters; this.lwirReaderParameters = lwirReaderParameters;
} }
...@@ -404,9 +404,9 @@ public class LwirReader { ...@@ -404,9 +404,9 @@ public class LwirReader {
} }
String hex_chan = String.format("0x%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.getLwirIP()+"/parsedit.php?immediate&sensor_port="+chn+
"&SENSOR_REGS67=0*"+FRAMES_AHEAD+"!"+hex_chan; "&SENSOR_REGS67=0*"+FRAMES_AHEAD+"!"+hex_chan;
// String url = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+ // String url = "http://"+lrp.getLwirIP()+"/parsedit.php?immediate&sensor_port="+chn+
// "&SENSOR_REGS67=0&*SENSOR_REGS67="+hex_chan; // "&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);
...@@ -459,7 +459,7 @@ public class LwirReader { ...@@ -459,7 +459,7 @@ public class LwirReader {
return false; return false;
} }
int chn = lrp.lwir_channels[0]; int chn = lrp.lwir_channels[0];
String url = "http://"+lrp.lwir_ip+":"+IMGSRV_PORTS[chn]+SKIP_FRAME_URL; String url = "http://"+lrp.getLwirIP()+":"+IMGSRV_PORTS[chn]+SKIP_FRAME_URL;
Document dom=null; Document dom=null;
try { try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
...@@ -467,7 +467,7 @@ public class LwirReader { ...@@ -467,7 +467,7 @@ public class LwirReader {
dom = db.parse(url); dom = db.parse(url);
if (!dom.getDocumentElement().getNodeName().equals("meta")) { if (!dom.getDocumentElement().getNodeName().equals("meta")) {
LOGGER.error("skipFrame() in " + url+ LOGGER.error("skipFrame() in " + url+
": Root element: expected 'me3ta', got \"" + dom.getDocumentElement().getNodeName()+"\""); ": Root element: expected 'meta', got \"" + dom.getDocumentElement().getNodeName()+"\"");
return false; return false;
} }
} catch(MalformedURLException e){ } catch(MalformedURLException e){
...@@ -618,7 +618,7 @@ public class LwirReader { ...@@ -618,7 +618,7 @@ public class LwirReader {
int num_eo = lrp.eo_channels.length; int num_eo = lrp.eo_channels.length;
final String [] urls = new String [num_lwir + num_eo]; final String [] urls = new String [num_lwir + num_eo];
for (int chn:lrp.lwir_channels) { for (int chn:lrp.lwir_channels) {
urls[chn] = "http://"+lrp.lwir_ip+"/parsedit.php?immediate&sensor_port="+chn+ urls[chn] = "http://"+lrp.getLwirIP()+"/parsedit.php?immediate&sensor_port="+chn+
"&BITS=16"+ "&BITS=16"+
"&COLOR="+COLOR_RAW+ // +"*0"; // raw mode - delay 0 - breaks compressor "&COLOR="+COLOR_RAW+ // +"*0"; // raw mode - delay 0 - breaks compressor
"&WOI_HEIGHT="+(LWIR_HEIGHT + (lrp.lwir_telemetry?LWIR_TELEMETRY_LINES:0)); "&WOI_HEIGHT="+(LWIR_HEIGHT + (lrp.lwir_telemetry?LWIR_TELEMETRY_LINES:0));
......
...@@ -36,12 +36,25 @@ import ij.ImagePlus; ...@@ -36,12 +36,25 @@ import ij.ImagePlus;
import ij.Prefs; import ij.Prefs;
public class LwirReaderParameters { public class LwirReaderParameters {
public final static String NAME_TALON= "Talon";
public final static String NAME_LWIR16= "LWIR16";
public final static String [] CAMERA_NAMES= {NAME_TALON,NAME_LWIR16};
public final static int [] BOSON_FFC_FRAMES= {2,4,8,16};
public final static int [] FFC_GROUPS= {1,2,4};
private boolean parameters_updated = false; private boolean parameters_updated = false;
protected int avg_number = 4; // number of measurements to average protected String camera_name = "Talon"; // "LWIR16";
protected int avg_number = 4; // number of LWIR measurements to average
protected int avg_number_eo = 1; // number of EO measurements to average
protected int num_frames = 7; // misses images if high quality large size? protected int num_frames = 7; // misses images if high quality large size?
protected boolean lwir_ffc = true; protected boolean lwir_ffc = true;
protected int ffc_frames = 8;
protected int ffc_wait_frames = 10; // extra wait after FFC finished (2xffc_frames)
protected int ffc_groups = 2; // 1/2/4 - do not run FFC on all channels simultaneously (43 failed)
protected double acquire_delay = 3.0; // seconds. Schedule later from the master channel current time to start all cameras
protected boolean avg_all = true; protected boolean avg_all = true;
protected String lwir_ip = "192.168.0.36"; // protected String lwir_ip = "192.168.0.36";
protected String[] lwir_ips = {"192.168.0.41","192.168.0.42","192.168.0.43","192.168.0.44"}; // first - master
protected String eo_ip = "192.168.0.38"; protected String eo_ip = "192.168.0.38";
protected int [] lwir_channels = {0, 1, 2 ,3}; protected int [] lwir_channels = {0, 1, 2 ,3};
protected int [] eo_channels = {0, 1, 2 ,3}; protected int [] eo_channels = {0, 1, 2 ,3};
...@@ -67,7 +80,7 @@ public class LwirReaderParameters { ...@@ -67,7 +80,7 @@ public class LwirReaderParameters {
1.0, 1.0, 1.0}; 1.0, 1.0, 1.0};
*/ */
protected double [] eo_exp_corr = { protected double [] eo_exp_corr = {
1.0, 1.0026, 0.9868, 1.0211}; 1.0, 1.0, 1.0, 1.0};
protected double [] eo_gcorr_rbgb = { // example after autobalance for 192.168.0.38 with halogen lamps protected double [] eo_gcorr_rbgb = { // example after autobalance for 192.168.0.38 with halogen lamps
1.0, 1.0, 0.9743, 1.0, 1.0, 0.9743,
1.0668, 1.1055, 1.0006, 1.0668, 1.1055, 1.0006,
...@@ -81,10 +94,30 @@ public class LwirReaderParameters { ...@@ -81,10 +94,30 @@ public class LwirReaderParameters {
protected boolean show_images = false; protected boolean show_images = false;
protected int lwir_chn0 = 0; // not configurable protected int lwir_chn0 = 0; // not configurable
protected int eo_chn0 = 4; // not configurable protected int eo_chn0 = 4; // not configurable
public LwirReaderParameters() {
}
public LwirReaderParameters(String name) {
if (NAME_TALON.equals(name)) camera_name = NAME_TALON;
else if (NAME_LWIR16.equals(name)) camera_name = NAME_LWIR16;
}
// --- interface methods // --- interface methods
public int getAvgNumberLwir() {
return avg_number;
}
public int getAvgNumberEO() {
return avg_number_eo;
}
public String getCameraName() {
return this.camera_name;
}
public int getNumFrames() { public int getNumFrames() {
return num_frames; return num_frames;
} }
...@@ -115,12 +148,91 @@ public class LwirReaderParameters { ...@@ -115,12 +148,91 @@ public class LwirReaderParameters {
public boolean isShowImages() { public boolean isShowImages() {
return show_images; return show_images;
} }
public String getLwirIP() {
return lwir_ips[0];
}
public String getLwirIP(int n) {
return lwir_ips[n];
}
public String [] getLwirIPs() {
return lwir_ips;
}
public String getEOIP() {
return eo_ip;
}
public String [] getAllIPs() {
String [] all_ips = new String [lwir_ips.length+1];
int i = 0;
for (i = 0; i < lwir_ips.length; i++) {
all_ips[i] = lwir_ips[i];
}
all_ips[i] = eo_ip;
return all_ips;
}
boolean [] getSelectedChannels() {
return selected_channels;
}
// call after switch from Lwir16 to Talon
public boolean isLwir16() {
return camera_name.equals(NAME_LWIR16);
}
public int getFFCFrames() {
return ffc_frames;
}
public int getFFCGroups() {
return ffc_groups;
}
public int getFFCWaitFrames() {
return ffc_wait_frames;
}
public double getAcquireDelay() {
return acquire_delay;
}
public boolean runFFCBeforeMeasurments() {
return lwir_ffc;
}
public void setDefaultChannels() {
boolean[] old_selected = selected_channels;
if (isLwir16()) {
lwir_ips = new String[]{"192.168.0.41","192.168.0.42","192.168.0.43","192.168.0.43"};
lwir_channels = new int[] {0,1,2,3,4,5,6,7,8,9,10,11,12,12,14,15};
eo_ip = "192.168.0.45";
} else {
lwir_ips = new String[]{"192.168.0.36"};
lwir_channels = new int[] {0,1,2,3};
eo_ip = "192.168.0.38";
}
selected_channels = new boolean[lwir_channels.length + eo_channels.length];
for (int i = 0; i < selected_channels.length; i++) {
if (i < old_selected.length) {
selected_channels[i] = old_selected[i];
} else {
selected_channels[i] = true;
}
}
}
public void setProperties(String prefix,Properties properties){ public void setProperties(String prefix,Properties properties){
properties.setProperty(prefix+"camera_name", this.camera_name+"");
properties.setProperty(prefix+"avg_number", this.avg_number+""); properties.setProperty(prefix+"avg_number", this.avg_number+"");
properties.setProperty(prefix+"avg_number_eo", this.avg_number_eo+"");
properties.setProperty(prefix+"num_frames", this.num_frames+""); properties.setProperty(prefix+"num_frames", this.num_frames+"");
properties.setProperty(prefix+"lwir_ffc", this.lwir_ffc+""); properties.setProperty(prefix+"lwir_ffc", this.lwir_ffc+"");
properties.setProperty(prefix+"ffc_frames", this.ffc_frames+"");
properties.setProperty(prefix+"ffc_wait_frames", this.ffc_wait_frames+"");
properties.setProperty(prefix+"ffc_groups", this.ffc_groups+"");
properties.setProperty(prefix+"acquire_delay", this.acquire_delay+"");
properties.setProperty(prefix+"avg_all", this.avg_all+""); properties.setProperty(prefix+"avg_all", this.avg_all+"");
properties.setProperty(prefix+"lwir_ip", this.lwir_ip+""); properties.setProperty(prefix+"lwir_ips", arr_to_str(this.lwir_ips)); // this.lwir_ip+"");; this.lwir_ip+"");
properties.setProperty(prefix+"eo_ip", this.eo_ip+""); properties.setProperty(prefix+"eo_ip", this.eo_ip+"");
properties.setProperty(prefix+"lwir_channels", arr_to_str(this.lwir_channels)); properties.setProperty(prefix+"lwir_channels", arr_to_str(this.lwir_channels));
properties.setProperty(prefix+"eo_channels", arr_to_str(this.eo_channels)); properties.setProperty(prefix+"eo_channels", arr_to_str(this.eo_channels));
...@@ -147,6 +259,15 @@ public class LwirReaderParameters { ...@@ -147,6 +259,15 @@ public class LwirReaderParameters {
} }
public void getProperties(String prefix,Properties properties){ public void getProperties(String prefix,Properties properties){
String old_camera_name = this.camera_name;
if (properties.getProperty(prefix+"camera_name")!=null) {
this.camera_name = properties.getProperty(prefix+"camera_name");
} else {
this.camera_name = NAME_TALON; // old configs
}
if (!this.camera_name.equals(old_camera_name)) {
setDefaultChannels(); // modifies lwir_IPs, eo_ip, channels,
}
if (properties.getProperty(prefix+"vnir_ip")!=null) this.eo_ip= properties.getProperty(prefix+"vnir_ip"); if (properties.getProperty(prefix+"vnir_ip")!=null) this.eo_ip= properties.getProperty(prefix+"vnir_ip");
if (properties.getProperty(prefix+"vnir_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"vnir_channels")); if (properties.getProperty(prefix+"vnir_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"vnir_channels"));
if (properties.getProperty(prefix+"vnir_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"vnir_quality")); if (properties.getProperty(prefix+"vnir_quality")!=null) this.eo_quality=Double.parseDouble(properties.getProperty(prefix+"vnir_quality"));
...@@ -161,13 +282,17 @@ public class LwirReaderParameters { ...@@ -161,13 +282,17 @@ public class LwirReaderParameters {
if (properties.getProperty(prefix+"vnir_exp_corr")!=null) this.eo_exp_corr=str_to_darr(properties.getProperty(prefix+"vnir_exp_corr")); if (properties.getProperty(prefix+"vnir_exp_corr")!=null) this.eo_exp_corr=str_to_darr(properties.getProperty(prefix+"vnir_exp_corr"));
if (properties.getProperty(prefix+"vnir_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=str_to_darr(properties.getProperty(prefix+"vnir_gcorr_rbgb")); if (properties.getProperty(prefix+"vnir_gcorr_rbgb")!=null) this.eo_gcorr_rbgb=str_to_darr(properties.getProperty(prefix+"vnir_gcorr_rbgb"));
if (properties.getProperty(prefix+"vnir_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"vnir_lag")); // old version if (properties.getProperty(prefix+"vnir_lag")!=null) this.eo_lag=Integer.parseInt(properties.getProperty(prefix+"vnir_lag")); // old version
if (properties.getProperty(prefix+"avg_number")!=null) this.avg_number=Integer.parseInt(properties.getProperty(prefix+"avg_number")); if (properties.getProperty(prefix+"avg_number")!=null) this.avg_number=Integer.parseInt(properties.getProperty(prefix+"avg_number"));
if (properties.getProperty(prefix+"avg_number_eo")!=null) this.avg_number_eo=Integer.parseInt(properties.getProperty(prefix+"avg_number_eo"));
if (properties.getProperty(prefix+"num_frames")!=null) this.num_frames=Integer.parseInt(properties.getProperty(prefix+"num_frames")); if (properties.getProperty(prefix+"num_frames")!=null) this.num_frames=Integer.parseInt(properties.getProperty(prefix+"num_frames"));
if (properties.getProperty(prefix+"lwir_ffc")!=null) this.lwir_ffc= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_ffc")); if (properties.getProperty(prefix+"lwir_ffc")!=null) this.lwir_ffc= Boolean.parseBoolean(properties.getProperty(prefix+"lwir_ffc"));
if (properties.getProperty(prefix+"ffc_frames")!=null) this.ffc_frames=Integer.parseInt(properties.getProperty(prefix+"ffc_frames"));
if (properties.getProperty(prefix+"ffc_wait_frames")!=null) this.ffc_wait_frames=Integer.parseInt(properties.getProperty(prefix+"ffc_wait_frames"));
if (properties.getProperty(prefix+"ffc_groups")!=null) this.ffc_groups=Integer.parseInt(properties.getProperty(prefix+"ffc_groups"));
if (properties.getProperty(prefix+"acquire_delay")!=null) this.acquire_delay=Double.parseDouble(properties.getProperty(prefix+"acquire_delay"));
if (properties.getProperty(prefix+"avg_all")!=null) this.avg_all= Boolean.parseBoolean(properties.getProperty(prefix+"avg_all")); if (properties.getProperty(prefix+"avg_all")!=null) this.avg_all= Boolean.parseBoolean(properties.getProperty(prefix+"avg_all"));
if (properties.getProperty(prefix+"lwir_ip")!=null) this.lwir_ip= properties.getProperty(prefix+"lwir_ip"); if (properties.getProperty(prefix+"lwir_ip")!=null) this.lwir_ips[0]= properties.getProperty(prefix+"lwir_ip");
if (properties.getProperty(prefix+"lwir_ips")!=null) this.lwir_ips= str_to_sarr(properties.getProperty(prefix+"lwir_ips"));
if (properties.getProperty(prefix+"eo_ip")!=null) this.eo_ip= properties.getProperty(prefix+"eo_ip"); if (properties.getProperty(prefix+"eo_ip")!=null) this.eo_ip= properties.getProperty(prefix+"eo_ip");
if (properties.getProperty(prefix+"lwir_channels")!=null) this.lwir_channels=str_to_iarr(properties.getProperty(prefix+"lwir_channels")); if (properties.getProperty(prefix+"lwir_channels")!=null) this.lwir_channels=str_to_iarr(properties.getProperty(prefix+"lwir_channels"));
if (properties.getProperty(prefix+"eo_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"eo_channels")); if (properties.getProperty(prefix+"eo_channels")!=null) this.eo_channels=str_to_iarr(properties.getProperty(prefix+"eo_channels"));
...@@ -196,11 +321,17 @@ public class LwirReaderParameters { ...@@ -196,11 +321,17 @@ public class LwirReaderParameters {
@Override @Override
public LwirReaderParameters clone() { // throws CloneNotSupportedException { public LwirReaderParameters clone() { // throws CloneNotSupportedException {
LwirReaderParameters lrp = new LwirReaderParameters(); LwirReaderParameters lrp = new LwirReaderParameters();
lrp.camera_name = this.camera_name;
lrp.avg_number= this.avg_number; lrp.avg_number= this.avg_number;
lrp.avg_number_eo= this.avg_number_eo;
lrp.num_frames= this.num_frames; lrp.num_frames= this.num_frames;
lrp.lwir_ffc= this.lwir_ffc; lrp.lwir_ffc= this.lwir_ffc;
lrp.ffc_frames= this.ffc_frames;
lrp.ffc_wait_frames= this.ffc_wait_frames;
lrp.ffc_groups= this.ffc_groups;
lrp.acquire_delay= this.acquire_delay;
lrp.avg_all= this.avg_all; lrp.avg_all= this.avg_all;
lrp.lwir_ip= this.lwir_ip; lrp.lwir_ips= this.lwir_ips.clone();
lrp.eo_ip= this.eo_ip; lrp.eo_ip= this.eo_ip;
lrp.lwir_channels= this.lwir_channels.clone(); lrp.lwir_channels= this.lwir_channels.clone();
lrp.eo_channels= this.eo_channels.clone(); lrp.eo_channels= this.eo_channels.clone();
...@@ -235,11 +366,25 @@ public class LwirReaderParameters { ...@@ -235,11 +366,25 @@ public class LwirReaderParameters {
if (!(o instanceof LwirReaderParameters)) { if (!(o instanceof LwirReaderParameters)) {
return false; return false;
} }
LwirReaderParameters lrp = (LwirReaderParameters) o; LwirReaderParameters lrp = (LwirReaderParameters) o;
return (lrp.avg_number == this.avg_number) && boolean all_ips_eq = lrp.lwir_ips.length == this.lwir_ips.length;
if (all_ips_eq) {
for (int i = 0; (i < lrp.lwir_ips.length) && all_ips_eq; i++) {
all_ips_eq &= (lrp.lwir_ips[i].equals(this.lwir_ips[i]));
}
}
return (lrp.camera_name.equals(this.camera_name)) &&
(lrp.avg_number == this.avg_number) &&
(lrp.avg_number_eo == this.avg_number_eo) &&
(lrp.lwir_ffc == this.lwir_ffc) && (lrp.lwir_ffc == this.lwir_ffc) &&
(lrp.ffc_frames == this.ffc_frames) &&
(lrp.ffc_wait_frames == this.ffc_wait_frames) &&
(lrp.ffc_groups == this.ffc_groups) &&
(lrp.acquire_delay == this.acquire_delay) &&
(lrp.avg_all == this.avg_all) && (lrp.avg_all == this.avg_all) &&
(lrp.lwir_ip.equals(this.lwir_ip)) && all_ips_eq && //(lrp.lwir_ip.equals(this.lwir_ip)) &&
(lrp.eo_ip.equals(this.eo_ip)) && (lrp.eo_ip.equals(this.eo_ip)) &&
(java.util.Arrays.equals(lrp.lwir_channels, this.lwir_channels)) && (java.util.Arrays.equals(lrp.lwir_channels, this.lwir_channels)) &&
(java.util.Arrays.equals(lrp.eo_channels, this.eo_channels)) && (java.util.Arrays.equals(lrp.eo_channels, this.eo_channels)) &&
...@@ -260,36 +405,44 @@ public class LwirReaderParameters { ...@@ -260,36 +405,44 @@ public class LwirReaderParameters {
(lrp.eo_lag == this.eo_lag) && (lrp.eo_lag == this.eo_lag) &&
(lrp.max_mismatch_ms == this.max_mismatch_ms) && (lrp.max_mismatch_ms == this.max_mismatch_ms) &&
(lrp.max_frame_diff == this.max_frame_diff) && (lrp.max_frame_diff == this.max_frame_diff) &&
(lrp.debug_level == this.debug_level) && // (lrp.debug_level == this.debug_level) &&
(java.util.Arrays.equals(lrp.selected_channels, this.selected_channels)) && (java.util.Arrays.equals(lrp.selected_channels, this.selected_channels));
(lrp.show_images == this.show_images); // && (lrp.show_images == this.show_images);
} }
@Override @Override
public int hashCode() { public int hashCode() {
int prime = 31; int prime = 31;
int result = 1; int result = 1;
result = prime * result + (new Integer(avg_number)).hashCode(); result = prime * result + camera_name.hashCode();
result = prime * result + ((Integer) avg_number).hashCode();
result = prime * result + ((Integer) avg_number_eo).hashCode();
result = prime * result + (lwir_ffc?1:0); result = prime * result + (lwir_ffc?1:0);
result = prime * result + ((Integer) ffc_frames).hashCode();
result = prime * result + ((Integer) ffc_wait_frames).hashCode();
result = prime * result + ((Integer) ffc_groups).hashCode();
result = prime * result + ((Double) acquire_delay).hashCode();
result = prime * result + (avg_all?1:0); result = prime * result + (avg_all?1:0);
result = prime * result + lwir_ip.hashCode(); for (String ip:lwir_ips) {
result = prime * result + ip.hashCode();
}
result = prime * result + eo_ip.hashCode(); result = prime * result + eo_ip.hashCode();
result = prime * result + arr_to_str(lwir_channels).hashCode(); result = prime * result + arr_to_str(lwir_channels).hashCode();
result = prime * result + arr_to_str(eo_channels).hashCode(); result = prime * result + arr_to_str(eo_channels).hashCode();
result = prime * result + (lwir_telemetry?1:0); result = prime * result + (lwir_telemetry?1:0);
result = prime * result + (eo_full_window?1:0); result = prime * result + (eo_full_window?1:0);
result = prime * result + (new Double(eo_quality)).hashCode(); result = prime * result + ((Double) eo_quality).hashCode();
result = prime * result + (eo_scale?1:0); result = prime * result + (eo_scale?1:0);
result = prime * result + (eo_autoexp?1:0); result = prime * result + (eo_autoexp?1:0);
result = prime * result + (new Double(eo_max_autoexp_ms)).hashCode(); result = prime * result + ((Double) eo_max_autoexp_ms).hashCode();
result = prime * result + (new Double(eo_exposure_ms)).hashCode(); result = prime * result + ((Double) eo_exposure_ms).hashCode();
result = prime * result + (eo_whitebal?1:0); result = prime * result + (eo_whitebal?1:0);
result = prime * result + (new Double(eo_gain_g)).hashCode(); result = prime * result + ((Double) eo_gain_g).hashCode();
result = prime * result + (new Double(eo_gain_rg)).hashCode(); result = prime * result + ((Double) eo_gain_rg).hashCode();
result = prime * result + (new Double(eo_gain_bg)).hashCode(); result = prime * result + ((Double) eo_gain_bg).hashCode();
result = prime * result + arr_to_str(eo_exp_corr).hashCode(); result = prime * result + arr_to_str(eo_exp_corr).hashCode();
result = prime * result + arr_to_str(eo_gcorr_rbgb).hashCode(); result = prime * result + arr_to_str(eo_gcorr_rbgb).hashCode();
result = prime * result + (new Integer(lwir_trig_dly)).hashCode(); result = prime * result + ((Integer) lwir_trig_dly).hashCode();
result = prime * result + arr_to_str(selected_channels).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(eo_lag)).hashCode(); // result = prime * result + (new Integer(eo_lag)).hashCode();
...@@ -299,14 +452,30 @@ public class LwirReaderParameters { ...@@ -299,14 +452,30 @@ public class LwirReaderParameters {
} }
public void dialogQuestions(GenericJTabbedDialog gd) { public void dialogQuestions(GenericJTabbedDialog gd) {
gd.addNumericField("Number to average",this.avg_number, 0,3,"","Number of acquired consecutive images to average"); // TODO: separate parameters into common and type -specific
gd. addChoice("Camera name", CAMERA_NAMES, camera_name, "Camera type - now Talon (4*Lepton+4*MT9P006) and LWIR16 (16xBoson+4*MT9P006");
gd.addNumericField("Number to average LWIR",this.avg_number, 0,3,"","Number of acquired consecutive LWIR images to average");
gd.addNumericField("Number to average EO", this.avg_number_eo, 0,3,"","Number of acquired consecutive EO images to average");
gd.addNumericField("Number of sets to acquire",this.num_frames, 0,3,"","Total number, may be limited by EO quality/frame size (last will be missed/null)"); gd.addNumericField("Number of sets to acquire",this.num_frames, 0,3,"","Total number, may be limited by EO quality/frame size (last will be missed/null)");
gd.addCheckbox ("Run FFC", this.lwir_ffc, "Perform calibration before each measurements to average (Lepton takes ~1.6 sec, 15 frames), Boson - twice ffc_frames");
String [] sffc_frames = new String [BOSON_FFC_FRAMES.length];
for (int i = 0; i < sffc_frames.length; i++) sffc_frames[i]=""+BOSON_FFC_FRAMES[i];
gd. addChoice ("FFC frames", sffc_frames, ""+ffc_frames,"Number of frames to integrate during FFC (Full FFC takes 2x this number of frames)" );
gd.addNumericField("FFC wait frames",this.ffc_wait_frames, 0,3,"","Wait this number of frames after FFC is supposed to finish");
gd.addCheckbox ("Run FFC", this.lwir_ffc, "Perform calibration before each measurements to average (takes ~1.6 sec, 15 frames)"); String [] sffc_groups = new String [FFC_GROUPS.length];
for (int i = 0; i < sffc_groups.length; i++) sffc_groups[i]=""+FFC_GROUPS[i];
gd. addChoice ("FFC groups", sffc_groups, ""+ffc_groups,"Split FFC actions in groups to limit power consumption" );
gd.addNumericField("Acquire delay", this.acquire_delay, 3,6,"s", "Schedule synchronous acquisition ahead of current master camera time");
gd.addCheckbox ("Average all", this.avg_all, "Average all simultaneously acquired images (unchecked - only requested number to average)"); gd.addCheckbox ("Average all", this.avg_all, "Average all simultaneously acquired images (unchecked - only requested number to average)");
gd.addStringField ("LWIR IP", this.lwir_ip, 20, "LWIR camera IP address"); // gd.addStringField ("LWIR IP", this.lwir_ip, 20, "LWIR camera IP address");
for (int i = 0; i < this.lwir_ips.length; i++) {
gd.addStringField ("LWIR IP"+i, this.lwir_ips[i], 20, "LWIR camera "+(i+((i==0)?" (master)":""))+" IP address");
}
gd.addStringField ("EO IP", this.eo_ip, 20, "Visible range high resolution camera IP address"); gd.addStringField ("EO IP", this.eo_ip, 20, "Visible range high resolution camera IP address");
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), 40, "Space-separated list of used LWIR camera channels, such as '0 1 2 3'");
gd.addStringField ("EO channels", arr_to_str(this.eo_channels), 20, "Space-separated list of used visible range camera channels, such as '0 1 2 3'"); gd.addStringField ("EO channels", arr_to_str(this.eo_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.addCheckbox ("EO full window",this.eo_full_window, "Set EO to full window, disregarding preset margins (need reset to restore original)"); gd.addCheckbox ("EO full window",this.eo_full_window, "Set EO to full window, disregarding preset margins (need reset to restore original)");
...@@ -319,23 +488,34 @@ public class LwirReaderParameters { ...@@ -319,23 +488,34 @@ public class LwirReaderParameters {
gd.addNumericField("EO gain G", this.eo_gain_g, 3,6,"","Analog gain for green channel for all visible range camera channels (normally 2.0)"); gd.addNumericField("EO gain G", this.eo_gain_g, 3,6,"","Analog gain for green channel for all visible range camera channels (normally 2.0)");
gd.addNumericField("EO gain R/G", this.eo_gain_rg, 3,6,"","Red to green gain ratio for all visible range camera channels"); gd.addNumericField("EO gain R/G", this.eo_gain_rg, 3,6,"","Red to green gain ratio for all visible range camera channels");
gd.addNumericField("EO gain B/G", this.eo_gain_bg, 3,6,"","Blue to green gain ratio for all visible range camera channels"); gd.addNumericField("EO gain B/G", this.eo_gain_bg, 3,6,"","Blue to green gain ratio for all visible range camera channels");
gd.addStringField ("EO exposuere corrections", arr_to_str(this.eo_exp_corr), 50, "Fine corrections of channel exposures (4 channel relative exposures)"); gd.addStringField ("EO exposure corrections", arr_to_str(this.eo_exp_corr), 50, "Fine corrections of channel exposures (4 channel relative exposures)");
gd.addStringField ("EO gain corrections", arr_to_str(this.eo_gcorr_rbgb), 100, "Fine corrections to per channel, per color gains:'r0 b0 gb0 r1 b1 gb1 ...'"); gd.addStringField ("EO gain corrections", arr_to_str(this.eo_gcorr_rbgb), 100, "Fine corrections to per channel, per color gains:'r0 b0 gb0 r1 b1 gb1 ...'");
gd.addNumericField("LWIR trig dly", this.lwir_trig_dly, 0,10,"x10ns","Output trigger delay, should eventually match Lepton+FPGA latency to trigger EO exactly 1 frame after LWIR. 0 does not work with current FPGA - usec do not match sec in transmitted timestamp"); gd.addNumericField("LWIR trig dly", this.lwir_trig_dly, 0,10,"x10ns","Output trigger delay, should eventually match Lepton+FPGA latency to trigger EO exactly 1 frame after LWIR. 0 does not work with current FPGA - usec do not match sec in transmitted timestamp");
gd.addNumericField("EO lag", this.eo_lag, 0,3,"","Visible camera lag (in frames) relative to LWIR one"); gd.addNumericField("EO lag", this.eo_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.addStringField ("Selected channels", arr_to_str(this.selected_channels), 40, "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)");
} }
public void dialogAnswers(GenericJTabbedDialog gd) { public void dialogAnswers(GenericJTabbedDialog gd) {
String new_camera_name = CAMERA_NAMES[gd.getNextChoiceIndex()];
this.avg_number = (int) gd.getNextNumber(); this.avg_number = (int) gd.getNextNumber();
this.avg_number_eo = (int) gd.getNextNumber();
this.num_frames = (int) gd.getNextNumber(); this.num_frames = (int) gd.getNextNumber();
this.lwir_ffc = gd.getNextBoolean(); this.lwir_ffc = gd.getNextBoolean();
this.ffc_frames = BOSON_FFC_FRAMES[gd.getNextChoiceIndex()];
this.ffc_wait_frames = (int) gd.getNextNumber();
this.ffc_groups = FFC_GROUPS[gd.getNextChoiceIndex()];
this.acquire_delay = gd.getNextNumber();
this.avg_all = gd.getNextBoolean(); this.avg_all = gd.getNextBoolean();
this.lwir_ip = gd.getNextString(); // this.lwir_ip = gd.getNextString();
for (int i = 0; i < this.lwir_ips.length; i++) {
this.lwir_ips[i] = gd.getNextString();
}
this.eo_ip = gd.getNextString(); this.eo_ip = gd.getNextString();
this.lwir_channels = str_to_iarr(gd.getNextString()); this.lwir_channels = str_to_iarr(gd.getNextString());
this.eo_channels = str_to_iarr(gd.getNextString()); this.eo_channels = str_to_iarr(gd.getNextString());
...@@ -359,6 +539,10 @@ public class LwirReaderParameters { ...@@ -359,6 +539,10 @@ public class LwirReaderParameters {
this.debug_level = (int) gd.getNextNumber(); this.debug_level = (int) gd.getNextNumber();
this.selected_channels = str_to_barr(gd.getNextString()); this.selected_channels = str_to_barr(gd.getNextString());
this.show_images = gd.getNextBoolean(); this.show_images = gd.getNextBoolean();
if (!this.camera_name.equals(new_camera_name)) {
this.camera_name = new_camera_name; // in the very end to to disturb the number of items
setDefaultChannels(); // modifies lwir_IPs, eo_ip, channels,
}
parameters_updated = true; parameters_updated = true;
} }
...@@ -477,6 +661,17 @@ public class LwirReaderParameters { ...@@ -477,6 +661,17 @@ public class LwirReaderParameters {
return s.trim(); return s.trim();
} }
private String arr_to_str(String [] arr) {
String s = "";
for (int i = 0; i < arr.length; i++) {
s += arr[i].trim();
if (i < (arr.length - 1)){
s += ",";
}
}
return s;
}
private boolean [] str_to_barr(String s) { private boolean [] str_to_barr(String s) {
int [] iarr = str_to_iarr(s); int [] iarr = str_to_iarr(s);
if (iarr == null) return null; if (iarr == null) return null;
...@@ -515,6 +710,20 @@ public class LwirReaderParameters { ...@@ -515,6 +710,20 @@ public class LwirReaderParameters {
return darr; return darr;
} }
private String [] str_to_sarr(String s) {
String [] sa;
if (s.indexOf(",") >= 0) {
sa = s.trim().split(",");
} else {
sa = s.trim().split(" ");
}
String [] sarr = new String [sa.length];
for (int i = 0; i < sa.length; i++) {
sarr[i]=sa[i].trim();
}
return sarr;
}
public boolean [] selectSourceChannels(){ public boolean [] selectSourceChannels(){
return selectSourceChannels(selected_channels); return selectSourceChannels(selected_channels);
......
...@@ -76,14 +76,13 @@ public class Boson640Telemetry { ...@@ -76,14 +76,13 @@ public class Boson640Telemetry {
dbg = bb.get(); dbg = bb.get();
bb.position(offset); bb.position(offset);
// this.bbtm =
bb.get(btm, 0,btm.length); bb.get(btm, 0,btm.length);
this.bbtm = ByteBuffer.wrap(btm); this.bbtm = ByteBuffer.wrap(btm);
this.bbtm.order( bb.order()); // or is it already same as in bb? this.bbtm.order( bb.order()); // or is it already same as in bb?
System.out.println("getShort(94)"+this.bbtm.getShort(94)); // System.out.println("getShort(94)"+this.bbtm.getShort(94));
System.out.println("getLong(162)"+this.bbtm.getLong(162)); // System.out.println("getLong(162)"+this.bbtm.getLong(162));
System.out.println("getLong(162)"+this.bbtm.getInt(162)); // System.out.println("getLong(162)"+this.bbtm.getInt(162));
......
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