Skip to content

Commit

Permalink
Place timestamps in original metadata hashtable and populate PlaneTim…
Browse files Browse the repository at this point in the history
…ing.DeltaT.
  • Loading branch information
melissalinkert committed Nov 9, 2009
1 parent 0fa9157 commit 4aa1f75
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 59 deletions.
149 changes: 94 additions & 55 deletions components/bio-formats/src/loci/formats/in/FluoviewReader.java
Expand Up @@ -26,6 +26,7 @@
import java.io.IOException;
import java.util.StringTokenizer;

import loci.common.DateTools;
import loci.common.RandomAccessInputStream;
import loci.formats.CoreMetadata;
import loci.formats.FormatException;
Expand Down Expand Up @@ -59,12 +60,18 @@ public class FluoviewReader extends BaseTiffReader {
private static final int MMHEADER = 34361;
private static final int MMSTAMP = 34362;

/** Date format */
private static final String DATE_FORMAT = "MM/dd/yyyy HH:mm:ss.SSS";

// -- Fields --

/** Pixel dimensions for this file. */
private double voxelX = 1, voxelY = 1, voxelZ = 1, voxelC = 1, voxelT = 1;

private String dimensionOrder;
private String date = null;
private int timeIndex = -1;
private long[][] stamps = null;

// hardware settings
private String[] gains, voltages, offsets, channelNames, lensNA;
Expand Down Expand Up @@ -147,6 +154,9 @@ public void close(boolean fileOnly) throws IOException {
gains = voltages = offsets = channelNames = lensNA = null;
mag = detManu = objManu = comment = null;
gamma = null;
date = null;
timeIndex = -1;
stamps = null;
}
}

Expand Down Expand Up @@ -229,7 +239,7 @@ protected void initStandardMetadata() throws FormatException, IOException {

// now we need to read the MMSTAMP data to determine dimension order

double[][] stamps = new double[8][ifds.size()];
stamps = new long[8][ifds.size()];
for (int i=0; i<ifds.size(); i++) {
s = ifds.get(i).getIFDShortArray(MMSTAMP, true);
byte[] stamp = new byte[s.length];
Expand All @@ -239,9 +249,9 @@ protected void initStandardMetadata() throws FormatException, IOException {
}
ras = new RandomAccessInputStream(stamp);

// each stamp is 8 doubles, representing the position on dimensions 3-10
// each stamp is 8 longs, representing the position on dimensions 3-10
for (int j=0; j<8; j++) {
stamps[j][i] = ras.readDouble();
stamps[j][i] = ras.readLong() / 10000;
}
}

Expand Down Expand Up @@ -287,6 +297,7 @@ else if (name.equals("time") || name.equals("t") ||
dimensionOrder += "T";
}
voxelT = voxel;
timeIndex = i - 2;
}
else {
if (dimensionOrder.indexOf("S") == -1) dimensionOrder += "S";
Expand Down Expand Up @@ -329,72 +340,88 @@ else if (name.equals("time") || name.equals("t") ||
channelNames = new String[getSizeC()];
lensNA = new String[getSizeC()];

if (comment != null && comment.startsWith("[")) {
int start = comment.indexOf("[Acquisition Parameters]");
int end = comment.indexOf("[Acquisition Parameters End]");
if (start != -1 && end != -1 && end > start) {
String parms = comment.substring(start + 24, end).trim();

// this is an INI-style comment, with one key/value pair per line

StringTokenizer st = new StringTokenizer(parms, "\n");
while (st.hasMoreTokens()) {
String token = st.nextToken();
int eq = token.indexOf("=");
if (eq != -1) {
String key = token.substring(0, eq);
String value = token.substring(eq + 1);
addGlobalMeta(key, value);
if (key.startsWith("Gain Ch")) {
for (int i=0; i<gains.length; i++) {
if (gains[i] == null) {
gains[i] = value;
break;
}
if (comment != null) {
// this is an INI-style comment, with one key/value pair per line

StringTokenizer st = new StringTokenizer(comment, "\n");
while (st.hasMoreTokens()) {
String token = st.nextToken();
int eq = token.indexOf("=");
if (eq != -1) {
String key = token.substring(0, eq);
String value = token.substring(eq + 1);
addGlobalMeta(key, value);
if (key.startsWith("Gain Ch")) {
for (int i=0; i<gains.length; i++) {
if (gains[i] == null) {
gains[i] = value;
break;
}
}
else if (key.startsWith("PMT Voltage Ch")) {
for (int i=0; i<voltages.length; i++) {
if (voltages[i] == null) {
voltages[i] = value;
break;
}
}
else if (key.startsWith("PMT Voltage Ch")) {
for (int i=0; i<voltages.length; i++) {
if (voltages[i] == null) {
voltages[i] = value;
break;
}
}
else if (key.startsWith("Offset Ch")) {
for (int i=0; i<offsets.length; i++) {
if (offsets[i] == null) {
offsets[i] = value;
break;
}
}
else if (key.startsWith("Offset Ch")) {
for (int i=0; i<offsets.length; i++) {
if (offsets[i] == null) {
offsets[i] = value;
break;
}
}
else if (key.equals("Magnification")) mag = value;
else if (key.equals("System Configuration")) detManu = value;
else if (key.equals("Objective Lens")) objManu = value;
else if (key.equals("Gamma")) gamma = new Double(value);
else if (key.startsWith("Channel ") && key.endsWith("Dye")) {
for (int i=0; i<channelNames.length; i++) {
if (channelNames[i] == null) {
channelNames[i] = value;
break;
}
}
else if (key.equals("Magnification")) mag = value;
else if (key.equals("System Configuration")) detManu = value;
else if (key.equals("Objective Lens")) objManu = value;
else if (key.equals("Gamma")) gamma = new Double(value);
else if (key.startsWith("Channel ") && key.endsWith("Dye")) {
for (int i=0; i<channelNames.length; i++) {
if (channelNames[i] == null) {
channelNames[i] = value;
break;
}
}
else if (key.startsWith("Confocal Aperture-Ch")) {
for (int i=0; i<lensNA.length; i++) {
if (lensNA[i] == null) {
lensNA[i] = value.substring(0, value.length() - 2);
break;
}
}
else if (key.startsWith("Confocal Aperture-Ch")) {
for (int i=0; i<lensNA.length; i++) {
if (lensNA[i] == null) {
lensNA[i] = value.substring(0, value.length() - 2);
break;
}
}
}
else if (key.equals("Date")) {
date = value;
}
else if (key.equals("Time")) {
date += " " + value;
}
}
}
if (date != null) {
date = DateTools.formatDate(date.trim(),
new String[] {"MM/dd/yyyy hh:mm:ss a", "MM-dd-yyyy hh:mm:ss"}, true);
if (timeIndex >= 0 && date != null) {
long ms = DateTools.getTime(date, DateTools.ISO8601_FORMAT);
int nChars = String.valueOf(getImageCount()).length();
for (int i=0; i<getImageCount(); i++) {
int[] zct = getZCTCoords(i);
String key = String.format(
"Timestamp for Z=%2s, C=%2s, T=%2s", zct[0], zct[1], zct[2]);
long stamp = ms + stamps[timeIndex][i];
addGlobalMeta(key,
DateTools.convertDate(stamp, DateTools.UNIX, DATE_FORMAT));
}
}
}

start = comment.indexOf("[Version Info]");
end = comment.indexOf("[Version Info End]");
int start = comment.indexOf("[Version Info]");
int end = comment.indexOf("[Version Info End]");
if (start != -1 && end != -1 && end > start) {
comment = comment.substring(start + 14, end).trim();
start = comment.indexOf("=") + 1;
Expand All @@ -412,14 +439,26 @@ protected void initMetadataStore() throws FormatException {
super.initMetadataStore();
MetadataStore store =
new FilterMetadata(getMetadataStore(), isMetadataFiltered());
MetadataTools.populatePixels(store, this, true);

store.setImageDescription(comment, 0);
if (date != null) {
store.setImageCreationDate(date, 0);
}

// link Instrument and Image
String instrumentID = MetadataTools.createLSID("Instrument", 0);
store.setInstrumentID(instrumentID, 0);
store.setImageInstrumentRef(instrumentID, 0);

// populate timing data
if (timeIndex >= 0) {
for (int i=0; i<getImageCount(); i++) {
store.setPlaneTimingDeltaT(
new Double(stamps[timeIndex][i] / 1000.0), 0, 0, i);
}
}

// populate Dimensions
store.setDimensionsPhysicalSizeX(new Double(voxelX), 0, 0);
store.setDimensionsPhysicalSizeY(new Double(voxelY), 0, 0);
Expand Down
42 changes: 38 additions & 4 deletions components/common/src/loci/common/DateTools.java
Expand Up @@ -73,8 +73,14 @@ public static long getMillisFromTicks(long hi, long lo) {
return ticks / 10000; // 100 ns = 0.0001 ms
}

/** Converts the given timestamp into an ISO 8601 date. */
/** Converts the given timestamp into an ISO8601 date. */
public static String convertDate(long stamp, int format) {
return convertDate(stamp, format, ISO8601_FORMAT);
}

/** Converts the given timestamp into a date string with the given format. */
public static String convertDate(long stamp, int format, String outputFormat)
{
// see http://www.merlyn.demon.co.uk/critdate.htm for more information on
// dates than you will ever need (or want)

Expand All @@ -95,7 +101,7 @@ public static String convertDate(long stamp, int format) {
break;
}

SimpleDateFormat fmt = new SimpleDateFormat(ISO8601_FORMAT);
SimpleDateFormat fmt = new SimpleDateFormat(outputFormat);
StringBuffer sb = new StringBuffer();

Date d = new Date(ms);
Expand All @@ -106,14 +112,27 @@ public static String convertDate(long stamp, int format) {

/**
* Formats the given date as an ISO 8601 date.
* Delegates to {@link formatDate(String, String, boolean)}, with the
* 'lenient' flag set to false.
*
* @param date The date to format as ISO 8601.
* @param format The date's input format.
*/
public static String formatDate(String date, String format) {
return formatDate(date, format, false);
}

/**
* Formats the given date as an ISO 8601 date.
*
* @param date The date to format as ISO 8601.
* @param form The date's input format.
* @param lenient Whether or not to leniently parse the date.
*/
public static String formatDate(String date, String format, boolean lenient) {
if (date == null) return null;
SimpleDateFormat sdf = new SimpleDateFormat(format);
sdf.setLenient(false);
sdf.setLenient(lenient);
Date d = sdf.parse(date, new ParsePosition(0));
if (d == null) return null;
sdf = new SimpleDateFormat(ISO8601_FORMAT);
Expand All @@ -122,13 +141,28 @@ public static String formatDate(String date, String format) {

/**
* Formats the given date as an ISO 8601 date.
* Delegates to {@link formatDates(String, String[], boolean)}, with the
* 'lenient' flag set to false.
*
* @param date The date to format as ISO 8601.
* @param formats The date's possible input formats.
*/
public static String formatDate(String date, String[] formats) {
return formatDate(date, formats, false);
}

/**
* Formats the given date as an ISO 8601 date.
*
* @param date The date to format as ISO 8601.
* @param formats The date's possible input formats.
* @param lenient Whether or not to leniently parse the date.
*/
public static String formatDate(String date, String[] formats,
boolean lenient)
{
for (int i=0; i<formats.length; i++) {
String result = formatDate(date, formats[i]);
String result = formatDate(date, formats[i], lenient);
if (result != null) return result;
}
return null;
Expand Down

0 comments on commit 4aa1f75

Please sign in to comment.