Commit 57a60fb7 authored by Andrey Filippov's avatar Andrey Filippov

bisin telemetry

parent 10f1f014
/**
** -----------------------------------------------------------------------------**
** Boson640Telemetry.java
**
** Parses FLIR Boson640 telemetry data
**
** Copyright (C) 2021 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** Boson640Telemetry.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.readers;
import java.nio.ByteBuffer;
import java.util.HashMap;
public class Boson640Telemetry {
private static final int BOSON640_IMAGE_WIDTH = 640;
private static final int BOSON640_IMAGE_HEIGHT = 512;
private static final int BOSON640_TELEMETRY_LINES = 1;
private static final String REVISION = "REVISION"; private static final int REVISION_OFFSET = 0; // 2
private static final String CAMSERIAL = "CAMSERIAL"; private static final int CAMSERIAL_OFFSET = 2; // 4
private static final String SENSSERIAL = "SENSSERIAL"; private static final int SENSSERIAL_OFFSET = 6; // 4
private static final String PART_ASCII = "PART_ASCII"; private static final int PART_ASCII_OFFSET = 10; // 20
private static final String SOFT_REV = "SOFT_REV"; private static final int SOFT_REV_OFFSET = 44; // 12
private static final String FRAME_RATE = "FRAME_RATE"; private static final int FRAME_RATE_OFFSET = 56; // 2
private static final String STATUS = "STATUS"; private static final int STATUS_OFFSET = 76; // hex,8
private static final String FRAME = "FRAME"; private static final int FRAME_OFFSET = 84; // 4
private static final String FRAME_FFC = "FRAME_FFC"; private static final int FRAME_FFC_OFFSET = 88; // 4
private static final String FPA_KELV = "FPA_KELV"; private static final int FPA_KELV_OFFSET = 94; // 2
private static final String FFC_KELV = "FFC_KELV"; private static final int FFC_KELV_OFFSET = 96; // 2
private static final String PIPELINE = "PIPELINE"; private static final int PIPELINE_OFFSET = 110; // 4
private static final String FFC_INTEG = "FFC_INTEG"; private static final int FFC_INTEG_OFFSET = 114; // 2
private static final String NUC_CURRENT = "NUC_CURRENT"; private static final int NUC_CURRENT_OFFSET = 158; // 2
private static final String NUC_DESIRED = "NUC_DESIRED"; private static final int NUC_DESIRED_OFFSET = 160; // 2
private static final String CORE_TEMP = "CORE_TEMP"; private static final int CORE_TEMP_OFFSET = 162; // 4
private static final String OVERTEMP = "OVERTEMP"; private static final int OVERTEMP_OFFSET = 166; // 4
private static final String ROI_POP_LTH = "ROI_POP_LTH"; private static final int ROI_POP_LTH_OFFSET = 170; // 4
private static final String ROI_POP_HTL = "ROI_POP_HTL"; private static final int ROI_POP_HTL_OFFSET = 174; // 4
private static final String TGL_PATT = "TGL_PATT"; private static final int TGL_PATT_OFFSET = 178; // 6
private static final String ZOOM_FACT = "ZOOM_FACT"; private static final int ZOOM_FACT_OFFSET = 184; // 4
private static final String ZOOM_X0 = "ZOOM_X0"; private static final int ZOOM_X0_OFFSET = 188; // 4
private static final String ZOOM_Y0 = "ZOOM_Y0"; private static final int ZOOM_Y0_OFFSET = 192; // 4
private float [] pixels = null;
private byte [] btm = null;
private ByteBuffer bbtm = null;
public Boson640Telemetry(ByteBuffer bb, float [] pixels, boolean bottom) {
this.pixels = pixels;
int offset = 2*(bottom?(BOSON640_IMAGE_WIDTH * BOSON640_IMAGE_HEIGHT):0);
if (pixels.length > BOSON640_IMAGE_WIDTH*BOSON640_IMAGE_HEIGHT) {
this.btm = new byte [BOSON640_IMAGE_WIDTH* BOSON640_TELEMETRY_LINES * 2];
bb.position(offset);
byte dbg = bb.get();
dbg = bb.get();
dbg = bb.get();
dbg = bb.get();
dbg = bb.get();
bb.position(offset);
// this.bbtm =
bb.get(btm, 0,btm.length);
this.bbtm = ByteBuffer.wrap(btm);
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("getLong(162)"+this.bbtm.getLong(162));
System.out.println("getLong(162)"+this.bbtm.getInt(162));
this.pixels = new float [BOSON640_IMAGE_WIDTH * BOSON640_IMAGE_HEIGHT];
System.arraycopy(
pixels,
(bottom? 0: BOSON640_IMAGE_WIDTH * BOSON640_TELEMETRY_LINES),
this.pixels,
0,
this.pixels.length);
}
}
public static int getWidth() {
return BOSON640_IMAGE_WIDTH;
}
public static int getHeight() {
return BOSON640_IMAGE_HEIGHT;
}
public static int getTelemetryLines() {
return BOSON640_TELEMETRY_LINES;
}
public boolean hasTelemetry() {
return bbtm != null;
}
public float [] getPixels() {
return pixels;
}
public HashMap<String, String> parseTelemetry(){
HashMap<String, String> tm = new HashMap<String, String>();
byte [] bytes = getBytes(REVISION_OFFSET,2);
tm.put(REVISION, "" + bytes[0] + "." + bytes[1]); // "0.2"
tm.put(CAMSERIAL, "" + String.format("%d", getU32 (CAMSERIAL_OFFSET)));
tm.put(SENSSERIAL, "" + String.format("%d", getU32 (SENSSERIAL_OFFSET)));
tm.put(PART_ASCII, "" + getAscii(PART_ASCII_OFFSET,20));
tm.put(STATUS, "" + (bbtm.getLong(STATUS_OFFSET))); // getHex (STATUS_OFFSET,8));
tm.put(SOFT_REV, "" + getU32 (SOFT_REV_OFFSET)+"."+getU32 (SOFT_REV_OFFSET+4)+"."+getU32 (SOFT_REV_OFFSET+8));
tm.put(FRAME_RATE, "" + getU16 (FRAME_RATE_OFFSET));
tm.put(FRAME, "" + getU32 (FRAME_OFFSET));
tm.put(FRAME_FFC, "" + getU32 (FRAME_FFC_OFFSET));
tm.put(FPA_KELV, String.format("%.1f", getKelv10 (FPA_KELV_OFFSET)));
tm.put(FFC_KELV, String.format("%.1f", getKelv10 (FFC_KELV_OFFSET)));
tm.put(PIPELINE, "" + getU32 (PIPELINE_OFFSET));
tm.put(FFC_INTEG, "" + getU16 (FFC_INTEG_OFFSET));
tm.put(NUC_CURRENT, "" + getU16 (NUC_CURRENT_OFFSET));
tm.put(NUC_DESIRED, "" + getU16 (NUC_DESIRED_OFFSET));
tm.put(CORE_TEMP, String.format("%.3f", getCelsius1000 (CORE_TEMP_OFFSET)));
tm.put(OVERTEMP, "" + getU32 (OVERTEMP_OFFSET));
tm.put(ROI_POP_LTH, "" + getU32 (ROI_POP_LTH_OFFSET));
tm.put(ROI_POP_HTL, "" + getU32 (ROI_POP_HTL_OFFSET));
tm.put(TGL_PATT, "" + getHex (TGL_PATT_OFFSET,8));
tm.put(ZOOM_FACT, "" + getU32 (ZOOM_FACT_OFFSET));
tm.put(ZOOM_X0, "" + getU32 (ZOOM_X0_OFFSET));
tm.put(ZOOM_Y0, "" + getU32 (ZOOM_Y0_OFFSET));
return tm;
}
// internal methods
private long getU32(int offset) {
return ((long) (bbtm.getInt(offset))) & 0xffffffff;
}
private long getU16(int offset) {
return ((long) (bbtm.getShort(offset))) & 0xffff;
}
private byte[] getBytes (int offset, int len) { // offset, len in bytes!
byte [] bytes = new byte [len];
for (int i = 0; i<len; i++) {
bytes[i] = bbtm.get(offset+i);
}
return bytes;
}
private String getHex (int offset, int len) { // offset, len bytes,
String s = "";
for (byte b :getBytes(offset, len)) {
s += String.format("%02x", b);
}
return s;
}
private String getAscii (int offset, int len) { // offset, len bytes,
String s = "";
for (byte b :getBytes(offset, len)) {
if (b == 0) break;
s += String.format("%c", b);
}
return s;
}
private double getKelv10(int offset) {
return 0.1*getU16(offset);
}
private double getCelsius1000(int offset) {
return 0.001*bbtm.getInt(offset);
}
}
...@@ -206,24 +206,49 @@ public class ImagejJp4Tiff { ...@@ -206,24 +206,49 @@ public class ImagejJp4Tiff {
Hashtable<String, Object> meta_hash = reader.getGlobalMetadata(); Hashtable<String, Object> meta_hash = reader.getGlobalMetadata();
boolean degamma = bytes_per_pixel < 2; // both JP4 and 8-bit tiff boolean degamma = bytes_per_pixel < 2; // both JP4 and 8-bit tiff
// FIXME: Do not scale telemetry!
/*
if (deGammaScale(pixels, reader.getSizeX(), meta_hash, degamma, scale ) == null) { if (deGammaScale(pixels, reader.getSizeX(), meta_hash, degamma, scale ) == null) {
LOGGER.error("Problem degamma/scaling of "+content_fileName); LOGGER.error("Problem degamma/scaling of "+content_fileName);
} }
*/
boolean telemetry = (bytes_per_pixel == 2); boolean telemetry = (bytes_per_pixel == 2);
boolean lepton_telemetry = telemetry && ((reader.getSizeX() == 160));
boolean boson_telemetry = telemetry && ((reader.getSizeX() == 640));
Lepton3Telemetry lepton3Telemetry = null; Lepton3Telemetry lepton3Telemetry = null;
Boson640Telemetry boson640Telemetry = null;
if (telemetry) { if (telemetry) {
lepton3Telemetry = new Lepton3Telemetry(bb,pixels, true); // bottom if (lepton_telemetry) {
telemetry = lepton3Telemetry.hasTelemetry(); lepton3Telemetry = new Lepton3Telemetry(bb,pixels, true); // bottom
telemetry = lepton3Telemetry.hasTelemetry();
} else if (boson_telemetry) {
boson640Telemetry = new Boson640Telemetry(bb,pixels, false); // top
telemetry = boson640Telemetry.hasTelemetry();
}
} }
ImageProcessor ip = null; ImageProcessor ip = null;
if (telemetry) { if (telemetry) {
ip=new FloatProcessor(Lepton3Telemetry.LEPTON3_IMAGE_WIDTH, Lepton3Telemetry.LEPTON3_IMAGE_HEIGHT); if (lepton_telemetry) {
ip.setPixels(lepton3Telemetry.getPixels()); // bo ip=new FloatProcessor(Lepton3Telemetry.getWidth(), Lepton3Telemetry.getHeight());
pixels = lepton3Telemetry.getPixels();
// ip.setPixels(lepton3Telemetry.getPixels()); // bo
} else if (boson_telemetry) {
ip=new FloatProcessor(Boson640Telemetry.getWidth(), Boson640Telemetry.getHeight());
pixels=boson640Telemetry.getPixels(); // bo
// ip.setPixels(boson640Telemetry.getPixels()); // bo
}
} else { } else {
ip=new FloatProcessor(reader.getSizeX(), reader.getSizeY()); ip=new FloatProcessor(reader.getSizeX(), reader.getSizeY());
ip.setPixels(pixels); // ip.setPixels(pixels);
}
if (deGammaScale(pixels, reader.getSizeX(), meta_hash, degamma, scale ) == null) {
LOGGER.error("Problem degamma/scaling of "+content_fileName);
} }
ip.setPixels(pixels);
ip.resetMinAndMax(); ip.resetMinAndMax();
String prefix = ElphelTiffReader.ELPHEL_PROPERTY_PREFIX; String prefix = ElphelTiffReader.ELPHEL_PROPERTY_PREFIX;
String imageName = content_fileName; // path; String imageName = content_fileName; // path;
...@@ -247,12 +272,18 @@ public class ImagejJp4Tiff { ...@@ -247,12 +272,18 @@ public class ImagejJp4Tiff {
imp.setProperty(std+(key.replace(" ","_").replace("/","_")), meta_hash.get(key).toString()); imp.setProperty(std+(key.replace(" ","_").replace("/","_")), meta_hash.get(key).toString());
} }
} }
if (telemetry) { if (lepton_telemetry) {
HashMap<String, String> telemetryMap = lepton3Telemetry.parseTelemetry(); HashMap<String, String> telemetryMap = lepton3Telemetry.parseTelemetry();
for (String key:telemetryMap.keySet()) { for (String key:telemetryMap.keySet()) {
imp.setProperty(TELEMETRY_PREFIX+key, telemetryMap.get(key)); imp.setProperty(TELEMETRY_PREFIX+key, telemetryMap.get(key));
} }
} }
if (boson_telemetry) {
HashMap<String, String> telemetryMap = boson640Telemetry.parseTelemetry();
for (String key:telemetryMap.keySet()) {
imp.setProperty(TELEMETRY_PREFIX+key, telemetryMap.get(key));
}
}
encodeProperiesToInfo(imp); encodeProperiesToInfo(imp);
Location.mapFile(content_fileName, null); Location.mapFile(content_fileName, null);
return imp; return imp;
...@@ -368,6 +399,10 @@ public class ImagejJp4Tiff { ...@@ -368,6 +399,10 @@ public class ImagejJp4Tiff {
for (int x = 0; x < width; x+=2) { for (int x = 0; x < width; x+=2) {
for (int dx = 0; dx<2; dx++) { for (int dx = 0; dx<2; dx++) {
int indx = base + x + dx; int indx = base + x + dx;
if (indx >= pixels.length) {
System.out.println(indx);
continue;
}
pixels[indx] *= rgains[(dy << 1) + 1 - dx]; pixels[indx] *= rgains[(dy << 1) + 1 - dx];
} }
} }
......
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