diff --git a/pom.xml b/pom.xml
index 702588d..c93bf77 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,4 +13,21 @@
provided
+
+
+
+
+ maven-assembly-plugin
+ 2.4
+
+ HDF5_Viewer-${pom.version}
+ false
+
+
+ jar-with-dependencies
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/ch/psi/imagej/hdf5/HDF5_Batch_.java b/src/main/java/ch/psi/imagej/hdf5/HDF5_Batch_.java
deleted file mode 100644
index 513744c..0000000
--- a/src/main/java/ch/psi/imagej/hdf5/HDF5_Batch_.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package ch.psi.imagej.hdf5;
-/* =========================================================================
- *
- * Copyright 2011 Matthias Schlachter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *=========================================================================*/
-
-public class HDF5_Batch_
-{
- public static void run(String arg)
- {
- parseArgs(arg);
- System.out.println("filename");
- System.out.println(_filename);
- System.out.println("varnames");
- for(int i=0; i<_varnames.length; i++)
- System.out.println(_varnames[i]);
- HDF5_Writer_ w = new HDF5_Writer_();
- w.setToBatchMode(_filename,_varnames);
- w.run(null);
- }
-
-
- private static void parseArgs(String arg)
- {
- String[] result = arg.split("]\\s");
- _filename = result[0].replaceAll("file=\\[","");
- String[] splitVars = result[1].split("\\s");
- _varnames = new String[splitVars.length];
- for (int x=0; x -1)
- return frameList.get(i);
- else
- return null;
- }
+public class HDF5_GroupedVarnames {
+
+ private final List matchedVarNames = new ArrayList();
+ private final List unMatchedVarNames = new ArrayList();
+ private final List frameList = new ArrayList();
+ private String[] formatTokens = null;
+ private String formatString = null;
+ private int minFrameIndex = -1;
+ private int maxFrameIndex = -1;
+ private int minChannelIndex = -1;
+ private int maxChannelIndex = -1;
+ private int nChannels = -1;
+
+ public static String[] parseFormatString(String groupVarsByNameFormat, String dollarRegexpForGrouping) throws PatternSyntaxException {
+ String[] formatTokens = null;
+ formatTokens = groupVarsByNameFormat.split("([$]T|[$]C)");
+ boolean containsFormatVars = groupVarsByNameFormat.contains("$T") && groupVarsByNameFormat.contains("$C");
+ boolean rightOrderOfFormatVars = groupVarsByNameFormat.indexOf("$T") < groupVarsByNameFormat.indexOf("$C");
- private void splitGroupedVarnames()
- {
- Iterator vars = matchedVarNames.iterator();
- while(vars.hasNext())
- {
- String varName = vars.next();
- String[] tokens = null;
- if(formatTokens.length == 2)
- {
- tokens = varName.split(formatTokens[1]);
- }
- else if(formatTokens.length == 3)
- {
- tokens = varName.split(formatTokens[2]);
- varName = tokens[0];
- tokens = varName.split(formatTokens[1]);
- }
-
- if(tokens.length < 2 || tokens.length > 3)
- {
- System.out.println("Error parsing varname!");
- }
- else
- {
- Integer channelIndex = new Integer(tokens[1]);
- System.out.println("channelIndex: " + channelIndex.toString());
- System.out.println("left token: " + tokens[0]);
- tokens = tokens[0].split("/t");
- Integer frameIndex = new Integer(tokens[1]);
- System.out.println("frameIndex: " + frameIndex.toString());
+ for (int i = 0; i < formatTokens.length; i++) {
+ System.out.println("tok " + Integer.toString(i) + " : " + formatTokens[i]);
+ }
+ if (formatTokens.length < 2 || !containsFormatVars || !rightOrderOfFormatVars) {
+ throw new PatternSyntaxException("Your format string has errors. " + "You must provide $T and $C and " + "also in correct order!", groupVarsByNameFormat, -1);
+ }
+ String regexp = groupVarsByNameFormat;
+ regexp = regexp.replace("$T", dollarRegexpForGrouping);
+ regexp = regexp.replace("$C", dollarRegexpForGrouping);
+ System.out.println(regexp);
+ // check if we have a regexp;
+ Pattern.compile(regexp);
+ return formatTokens;
+ }
- if(minFrameIndex == -1)
- minFrameIndex = frameIndex.intValue();
- minFrameIndex = Math.min(minFrameIndex,frameIndex.intValue());
+ public void parseVarNames(String[] varNames, String groupVarsByNameFormat, String dollarRegexpForGrouping) {
+ // save format string
+ formatString = groupVarsByNameFormat;
+ try {
+ formatTokens = parseFormatString(groupVarsByNameFormat, dollarRegexpForGrouping);
+ } catch (PatternSyntaxException e) {
+ // produce an error dialog an start over
+ String errMsg = e.getMessage();
+ System.out.println(errMsg);
+ return;
+ }
+ String regexp = groupVarsByNameFormat;
+ regexp = regexp.replace("$T", dollarRegexpForGrouping);
+ regexp = regexp.replace("$C", dollarRegexpForGrouping);
- if(maxFrameIndex == -1)
- maxFrameIndex = frameIndex.intValue();
- maxFrameIndex = Math.max(maxFrameIndex,frameIndex.intValue());
-
- if(minChannelIndex == -1)
- minChannelIndex = channelIndex.intValue();
- minChannelIndex = Math.min(minChannelIndex,channelIndex.intValue());
+ System.out.println(regexp);
+ // check if we have a regexp;
+ Pattern p = null;
+ p = Pattern.compile(regexp);
+ /*---------------------------------------------------------------------
+ * parse var names
+ *---------------------------------------------------------------------*/
+ for (int i = 0; i < varNames.length; i++) {
+ Matcher m = p.matcher(varNames[i]);
+ boolean b = m.matches();
+ if (b) {
+ System.out.println(varNames[i]);
+ matchedVarNames.add(varNames[i]);
+ } else {
+ unMatchedVarNames.add(varNames[i]);
+ }
+ }
+ splitGroupedVarnames();
+ // ugly hack for sorting ArrayList
+ Object[] frameListAsArray = frameList.toArray();
+ Arrays.sort(frameListAsArray);
+ for (int i = 0; i < frameListAsArray.length; i++)
+ frameList.set(i, (TimeFrame) frameListAsArray[i]);
+ }
- if(maxChannelIndex == -1)
- maxChannelIndex = channelIndex.intValue();
- maxChannelIndex = Math.max(maxChannelIndex,channelIndex.intValue());
+ public TimeFrame getFrame(int i) {
+ if (i < frameList.size() && i > -1)
+ return frameList.get(i);
+ else
+ return null;
+ }
- TimeFrame frame = new TimeFrame(frameIndex.intValue());
- int idx = frameList.indexOf(frame);
- if(idx != -1)
- {
- frame = (TimeFrame) frameList.get(idx);
- frame.addChannel(channelIndex.intValue());
- }
- else
- {
- frame.addChannel(channelIndex.intValue());
- frameList.add(frame);
- }
- //System.out.println(frame.toString());
- }
- }
- }
+ private void splitGroupedVarnames() {
+ Iterator vars = matchedVarNames.iterator();
+ while (vars.hasNext()) {
+ String varName = vars.next();
+ String[] tokens = null;
+ if (formatTokens.length == 2) {
+ tokens = varName.split(formatTokens[1]);
+ } else if (formatTokens.length == 3) {
+ tokens = varName.split(formatTokens[2]);
+ varName = tokens[0];
+ tokens = varName.split(formatTokens[1]);
+ }
- public int getMinFrameIndex()
- {
- return minFrameIndex;
- }
- public int getMaxFrameIndex()
- {
- return maxFrameIndex;
- }
- public int getMinChannelIndex()
- {
- return minChannelIndex;
- }
- public int getMaxChannelIndex()
- {
- return maxChannelIndex;
- }
- public int getNFrames()
- {
- return frameList.size();
- }
- public int getNChannels()
- {
- // TODO: check all frames for min/max of channels not index
- if(nChannels == -1)
- return maxChannelIndex-minChannelIndex+1;
- else
- return nChannels;
- }
- public boolean hasAllFramesInRange()
- {
- return frameList.size() == (maxFrameIndex-minFrameIndex+1);
- }
- public String toString()
- {
- String s = "Data set statistics\n";
- s = s + "----------------------------------\n";
- s = s + "nFrames: " + Integer.toString(frameList.size()) + "\n";
- s = s + "minFrameIndex: " + Integer.toString(minFrameIndex) + "\n";
- s = s + "maxFrameIndex: " + Integer.toString(maxFrameIndex) + "\n";
- s = s
- + "hasAllFramesInRange: "
- + Boolean.toString(hasAllFramesInRange()) + "\n";
- s = s + "minChannelIndex: " + Integer.toString(minChannelIndex) + "\n";
- s = s + "maxChannelIndex: " + Integer.toString(maxChannelIndex) + "\n";
+ if (tokens.length < 2 || tokens.length > 3) {
+ System.out.println("Error parsing varname!");
+ } else {
+ Integer channelIndex = new Integer(tokens[1]);
+ System.out.println("channelIndex: " + channelIndex.toString());
+ System.out.println("left token: " + tokens[0]);
+ tokens = tokens[0].split("/t");
+ Integer frameIndex = new Integer(tokens[1]);
+ System.out.println("frameIndex: " + frameIndex.toString());
- // String[] toks = getFormatTokens();
- Iterator frames = frameList.iterator();
- while(frames.hasNext())
- {
- TimeFrame f = frames.next();
- s = s + f.toString() + "\n";
- // s = s + "(" + toks[0] +
- // Integer.toString(f.getFrameIndex())
- // + toks[1] + "$C";
- // if(toks.length>2)
- // s = s + toks[2] + "\n";
- // else
- // s = s + "\n";
- }
- s = s + "----------------------------------";
- return s;
- }
+ if (minFrameIndex == -1)
+ minFrameIndex = frameIndex.intValue();
+ minFrameIndex = Math.min(minFrameIndex, frameIndex.intValue());
- public List getUnmatchedVarNames()
- {
- return unMatchedVarNames;
- }
-
- public String[] getFormatTokens()
- {
- return formatTokens;
- }
+ if (maxFrameIndex == -1)
+ maxFrameIndex = frameIndex.intValue();
+ maxFrameIndex = Math.max(maxFrameIndex, frameIndex.intValue());
- public String getFormatString()
- {
- return formatString;
- }
+ if (minChannelIndex == -1)
+ minChannelIndex = channelIndex.intValue();
+ minChannelIndex = Math.min(minChannelIndex, channelIndex.intValue());
- public void setFrameAndChannelRange(int minFrame,
- int skipFrame,
- int maxFrame,
- int minChannel,
- int skipChannel,
- int maxChannel)
- {
- System.out.println("Setting frame range: " +
- Integer.toString(minFrame) + ":" +
- Integer.toString(skipFrame) + ":" +
- Integer.toString(maxFrame));
- System.out.println("Setting channel range: " +
- Integer.toString(minChannel) + ":" +
- Integer.toString(skipChannel) + ":" +
- Integer.toString(maxChannel));
- if(hasAllFramesInRange())
- {
- // copy frames
- List completeFrameList = new ArrayList(frameList);
- // clear frames
- frameList.clear();
- // insert wanted frames and channels
- for(int f=minFrame;f completeFrameList = new ArrayList(frameList);
- // clear frames
- frameList.clear();
- // insert wanted frames and channels
- for(int f=minFrame;f matchedVarNames = new ArrayList();
- private final List unMatchedVarNames = new ArrayList();
- private final List frameList = new ArrayList();
- private String[] formatTokens = null;
- private String formatString = null;
- private int minFrameIndex = -1;
- private int maxFrameIndex = -1;
- private int minChannelIndex = -1;
- private int maxChannelIndex = -1;
- private int nChannels = -1;
+ TimeFrame frame = new TimeFrame(frameIndex.intValue());
+ int idx = frameList.indexOf(frame);
+ if (idx != -1) {
+ frame = (TimeFrame) frameList.get(idx);
+ frame.addChannel(channelIndex.intValue());
+ } else {
+ frame.addChannel(channelIndex.intValue());
+ frameList.add(frame);
+ }
+ // System.out.println(frame.toString());
+ }
+ }
+ }
+
+ public int getMinFrameIndex() {
+ return minFrameIndex;
+ }
+
+ public int getMaxFrameIndex() {
+ return maxFrameIndex;
+ }
+
+ public int getMinChannelIndex() {
+ return minChannelIndex;
+ }
+
+ public int getMaxChannelIndex() {
+ return maxChannelIndex;
+ }
+
+ public int getNFrames() {
+ return frameList.size();
+ }
+
+ public int getNChannels() {
+ // TODO: check all frames for min/max of channels not index
+ if (nChannels == -1)
+ return maxChannelIndex - minChannelIndex + 1;
+ else
+ return nChannels;
+ }
+
+ public boolean hasAllFramesInRange() {
+ return frameList.size() == (maxFrameIndex - minFrameIndex + 1);
+ }
+
+ public String toString() {
+ String s = "Data set statistics\n";
+ s = s + "----------------------------------\n";
+ s = s + "nFrames: " + Integer.toString(frameList.size()) + "\n";
+ s = s + "minFrameIndex: " + Integer.toString(minFrameIndex) + "\n";
+ s = s + "maxFrameIndex: " + Integer.toString(maxFrameIndex) + "\n";
+ s = s + "hasAllFramesInRange: " + Boolean.toString(hasAllFramesInRange()) + "\n";
+ s = s + "minChannelIndex: " + Integer.toString(minChannelIndex) + "\n";
+ s = s + "maxChannelIndex: " + Integer.toString(maxChannelIndex) + "\n";
+
+ // String[] toks = getFormatTokens();
+ Iterator frames = frameList.iterator();
+ while (frames.hasNext()) {
+ TimeFrame f = frames.next();
+ s = s + f.toString() + "\n";
+ // s = s + "(" + toks[0] +
+ // Integer.toString(f.getFrameIndex())
+ // + toks[1] + "$C";
+ // if(toks.length>2)
+ // s = s + toks[2] + "\n";
+ // else
+ // s = s + "\n";
+ }
+ s = s + "----------------------------------";
+ return s;
+ }
+
+ public List getUnmatchedVarNames() {
+ return unMatchedVarNames;
+ }
+
+ public String[] getFormatTokens() {
+ return formatTokens;
+ }
+
+ public String getFormatString() {
+ return formatString;
+ }
+
+ public void setFrameAndChannelRange(int minFrame, int skipFrame, int maxFrame, int minChannel, int skipChannel, int maxChannel) {
+ System.out.println("Setting frame range: " + Integer.toString(minFrame) + ":" + Integer.toString(skipFrame) + ":" + Integer.toString(maxFrame));
+ System.out.println("Setting channel range: " + Integer.toString(minChannel) + ":" + Integer.toString(skipChannel) + ":" + Integer.toString(maxChannel));
+ if (hasAllFramesInRange()) {
+ // copy frames
+ List completeFrameList = new ArrayList(frameList);
+ // clear frames
+ frameList.clear();
+ // insert wanted frames and channels
+ for (int f = minFrame; f < maxFrame + 1; f += skipFrame) {
+ TimeFrame frameAllChannels = completeFrameList.get(f);
+ TimeFrame frame = new TimeFrame(frameAllChannels.getFrameIndex());
+ // TODO remove unwanted channels
+ for (int c = minChannel; c < maxChannel + 1; c += skipChannel) {
+ // System.out.println("Adding channels: " +
+ // Integer.toString(c));
+ frame.addChannel(c);
+ }
+ // if(nChannels == -1)
+ // nChannels = frame.getNChannels();
+ frameList.add(frame);
+ }
+ // TODO update min/max of frames/channels
+ nChannels = ((maxChannel - minChannel) / skipChannel) + 1;
+ System.out.println("Adding nChannels: " + Integer.toString(nChannels));
+ } else {
+ System.out.println("-------------------------\n" + "hasAllFramesInRange==false\n" + "-------------------------");
+ // copy frames
+ List completeFrameList = new ArrayList(frameList);
+ // clear frames
+ frameList.clear();
+ // insert wanted frames and channels
+ for (int f = minFrame; f < maxFrame + 1; f += skipFrame) {
+ TimeFrame frame = new TimeFrame(f);
+ int idx = completeFrameList.indexOf(frame);
+ // System.out.println("index of frame in list: " +
+ // Integer.toString(idx));
+ if (idx != -1) {
+ // TODO remove unwanted channels
+ for (int c = minChannel; c < maxChannel + 1; c += skipChannel) {
+ // System.out.println("Adding channels: " +
+ // Integer.toString(c));
+ frame.addChannel(c);
+ }
+ // if(nChannels == -1)
+ // nChannels = frame.getNChannels();
+ frameList.add(frame);
+ } else {
+ System.out.println("Timestep " + Integer.toString(f) + " is missing!");
+ }
+ }
+ // TODO update min/max of frames/channels
+ nChannels = ((maxChannel - minChannel) / skipChannel) + 1;
+ System.out.println("Adding nChannels: " + Integer.toString(nChannels));
+ }
+ }
}
diff --git a/src/main/java/ch/psi/imagej/hdf5/HDF5_Reader_.java b/src/main/java/ch/psi/imagej/hdf5/HDF5_Reader_.java
index 013c4f1..fe85783 100644
--- a/src/main/java/ch/psi/imagej/hdf5/HDF5_Reader_.java
+++ b/src/main/java/ch/psi/imagej/hdf5/HDF5_Reader_.java
@@ -1,22 +1,24 @@
package ch.psi.imagej.hdf5;
-/* =========================================================================
- *
- * Copyright 2011 Matthias Schlachter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *=========================================================================*/
+/*
+ * =========================================================================
+ *
+ * Copyright 2011 Matthias Schlachter
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * =========================================================================
+ */
import ij.IJ;
import ij.Prefs;
@@ -26,7 +28,6 @@ import ij.ImageStack;
import ij.gui.GenericDialog;
import ij.io.OpenDialog;
import ij.plugin.PlugIn;
-import ij.process.ColorProcessor;
import ij.process.ImageProcessor;
import java.io.File;
@@ -40,2709 +41,2021 @@ import ncsa.hdf.object.h5.*; // the HDF5 implementation
import ncsa.hdf.hdf5lib.exceptions.HDF5Exception;
import ncsa.hdf.hdflib.HDFException;
-public class HDF5_Reader_ implements PlugIn
-{
- public void run(String arg)
- {
- // make sure default values for config are written
- // HDF5_Config.setDefaultsIfNoValueExists();
-
- // run plugin
- String directory = "";
- String name = "";
- boolean tryAgain;
- String openMSG = "Open HDF5...";
- do
- {
- tryAgain = false;
- OpenDialog od;
- if (directory.equals(""))
- od = new OpenDialog(openMSG, arg);
- else
- od = new OpenDialog(openMSG, directory, arg);
-
- directory = od.getDirectory();
- name = od.getFileName();
- if (name == null)
- return;
- if (name == "")
- return;
-
- File testFile = new File(directory + name);
- if (!testFile.exists() || !testFile.canRead())
- return;
-
- if (testFile.isDirectory())
- {
- directory = directory + name;
- tryAgain = true;
- }
- } while (tryAgain);
-
- IJ.showStatus("Loading HDF5 File: " + directory + name);
-
- H5File inFile = null;
-
-
- // define grouping class
- HDF5_GroupedVarnames groupedVarnames = new HDF5_GroupedVarnames();
- boolean loadGroupedVarNames = true;
-
- try
- {
- inFile = new H5File(directory + name, H5File.READ);
- inFile.open();
-
- /*-------------------------------------------------------------------
- * read HDF5_Config prefs
- *-------------------------------------------------------------------*/
- boolean groupVarsByName =
- Boolean.getBoolean(HDF5_Config.
- getDefaultValue("HDF5.groupVarsByName"));
- groupVarsByName = Prefs.get("HDF5.groupVarsByName", groupVarsByName);
-
- boolean showUnmatchedDataSetNames =
- Boolean.getBoolean(HDF5_Config.
- getDefaultValue("HDF5.showUnmatchedDataSetNames"));
- showUnmatchedDataSetNames = Prefs.get("HDF5.showUnmatchedDataSetNames",
- showUnmatchedDataSetNames);
-
- String groupVarsByNameFormatGroup =
- HDF5_Config.getDefaultValue("HDF5.groupVarsByNameFormatGroup");
- groupVarsByNameFormatGroup
- = Prefs.get("HDF5.groupVarsByNameFormatGroup",
- groupVarsByNameFormatGroup);
-
- // TODO: try to read attribute containing format String
- String groupVarsByNameFormat = null;
- try
- {
- HObject gr = inFile.get(groupVarsByNameFormatGroup);
- String attrName = ""; // this will throw an error
-
- if(gr != null)
- {
- // get the attr list and make a selection dialog if necessary
- List hintsAttrList = getAttrList(gr);
- if(hintsAttrList.size() == 1)
- attrName = hintsAttrList.get(0).getName();
- else if(hintsAttrList.size() > 1)
- {
- String[] hintsAttrNames = new String[hintsAttrList.size()];
- for(int a=0;a varList = getDataSetList(rootNode,
- new ArrayList());
-
- GenericDialog gd = new GenericDialog("Variable Name Selection");
- gd.addMessage("Please select variables to be loaded.\n");
-
- if (varList.size() < 1)
- {
- IJ.error("The file did not contain variables. (broken?)");
- inFile.close();
- return;
- }
- // else if (varList.size() < 2)
- // {
- // gd.addCheckbox("single variable", true);
- // }
- else if(groupVarsByName)
- {
- // parse file structure
- String[] varNames = new String[varList.size()];
- for (int i = 0; i < varList.size(); i++)
- {
- varNames[i] = varList.get(i).getFullName();
- }
- groupedVarnames.parseVarNames(varNames,
- groupVarsByNameFormat,
- dollarRegexpForGrouping);
- System.out.println(groupedVarnames.toString());
-
- // make the data set selection dialog
- minFrameIndex = groupedVarnames.getMinFrameIndex();
- maxFrameIndex = groupedVarnames.getMaxFrameIndex();
- minChannelIndex = groupedVarnames.getMinChannelIndex();
- maxChannelIndex = groupedVarnames.getMaxChannelIndex();
-
-
- gd = new GenericDialog("Variable Name Selection");
- // check if we have matched var names
- if(groupedVarnames.getNFrames()>0)
- {
- gd.addCheckbox("Load grouped data sets",
- loadGroupedVarNames);
-
- gd.addMessage("Select frames and channels you want to read");
- gd.addMessage("Frame selection (start/step/end): ");
-
- gd.addStringField("Frame selection (start:[step:]end): ",
- Integer.toString(minFrameIndex) + ":" +
- Integer.toString(skipFrameIndex) + ":" +
- Integer.toString(maxFrameIndex));
-
- gd.addStringField("Channel selection (start:[step:]end): ",
- Integer.toString(minChannelIndex) + ":" +
- Integer.toString(skipChannelIndex) + ":" +
- Integer.toString(maxChannelIndex));
- }
-
- // get unmatched names
- List unmatchedVarNames
- = groupedVarnames.getUnmatchedVarNames();
- if(showUnmatchedDataSetNames)
- {
- // add all unmatched data set names to the dialog
- String[] varSelections = new String[unmatchedVarNames.size()];
- boolean[] defaultValues = new boolean[unmatchedVarNames.size()];
- for (int i = 0; i < unmatchedVarNames.size(); i++)
- {
- Dataset var = (Dataset) inFile.get(unmatchedVarNames.get(i));
- int rank = var.getRank();
- String title = rank + "D: " + var.getFullName() + " "
- + var.getDatatype().getDatatypeDescription() + "( ";
- long[] extent = var.getDims();
- for (int d = 0; d < rank; ++d)
- {
- if (d != 0)
- title += "x";
- title += extent[d];
- }
- title += ")";
- varSelections[i] = title;
- defaultValues[i] = false;
- }
- System.out.println("addcheckboxgroup with "
- + unmatchedVarNames.size() + " rows");
- gd.addCheckboxGroup(unmatchedVarNames.size(), 1,
- varSelections, defaultValues);
- addScrollBars(gd);
- }
- gd.showDialog();
- if (gd.wasCanceled())
- {
- return;
- }
-
- // load grouped var names ?
- if(groupedVarnames.getNFrames()>0)
- loadGroupedVarNames = gd.getNextBoolean();
-
- // read range selections if we have matched varnames
- String frameRange = null;
- String channelRange = null;
- if(groupedVarnames.getNFrames()>0)
- {
- frameRange = gd.getNextString();
- channelRange = gd.getNextString();
- }
- // parse the range selection
- String[] frameRangeToks = null;
- String[] channelRangeToks = null;
- boolean wrongFrameRange = true;
- boolean wrongChannelRange = true;
- // check if the parsed values are in range
- if(groupedVarnames.getNFrames()>0 && loadGroupedVarNames)
- while(wrongFrameRange || wrongChannelRange)
- {
- // check frame range
- frameRangeToks = frameRange.split(":");
- if(frameRangeToks.length == 1)
- {
- // single frame
- try
- {
- System.out.println("single frame");
- minFrameIndex = Integer.parseInt(frameRangeToks[0]);
- maxFrameIndex = minFrameIndex;
- wrongFrameRange = false;
- }
- catch(Exception e)
- {
- wrongFrameRange = true;
- }
- }
- else if(frameRangeToks.length == 2)
- {
- // frame range with skipFrameIndex=1
- try
- {
- System.out.println("frame range with skipFrameIndex=1");
- minFrameIndex = Integer.parseInt(frameRangeToks[0]);
- maxFrameIndex = Integer.parseInt(frameRangeToks[1]);
- wrongFrameRange = false;
- }
- catch(Exception e)
- {
- wrongFrameRange = true;
- }
- }
- else if(frameRangeToks.length == 3)
- {
- // frame range with skipFrameIndex
- try
- {
- System.out.println("frame range with skipFrameIndex");
- minFrameIndex = Integer.parseInt(frameRangeToks[0]);
- skipFrameIndex = Integer.parseInt(frameRangeToks[1]);
- maxFrameIndex = Integer.parseInt(frameRangeToks[2]);
- wrongFrameRange = false;
- }
- catch(Exception e)
- {
- wrongFrameRange = true;
- }
- }
- else
- {
- // wrong format
- System.out.println("wrong format");
- wrongFrameRange = true;
- }
-
- // check channel range
- channelRangeToks = channelRange.split(":");
- if(channelRangeToks.length == 1)
- {
- // single channel
- try
- {
- minChannelIndex = Integer.parseInt(channelRangeToks[0]);
- maxChannelIndex = minChannelIndex;
- wrongChannelRange = false;
- }
- catch(Exception e)
- {
- wrongChannelRange = true;
- }
- }
- else if(channelRangeToks.length == 2)
- {
- // channel range with skipChannelIndex=1
- try
- {
- minChannelIndex = Integer.parseInt(channelRangeToks[0]);
- maxChannelIndex = Integer.parseInt(channelRangeToks[1]);
- wrongChannelRange = false;
- }
- catch(Exception e)
- {
- wrongChannelRange = true;
- }
- }
- else if(channelRangeToks.length == 3)
- {
- // channel range with skipChannelIndex
- try
- {
- minChannelIndex = Integer.parseInt(channelRangeToks[0]);
- skipChannelIndex = Integer.parseInt(channelRangeToks[1]);
- maxChannelIndex = Integer.parseInt(channelRangeToks[2]);
- wrongChannelRange = false;
- }
- catch(Exception e)
- {
- wrongChannelRange = true;
- }
- }
- else
- {
- // wrong format
- wrongChannelRange = true;
- }
- if(wrongFrameRange || wrongChannelRange)
- {
- // show dialog again
- System.out.println("show dialog again");
- // TODO reset dialog when possible
- gd = new GenericDialog("Range Selection");
- gd.addMessage("Select frames and channels you want to read");
- gd.addMessage("Frame selection (start/step/end): ");
-
- gd.addStringField("Frame selection (start:[step:]end): ",
- Integer.toString(minFrameIndex) + ":" +
- Integer.toString(skipFrameIndex) + ":" +
- Integer.toString(maxFrameIndex));
-
- gd.addStringField("Channel selection (start:[step:]end): ",
- Integer.toString(minChannelIndex) + ":" +
- Integer.toString(skipChannelIndex) + ":" +
- Integer.toString(maxChannelIndex));
- gd.showDialog();
- System.out.println("read ranges again");
- frameRange = gd.getNextString();
- channelRange = gd.getNextString();
-
- }
- if (gd.wasCanceled())
- {
- return;
- }
- // the parameters for the range have correct format
- }
-
- if(showUnmatchedDataSetNames)
- {
- varList = new ArrayList();
- // fill varList with unmatched var names
- for (int i = 0; i < unmatchedVarNames.size(); i++)
- {
- String dsName = unmatchedVarNames.get(i);
- try
- {
- HObject ds = inFile.get(dsName);
- if(ds != null && ds instanceof Dataset)
- {
- varList.add((Dataset) ds);
- }
- }
- catch(Exception e)
- {
- System.out.println("The file does not contain a variable " +
- "with name " + "`" + dsName + "`!");
- }
- }
- }
- else
- {
- // set varList=empty if we dont want unmatched var names
- varList = new ArrayList();
- }
-
- }
- else if(varList.size() > 1000)
- {
- /*-----------------------------------------------------------------
- * FIXME: quick an dirty hack for files with more than 1000
- * datasets
- *-----------------------------------------------------------------*/
- gd = new GenericDialog("Variable Name Selection");
- gd.addMessage("Too many variables in your file! "
- + "(More than 1000)\n\n"
- + "Please enter the full name of your desired dataset.");
- gd.addStringField("dataset name", "");
- gd.showDialog();
-
- if (gd.wasCanceled())
- {
- return;
- }
-
- String dsName = gd.getNextString();
- varList = new ArrayList();
- try
- {
- HObject ds = inFile.get(dsName);
- if(ds != null && ds instanceof Dataset)
- {
- varList.add((Dataset) ds);
- gd.addCheckbox("single variable", true);
- }
- else
- {
- IJ.error("The file does not contain a variable with name "
- + "`" + dsName + "`!");
- inFile.close();
- return;
- }
- }
- catch(Exception e)
- {
- IJ.error("The file does not contain a variable with name "
- + "`" + dsName + "`!");
- inFile.close();
- return;
- }
- }
- else
- {
- String[] varSelections = new String[varList.size()];
- boolean[] defaultValues = new boolean[varList.size()];
- for (int i = 0; i < varList.size(); i++)
- {
- Dataset var = varList.get(i);
- int rank = var.getRank();
- String title = rank + "D: " + var.getFullName() + " "
- + var.getDatatype().getDatatypeDescription() + "( ";
- long[] extent = var.getDims();
- for (int d = 0; d < rank; ++d)
- {
- if (d != 0)
- title += "x";
- title += extent[d];
- }
- title += ")";
- varSelections[i] = title;
- defaultValues[i] = false;
- }
- System.out.println("addcheckboxgroup with "
- + varList.size() + " rows");
- gd.addCheckboxGroup(varList.size(), 1,
- varSelections, defaultValues);
- addScrollBars(gd);
- gd.showDialog();
-
- if (gd.wasCanceled())
- {
- return;
- }
- }
- /*-------------------------------------------------------------------
- * now reading data sets
- *-------------------------------------------------------------------*/
- if(groupVarsByName &&
- groupedVarnames.getNFrames()>0 &&
- loadGroupedVarNames)
- {
- groupedVarnames.setFrameAndChannelRange(minFrameIndex,
- skipFrameIndex,
- maxFrameIndex,
- minChannelIndex,
- skipChannelIndex,
- maxChannelIndex);
- // TODO implement hyperstack reading
- int nFrames = groupedVarnames.getNFrames();
- int nChannels = groupedVarnames.getNChannels();
-
- // get extents of first data set
- long[] extent = null;
- int rank = -1;
- double[] elem_sizes = new double[3];
- String dsName = "";
- String[] formatTokens = groupedVarnames.getFormatTokens();
- Dataset var = null;
- boolean isSigned16Bit = false;
- int unsignedConvSelec = 0; // cut off values
- try
- {
- TimeFrame f = groupedVarnames.getFrame(0);
- if(f == null)
- System.out.println("frame is null");
- if(formatTokens.length == 2)
- dsName = formatTokens[0]
- + Integer.toString(f.getFrameIndex())
- + formatTokens[1]
- + Integer.toString(f.getChannelIndices()[0]);
- else if(formatTokens.length == 3)
- dsName = formatTokens[0]
- + Integer.toString(f.getFrameIndex())
- + formatTokens[1]
- + Integer.toString(f.getChannelIndices()[0])
- + formatTokens[2];
- System.out.println("VarName: " + dsName);
- HObject ds = inFile.get(dsName);
- if(ds != null && ds instanceof Dataset)
- {
- var = (Dataset) ds;
- Datatype dType = var.getDatatype();
- isSigned16Bit = !dType.isUnsigned() &&
- (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) &&
- (dType.getDatatypeSize() == 2);
- if(isSigned16Bit)
- {
- GenericDialog convDiag
- = new GenericDialog("Unsigned to signed conversion");
- convDiag.addMessage("Detected unsigned datatype, which "+
- "is not supported.");
- String[] convOptions = new String[2];
- convOptions[0] = "cut off values";
- convOptions[1] = "convert to float";
- convDiag.addChoice("Please select an conversion option:",
- convOptions,
- convOptions[0]);
- convDiag.showDialog();
- if(convDiag.wasCanceled())
- return;
- unsignedConvSelec = convDiag.getNextChoiceIndex();
- }
- // TODO check for unsupported datatypes int,long
- rank = var.getRank();
- extent = var.getDims();
- Attribute elemsize_att = getAttribute(var, "element_size_um");
-
- if (elemsize_att == null)
- {
- elem_sizes[0] = 1.0;
- elem_sizes[1] = 1.0;
- elem_sizes[2] = 1.0;
- }
- else
- {
- System.out.println("Reading element_size_um");
- float[] tmp = null;
- try
- {
- tmp = ((float[]) elemsize_att.getValue());
- elem_sizes[0] = tmp[0];
- elem_sizes[1] = tmp[1];
- elem_sizes[2] = tmp[2];
- }
- catch(java.lang.ClassCastException e)
- {
- String title = "Error Reading Element Size";
- String msg = "The element_size_um attribute "
- + "has wrong format!\n";
- msg += "Setting to default size of (1,1,1)...";
- ij.gui.MessageDialog errMsg = new ij.gui.MessageDialog(null,
- title,
- msg);
- elem_sizes[0] = 1;
- elem_sizes[1] = 1;
- elem_sizes[2] = 1;
- }
- }
- }
- else
- {
- IJ.error("The file does not contain a variable with name "
- + "`" + dsName + "`!");
- inFile.close();
- return;
- }
- }
- catch(Exception e)
- {
- IJ.error("The file does not contain a variable with name "
- + "`" + dsName + "`!");
- inFile.close();
- return;
- }
- // String title = rank + "D: " + var.getFullName() + " "
- // + var.getDatatype().getDatatypeDescription() + "( ";
-
- // read 3D or 2D dataset
- if(rank == 3 || rank == 2)
- {
- int nRows = -1; // height
- int nCols = -1; // width
- int nSlices = 1; // if rank == 2
- if(rank == 3)
- {
- nSlices = (int) extent[0];
- nRows = (int) extent[1];
- nCols = (int) extent[2];
- }
- else
- {
- nRows = (int) extent[0];
- nCols = (int) extent[1];
- }
-
-
- // create a new image stack and fill in the data
- ImageStack stack = new ImageStack(nCols,
- nRows,
- nFrames*nSlices*nChannels);
- System.out.println("stackSize: "
- + Integer.toString(stack.getSize()));
-
- ImagePlus imp = new ImagePlus();
- // to get getFrameIndex() working
- imp.setDimensions(nChannels,nSlices,nFrames);
-
- long stackSize = nCols*nRows;
- // global min max values of all data sets
- double[] minValChannel = new double[nChannels];
- double[] maxValChannel = new double[nChannels];
-
- // TODO implement frame and channel ranges
- // now read frame by frame
- for(int fIdx=0; fIdx2)
- selected[2] = extent[2];
-
- Object wholeDataset = var.read();
- if(isSigned16Bit)
- wholeDataset = convertToUnsigned(wholeDataset,
- unsignedConvSelec);
-
- long wholeDatasetSize = 1;
- for(int d=0;d1)
- {
- System.out.println("Creating composite hyperstack with " +
- Integer.toString(nChannels) +
- " channels.");
- imp = new CompositeImage(imp, CompositeImage.COMPOSITE);
- }
- else
- {
- System.out.println("Creating grayscale hyperstack.");
- //imp = new CompositeImage(imp, CompositeImage.GRAYSCALE);
- }
-
-
- System.out.println("nFrames: " + Integer.toString(nFrames));
- System.out.println("nSlices: " + Integer.toString(nSlices));
-
- System.out.println("stackSize: "
- + Integer.toString(stack.getSize()));
-
- // set element_size_um
- imp.getCalibration().pixelDepth = elem_sizes[0];
- imp.getCalibration().pixelHeight = elem_sizes[1];
- imp.getCalibration().pixelWidth = elem_sizes[2];
-
-
- // System.out.println(" Min = " + minMaxVal[0] +
- // ", Max = " + minMaxVal[1]);
- //imp.setDisplayRange(1.5*minMaxVal[0], 0.5*minMaxVal[1]);
- //imp.resetDisplayRange();
- int[] channelsIJ = {4,2,1};
- for(int c=0;c
- getDataSetList(Group g, List datasets) throws Exception
- {
- if (g == null)
- return datasets;
-
- List members = g.getMemberList();
- int n = members.size();
- HObject obj = null;
- for (int i = 0; i < n; i++)
- {
- obj = (HObject) members.get(i);
- if (obj instanceof Dataset)
- {
- ((Dataset) obj).init();
- datasets.add((Dataset) obj);
- //System.out.println(obj.getFullName());
- }
- else if (obj instanceof Group)
- {
- datasets = (getDataSetList((Group) obj, datasets));
- }
- }
- return datasets;
- }
-
- private static List getAttrList(HObject ds) throws Exception
- {
- if (ds == null)
- return null;
-
- List attributes = new ArrayList();
- List members = ds.getMetadata();
- int n = members.size();
- Metadata obj = null;
- for (int i = 0; i < n; i++)
- {
- obj = (Metadata) members.get(i);
- if (obj instanceof Attribute)
- {
- try
- {
- System.out.println(((Attribute) obj).getName());
- attributes.add((Attribute) obj);
- }
- catch (java.lang.UnsupportedOperationException e)
- {
- System.out
- .println("Caught UnsupportedOperationException datasets2.add((Dataset) obj)");
- System.out.println(e.getMessage());
- }
- }
- }
- return attributes;
- }
-
- private static Attribute
- getAttribute(Dataset ds, String attrName) throws Exception
- {
- List attrList = getAttrList((HObject)ds);
- Iterator attrIter = attrList.iterator();
-
- while (attrIter.hasNext())
- {
- Attribute attr = attrIter.next();
- if (attr.getName().equals(attrName))
- {
- return attr;
- }
- }
- return null;
- }
-
- private static Attribute
- getAttribute(HObject ds, String attrName) throws Exception
- {
- List attrList = getAttrList(ds);
- Iterator attrIter = attrList.iterator();
-
- while (attrIter.hasNext())
- {
- Attribute attr = attrIter.next();
- System.out.println(attr.getName());
- if (attr.getName().equals(attrName))
- {
- return attr;
- }
- }
- return null;
- }
- /*-----------------------------------------------------------------------
- * minmax of array
- *-----------------------------------------------------------------------*/
- private double[] getMinMax(Object data, long stackSize)
- {
- double[] minmax = new double[2];
-
- if (data instanceof byte[])
- {
- byte[] tmp = (byte[]) data;
- minmax[0]=tmp[0];
- minmax[1]=tmp[0];
- for(int i=1; iminmax[1])
- minmax[1]=val;
- }
- }
- else if (data instanceof short[])
- {
- short[] tmp = (short[]) data;
- minmax[0]=tmp[0];
- minmax[1]=tmp[0];
- for(int i=1; iminmax[1])
- minmax[1]=val;
- }
- }
- else if (data instanceof int[])
- {
- int[] tmp = (int[]) data;
- minmax[0]=tmp[0];
- minmax[1]=tmp[0];
- for(int i=1; iminmax[1])
- minmax[1]=tmp[i];
- }
- }
- else if (data instanceof long[])
- {
- long[] tmp = (long[]) data;
- minmax[0]=tmp[0];
- minmax[1]=tmp[0];
- for(int i=1; iminmax[1])
- minmax[1]=tmp[i];
- }
- }
- else if (data instanceof float[])
- {
- float[] tmp = (float[]) data;
- minmax[0]=tmp[0];
- minmax[1]=tmp[0];
- for(int i=1; iminmax[1])
- minmax[1]=tmp[i];
- }
- }
- else if (data instanceof double[])
- {
- double[] tmp = (double[]) data;
- minmax[0]=tmp[0];
- minmax[1]=tmp[0];
- for(int i=1; iminmax[1])
- minmax[1]=tmp[i];
- }
- }
- System.out.println("min: " + minmax[0] + ", max: " + minmax[1]);
- return minmax;
- }
- /*-----------------------------------------------------------------------
- * converter functions
- *-----------------------------------------------------------------------*/
- private float[] convertDoubleToFloat(double[] dataIn)
- {
- float[] dataOut = new float[dataIn.length];
- for (int index = 0; index < dataIn.length; index++)
- {
- dataOut[index] = (float) dataIn[index];
- }
- return dataOut;
- }
-
- private float[] convertInt32ToFloat(int[] dataIn)
- {
- float[] dataOut = new float[dataIn.length];
- for (int index = 0; index < dataIn.length; index++)
- {
- dataOut[index] = dataIn[index];
- }
- return dataOut;
- }
-
- private short[] convertInt32ToShort(int[] dataIn)
- {
- short[] dataOut = new short[dataIn.length];
- for (int index = 0; index < dataIn.length; index++)
- {
- dataOut[index] = (short) dataIn[index];
- }
- return dataOut;
- }
-
- private float[] convertInt64ToFloat(long[] dataIn)
- {
- float[] dataOut = new float[dataIn.length];
- for (int index = 0; index < dataIn.length; index++)
- {
- dataOut[index] = dataIn[index];
- }
- return dataOut;
- }
-
- private short[] convertInt64ToShort(long[] dataIn)
- {
- short[] dataOut = new short[dataIn.length];
- for (int index = 0; index < dataIn.length; index++)
- {
- dataOut[index] = (short) dataIn[index];
- }
- return dataOut;
- }
-
-
- private Object convertToUnsigned(Object dataIn,
- int unsignedConvSelec)
- {
- Object dataOut = null;
- if(unsignedConvSelec == 0)
- {
- // cut off values
- if(dataIn instanceof short[])
- {
- short[] tmp = (short[]) dataIn;
- for(int i=0;i maxWidth) size.width = maxWidth;
- if (size.height > maxHeight) size.height = maxHeight;
-
- // create scroll pane
- ScrollPane scroll = new ScrollPane() {
- public Dimension getPreferredSize() {
- return size;
- }
- };
- scroll.add(newPane);
-
- // add scroll pane to original container
- GridBagConstraints constraints = new GridBagConstraints();
- constraints.anchor = GridBagConstraints.WEST;
- constraints.fill = GridBagConstraints.BOTH;
- constraints.weightx = 1.0;
- constraints.weighty = 1.0;
- layout.setConstraints(scroll, constraints);
- pane.add(scroll);
- }
+public class HDF5_Reader_ implements PlugIn {
+ public void run(String arg) {
+ // make sure default values for config are written
+ // HDF5_Config.setDefaultsIfNoValueExists();
+
+ // run plugin
+ String directory = "";
+ String name = "";
+ boolean tryAgain;
+ String openMSG = "Open HDF5...";
+ do {
+ tryAgain = false;
+ OpenDialog od;
+ if (directory.equals(""))
+ od = new OpenDialog(openMSG, arg);
+ else
+ od = new OpenDialog(openMSG, directory, arg);
+
+ directory = od.getDirectory();
+ name = od.getFileName();
+ if (name == null)
+ return;
+ if (name == "")
+ return;
+
+ File testFile = new File(directory + name);
+ if (!testFile.exists() || !testFile.canRead())
+ return;
+
+ if (testFile.isDirectory()) {
+ directory = directory + name;
+ tryAgain = true;
+ }
+ } while (tryAgain);
+
+ IJ.showStatus("Loading HDF5 File: " + directory + name);
+
+ H5File inFile = null;
+
+ // define grouping class
+ HDF5_GroupedVarnames groupedVarnames = new HDF5_GroupedVarnames();
+ boolean loadGroupedVarNames = true;
+
+ try {
+ inFile = new H5File(directory + name, H5File.READ);
+ inFile.open();
+
+ /*-------------------------------------------------------------------
+ * read HDF5_Config prefs
+ *-------------------------------------------------------------------*/
+ boolean groupVarsByName = Boolean.getBoolean(HDF5_Config.getDefaultValue("HDF5.groupVarsByName"));
+ groupVarsByName = Prefs.get("HDF5.groupVarsByName", groupVarsByName);
+
+ boolean showUnmatchedDataSetNames = Boolean.getBoolean(HDF5_Config.getDefaultValue("HDF5.showUnmatchedDataSetNames"));
+ showUnmatchedDataSetNames = Prefs.get("HDF5.showUnmatchedDataSetNames", showUnmatchedDataSetNames);
+
+ String groupVarsByNameFormatGroup = HDF5_Config.getDefaultValue("HDF5.groupVarsByNameFormatGroup");
+ groupVarsByNameFormatGroup = Prefs.get("HDF5.groupVarsByNameFormatGroup", groupVarsByNameFormatGroup);
+
+ // TODO: try to read attribute containing format String
+ String groupVarsByNameFormat = null;
+ try {
+ HObject gr = inFile.get(groupVarsByNameFormatGroup);
+ String attrName = ""; // this will throw an error
+
+ if (gr != null) {
+ // get the attr list and make a selection dialog if
+ // necessary
+ List hintsAttrList = getAttrList(gr);
+ if (hintsAttrList.size() == 1)
+ attrName = hintsAttrList.get(0).getName();
+ else if (hintsAttrList.size() > 1) {
+ String[] hintsAttrNames = new String[hintsAttrList.size()];
+ for (int a = 0; a < hintsAttrList.size(); a++)
+ hintsAttrNames[a] = hintsAttrList.get(a).getName();
+ GenericDialog attrSelecD = new GenericDialog("Format string selector");
+ attrSelecD.addChoice("Select format string", hintsAttrNames, hintsAttrNames[0]);
+ attrSelecD.showDialog();
+ if (attrSelecD.wasCanceled())
+ return;
+ else
+ attrName = attrSelecD.getNextChoice();
+ }
+
+ System.out.println("Reading attribute");
+ Attribute attr = getAttribute(gr, attrName);
+ System.out.println("Reading attribute is ok");
+ if (attr != null)
+ System.out.println("attr is not null");
+ System.out.println("attr.getName(): " + attr.getName());
+ Datatype dType = attr.getType();
+ System.out.println(dType.getDatatypeDescription());
+
+ Object tmp = attr.getValue();
+ if (tmp != null)
+ System.out.println("get value is ok");
+ if (tmp instanceof String) {
+ // we have a string
+ groupVarsByNameFormat = (String) tmp;
+ } else if (tmp instanceof String[]) {
+ // we have a cstring
+ String[] sTmp = (String[]) tmp;
+ groupVarsByNameFormat = "";
+ for (int i = 0; i < sTmp.length; i++)
+ groupVarsByNameFormat = groupVarsByNameFormat + sTmp[i];
+ }
+ System.out.println("File has format string for grouping: " + groupVarsByNameFormat);
+ } else {
+ System.out.println("File has no format string for grouping" + ", using default");
+ groupVarsByNameFormat = HDF5_Config.getDefaultValue("HDF5.groupVarsByNameFormat");
+ groupVarsByNameFormat = Prefs.get("HDF5.groupVarsByNameFormat", groupVarsByNameFormat);
+ }
+ } catch (Exception e) {
+ System.out.println("Error occured read format string " + "for grouping, using default");
+ groupVarsByNameFormat = HDF5_Config.getDefaultValue("HDF5.groupVarsByNameFormat");
+ groupVarsByNameFormat = Prefs.get("HDF5.groupVarsByNameFormat", groupVarsByNameFormat);
+ }
+
+ String dollarRegexpForGrouping = HDF5_Config.getDefaultValue("HDF5.dollarRegexpForGrouping");
+ dollarRegexpForGrouping = Prefs.get("HDF5.dollarRegexpForGrouping", dollarRegexpForGrouping);
+
+ /*-------------------------------------------------------------------
+ * init the frame and channel ranges
+ *-------------------------------------------------------------------*/
+ int minFrameIndex = -1;
+ int maxFrameIndex = -1;
+ int skipFrameIndex = 1;
+
+ int minChannelIndex = -1;
+ int maxChannelIndex = -1;
+ int skipChannelIndex = 1;
+
+ /*-------------------------------------------------------------------
+ * parse the file
+ *-------------------------------------------------------------------*/
+
+ Group rootNode = (Group) ((javax.swing.tree.DefaultMutableTreeNode) inFile.getRootNode()).getUserObject();
+ List varList = getDataSetList(rootNode, new ArrayList());
+
+ GenericDialog gd = new GenericDialog("Variable Name Selection");
+ gd.addMessage("Please select variables to be loaded.\n");
+
+ if (varList.size() < 1) {
+ IJ.error("The file did not contain variables. (broken?)");
+ inFile.close();
+ return;
+ }
+ // else if (varList.size() < 2)
+ // {
+ // gd.addCheckbox("single variable", true);
+ // }
+ else if (groupVarsByName) {
+ // parse file structure
+ String[] varNames = new String[varList.size()];
+ for (int i = 0; i < varList.size(); i++) {
+ varNames[i] = varList.get(i).getFullName();
+ }
+ groupedVarnames.parseVarNames(varNames, groupVarsByNameFormat, dollarRegexpForGrouping);
+ System.out.println(groupedVarnames.toString());
+
+ // make the data set selection dialog
+ minFrameIndex = groupedVarnames.getMinFrameIndex();
+ maxFrameIndex = groupedVarnames.getMaxFrameIndex();
+ minChannelIndex = groupedVarnames.getMinChannelIndex();
+ maxChannelIndex = groupedVarnames.getMaxChannelIndex();
+
+ gd = new GenericDialog("Variable Name Selection");
+ // check if we have matched var names
+ if (groupedVarnames.getNFrames() > 0) {
+ gd.addCheckbox("Load grouped data sets", loadGroupedVarNames);
+
+ gd.addMessage("Select frames and channels you want to read");
+ gd.addMessage("Frame selection (start/step/end): ");
+
+ gd.addStringField("Frame selection (start:[step:]end): ", Integer.toString(minFrameIndex) + ":" + Integer.toString(skipFrameIndex) + ":" + Integer.toString(maxFrameIndex));
+
+ gd.addStringField("Channel selection (start:[step:]end): ", Integer.toString(minChannelIndex) + ":" + Integer.toString(skipChannelIndex) + ":" + Integer.toString(maxChannelIndex));
+ }
+
+ // get unmatched names
+ List unmatchedVarNames = groupedVarnames.getUnmatchedVarNames();
+ if (showUnmatchedDataSetNames) {
+ // add all unmatched data set names to the dialog
+ String[] varSelections = new String[unmatchedVarNames.size()];
+ boolean[] defaultValues = new boolean[unmatchedVarNames.size()];
+ for (int i = 0; i < unmatchedVarNames.size(); i++) {
+ Dataset var = (Dataset) inFile.get(unmatchedVarNames.get(i));
+ int rank = var.getRank();
+ String title = rank + "D: " + var.getFullName() + " " + var.getDatatype().getDatatypeDescription() + "( ";
+ long[] extent = var.getDims();
+ for (int d = 0; d < rank; ++d) {
+ if (d != 0)
+ title += "x";
+ title += extent[d];
+ }
+ title += ")";
+ varSelections[i] = title;
+ defaultValues[i] = false;
+ }
+ System.out.println("addcheckboxgroup with " + unmatchedVarNames.size() + " rows");
+ gd.addCheckboxGroup(unmatchedVarNames.size(), 1, varSelections, defaultValues);
+ addScrollBars(gd);
+ }
+ gd.showDialog();
+ if (gd.wasCanceled()) {
+ return;
+ }
+
+ // load grouped var names ?
+ if (groupedVarnames.getNFrames() > 0)
+ loadGroupedVarNames = gd.getNextBoolean();
+
+ // read range selections if we have matched varnames
+ String frameRange = null;
+ String channelRange = null;
+ if (groupedVarnames.getNFrames() > 0) {
+ frameRange = gd.getNextString();
+ channelRange = gd.getNextString();
+ }
+ // parse the range selection
+ String[] frameRangeToks = null;
+ String[] channelRangeToks = null;
+ boolean wrongFrameRange = true;
+ boolean wrongChannelRange = true;
+ // check if the parsed values are in range
+ if (groupedVarnames.getNFrames() > 0 && loadGroupedVarNames)
+ while (wrongFrameRange || wrongChannelRange) {
+ // check frame range
+ frameRangeToks = frameRange.split(":");
+ if (frameRangeToks.length == 1) {
+ // single frame
+ try {
+ System.out.println("single frame");
+ minFrameIndex = Integer.parseInt(frameRangeToks[0]);
+ maxFrameIndex = minFrameIndex;
+ wrongFrameRange = false;
+ } catch (Exception e) {
+ wrongFrameRange = true;
+ }
+ } else if (frameRangeToks.length == 2) {
+ // frame range with skipFrameIndex=1
+ try {
+ System.out.println("frame range with skipFrameIndex=1");
+ minFrameIndex = Integer.parseInt(frameRangeToks[0]);
+ maxFrameIndex = Integer.parseInt(frameRangeToks[1]);
+ wrongFrameRange = false;
+ } catch (Exception e) {
+ wrongFrameRange = true;
+ }
+ } else if (frameRangeToks.length == 3) {
+ // frame range with skipFrameIndex
+ try {
+ System.out.println("frame range with skipFrameIndex");
+ minFrameIndex = Integer.parseInt(frameRangeToks[0]);
+ skipFrameIndex = Integer.parseInt(frameRangeToks[1]);
+ maxFrameIndex = Integer.parseInt(frameRangeToks[2]);
+ wrongFrameRange = false;
+ } catch (Exception e) {
+ wrongFrameRange = true;
+ }
+ } else {
+ // wrong format
+ System.out.println("wrong format");
+ wrongFrameRange = true;
+ }
+
+ // check channel range
+ channelRangeToks = channelRange.split(":");
+ if (channelRangeToks.length == 1) {
+ // single channel
+ try {
+ minChannelIndex = Integer.parseInt(channelRangeToks[0]);
+ maxChannelIndex = minChannelIndex;
+ wrongChannelRange = false;
+ } catch (Exception e) {
+ wrongChannelRange = true;
+ }
+ } else if (channelRangeToks.length == 2) {
+ // channel range with skipChannelIndex=1
+ try {
+ minChannelIndex = Integer.parseInt(channelRangeToks[0]);
+ maxChannelIndex = Integer.parseInt(channelRangeToks[1]);
+ wrongChannelRange = false;
+ } catch (Exception e) {
+ wrongChannelRange = true;
+ }
+ } else if (channelRangeToks.length == 3) {
+ // channel range with skipChannelIndex
+ try {
+ minChannelIndex = Integer.parseInt(channelRangeToks[0]);
+ skipChannelIndex = Integer.parseInt(channelRangeToks[1]);
+ maxChannelIndex = Integer.parseInt(channelRangeToks[2]);
+ wrongChannelRange = false;
+ } catch (Exception e) {
+ wrongChannelRange = true;
+ }
+ } else {
+ // wrong format
+ wrongChannelRange = true;
+ }
+ if (wrongFrameRange || wrongChannelRange) {
+ // show dialog again
+ System.out.println("show dialog again");
+ // TODO reset dialog when possible
+ gd = new GenericDialog("Range Selection");
+ gd.addMessage("Select frames and channels you want to read");
+ gd.addMessage("Frame selection (start/step/end): ");
+
+ gd.addStringField("Frame selection (start:[step:]end): ", Integer.toString(minFrameIndex) + ":" + Integer.toString(skipFrameIndex) + ":" + Integer.toString(maxFrameIndex));
+
+ gd.addStringField("Channel selection (start:[step:]end): ",
+ Integer.toString(minChannelIndex) + ":" + Integer.toString(skipChannelIndex) + ":" + Integer.toString(maxChannelIndex));
+ gd.showDialog();
+ System.out.println("read ranges again");
+ frameRange = gd.getNextString();
+ channelRange = gd.getNextString();
+
+ }
+ if (gd.wasCanceled()) {
+ return;
+ }
+ // the parameters for the range have correct format
+ }
+
+ if (showUnmatchedDataSetNames) {
+ varList = new ArrayList();
+ // fill varList with unmatched var names
+ for (int i = 0; i < unmatchedVarNames.size(); i++) {
+ String dsName = unmatchedVarNames.get(i);
+ try {
+ HObject ds = inFile.get(dsName);
+ if (ds != null && ds instanceof Dataset) {
+ varList.add((Dataset) ds);
+ }
+ } catch (Exception e) {
+ System.out.println("The file does not contain a variable " + "with name " + "`" + dsName + "`!");
+ }
+ }
+ } else {
+ // set varList=empty if we dont want unmatched var names
+ varList = new ArrayList();
+ }
+
+ } else if (varList.size() > 1000) {
+ /*-----------------------------------------------------------------
+ * FIXME: quick an dirty hack for files with more than 1000
+ * datasets
+ *-----------------------------------------------------------------*/
+ gd = new GenericDialog("Variable Name Selection");
+ gd.addMessage("Too many variables in your file! " + "(More than 1000)\n\n" + "Please enter the full name of your desired dataset.");
+ gd.addStringField("dataset name", "");
+ gd.showDialog();
+
+ if (gd.wasCanceled()) {
+ return;
+ }
+
+ String dsName = gd.getNextString();
+ varList = new ArrayList();
+ try {
+ HObject ds = inFile.get(dsName);
+ if (ds != null && ds instanceof Dataset) {
+ varList.add((Dataset) ds);
+ gd.addCheckbox("single variable", true);
+ } else {
+ IJ.error("The file does not contain a variable with name " + "`" + dsName + "`!");
+ inFile.close();
+ return;
+ }
+ } catch (Exception e) {
+ IJ.error("The file does not contain a variable with name " + "`" + dsName + "`!");
+ inFile.close();
+ return;
+ }
+ } else {
+ String[] varSelections = new String[varList.size()];
+ boolean[] defaultValues = new boolean[varList.size()];
+ for (int i = 0; i < varList.size(); i++) {
+ Dataset var = varList.get(i);
+ int rank = var.getRank();
+ String title = rank + "D: " + var.getFullName() + " " + var.getDatatype().getDatatypeDescription() + "( ";
+ long[] extent = var.getDims();
+ for (int d = 0; d < rank; ++d) {
+ if (d != 0)
+ title += "x";
+ title += extent[d];
+ }
+ title += ")";
+ varSelections[i] = title;
+ defaultValues[i] = false;
+ }
+ System.out.println("addcheckboxgroup with " + varList.size() + " rows");
+ gd.addCheckboxGroup(varList.size(), 1, varSelections, defaultValues);
+ addScrollBars(gd);
+ gd.showDialog();
+
+ if (gd.wasCanceled()) {
+ return;
+ }
+ }
+ /*-------------------------------------------------------------------
+ * now reading data sets
+ *-------------------------------------------------------------------*/
+ if (groupVarsByName && groupedVarnames.getNFrames() > 0 && loadGroupedVarNames) {
+ groupedVarnames.setFrameAndChannelRange(minFrameIndex, skipFrameIndex, maxFrameIndex, minChannelIndex, skipChannelIndex, maxChannelIndex);
+ // TODO implement hyperstack reading
+ int nFrames = groupedVarnames.getNFrames();
+ int nChannels = groupedVarnames.getNChannels();
+
+ // get extents of first data set
+ long[] extent = null;
+ int rank = -1;
+ double[] elem_sizes = new double[3];
+ String dsName = "";
+ String[] formatTokens = groupedVarnames.getFormatTokens();
+ Dataset var = null;
+ boolean isSigned16Bit = false;
+ int unsignedConvSelec = 0; // cut off values
+ try {
+ TimeFrame f = groupedVarnames.getFrame(0);
+ if (f == null)
+ System.out.println("frame is null");
+ if (formatTokens.length == 2)
+ dsName = formatTokens[0] + Integer.toString(f.getFrameIndex()) + formatTokens[1] + Integer.toString(f.getChannelIndices()[0]);
+ else if (formatTokens.length == 3)
+ dsName = formatTokens[0] + Integer.toString(f.getFrameIndex()) + formatTokens[1] + Integer.toString(f.getChannelIndices()[0]) + formatTokens[2];
+ System.out.println("VarName: " + dsName);
+ HObject ds = inFile.get(dsName);
+ if (ds != null && ds instanceof Dataset) {
+ var = (Dataset) ds;
+ Datatype dType = var.getDatatype();
+ isSigned16Bit = !dType.isUnsigned() && (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && (dType.getDatatypeSize() == 2);
+ if (isSigned16Bit) {
+ GenericDialog convDiag = new GenericDialog("Unsigned to signed conversion");
+ convDiag.addMessage("Detected unsigned datatype, which " + "is not supported.");
+ String[] convOptions = new String[2];
+ convOptions[0] = "cut off values";
+ convOptions[1] = "convert to float";
+ convDiag.addChoice("Please select an conversion option:", convOptions, convOptions[0]);
+ convDiag.showDialog();
+ if (convDiag.wasCanceled())
+ return;
+ unsignedConvSelec = convDiag.getNextChoiceIndex();
+ }
+ // TODO check for unsupported datatypes int,long
+ rank = var.getRank();
+ extent = var.getDims();
+ Attribute elemsize_att = getAttribute(var, "element_size_um");
+
+ if (elemsize_att == null) {
+ elem_sizes[0] = 1.0;
+ elem_sizes[1] = 1.0;
+ elem_sizes[2] = 1.0;
+ } else {
+ System.out.println("Reading element_size_um");
+ float[] tmp = null;
+ try {
+ tmp = ((float[]) elemsize_att.getValue());
+ elem_sizes[0] = tmp[0];
+ elem_sizes[1] = tmp[1];
+ elem_sizes[2] = tmp[2];
+ } catch (java.lang.ClassCastException e) {
+ String title = "Error Reading Element Size";
+ String msg = "The element_size_um attribute " + "has wrong format!\n";
+ msg += "Setting to default size of (1,1,1)...";
+ new ij.gui.MessageDialog(null, title, msg);
+ elem_sizes[0] = 1;
+ elem_sizes[1] = 1;
+ elem_sizes[2] = 1;
+ }
+ }
+ } else {
+ IJ.error("The file does not contain a variable with name " + "`" + dsName + "`!");
+ inFile.close();
+ return;
+ }
+ } catch (Exception e) {
+ IJ.error("The file does not contain a variable with name " + "`" + dsName + "`!");
+ inFile.close();
+ return;
+ }
+ // String title = rank + "D: " + var.getFullName() +
+ // " "
+ // + var.getDatatype().getDatatypeDescription() + "( ";
+
+ // read 3D or 2D dataset
+ if (rank == 3 || rank == 2) {
+ int nRows = -1; // height
+ int nCols = -1; // width
+ int nSlices = 1; // if rank == 2
+ if (rank == 3) {
+ nSlices = (int) extent[0];
+ nRows = (int) extent[1];
+ nCols = (int) extent[2];
+ } else {
+ nRows = (int) extent[0];
+ nCols = (int) extent[1];
+ }
+
+ // create a new image stack and fill in the data
+ ImageStack stack = new ImageStack(nCols, nRows, nFrames * nSlices * nChannels);
+ System.out.println("stackSize: " + Integer.toString(stack.getSize()));
+
+ ImagePlus imp = new ImagePlus();
+ // to get getFrameIndex() working
+ imp.setDimensions(nChannels, nSlices, nFrames);
+
+ long stackSize = nCols * nRows;
+ // global min max values of all data sets
+ double[] minValChannel = new double[nChannels];
+ double[] maxValChannel = new double[nChannels];
+
+ // TODO implement frame and channel ranges
+ // now read frame by frame
+ for (int fIdx = 0; fIdx < nFrames; fIdx++) {
+ // get current frame
+ TimeFrame f = groupedVarnames.getFrame(fIdx);
+ if (f == null)
+ System.out.println("frame is null");
+ // get channel indices
+
+ // TODO: check if frame has same parameters as first,
+ // skip otherwise
+
+ // now read channel by channel of frame
+ for (int cIdx = 0; cIdx < nChannels; cIdx++) {
+ if (formatTokens.length == 2)
+ dsName = formatTokens[0] + Integer.toString(f.getFrameIndex()) + formatTokens[1] + Integer.toString(f.getChannelIndices()[cIdx]);
+ else if (formatTokens.length == 3)
+ dsName = formatTokens[0] + Integer.toString(f.getFrameIndex()) + formatTokens[1] + Integer.toString(f.getChannelIndices()[cIdx]) + formatTokens[2];
+
+ System.out.println("VarName: " + dsName);
+
+ HObject ds = inFile.get(dsName);
+ if (ds != null && ds instanceof Dataset) {
+ var = (Dataset) ds;
+ rank = var.getRank();
+ extent = var.getDims();
+ }
+
+ // TODO: check if dataset has same parameters as
+ // first,
+ // skip otherwise
+
+ long[] selected = var.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ selected[0] = extent[0];
+ selected[1] = extent[1];
+ if (selected.length > 2)
+ selected[2] = extent[2];
+
+ Object wholeDataset = var.read();
+ if (isSigned16Bit)
+ wholeDataset = convertToUnsigned(wholeDataset, unsignedConvSelec);
+
+ long wholeDatasetSize = 1;
+ for (int d = 0; d < extent.length; d++)
+ wholeDatasetSize *= extent[d];
+
+ if (fIdx == 0) {
+ // init min/max
+ double[] minMaxVal = getMinMax(wholeDataset, wholeDatasetSize);
+ minValChannel[cIdx] = minMaxVal[0];
+ maxValChannel[cIdx] = minMaxVal[1];
+ } else {
+ // update minMaxVal
+ double[] minMaxVal = getMinMax(wholeDataset, wholeDatasetSize);
+ minValChannel[cIdx] = Math.min(minMaxVal[0], minValChannel[cIdx]);
+ maxValChannel[cIdx] = Math.max(minMaxVal[1], maxValChannel[cIdx]);
+ }
+
+ for (int lev = 0; lev < nSlices; ++lev) {
+ // if ((lev % progressDivisor) == 0)
+ // IJ.showProgress((float) lev / (float)
+ // extent[0]);
+ // select hyperslab for lev
+ // start[0] = lev;
+ // Object slice = var.read();
+
+ long startIdx = lev * stackSize;
+ long numElements = stackSize;
+ if (wholeDataset instanceof byte[]) {
+ byte[] tmp = (byte[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.setPixels(tmp, imp.getStackIndex(cIdx + 1, lev + 1, fIdx + 1));
+ } else if (wholeDataset instanceof short[]) {
+ short[] tmp = (short[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.setPixels(tmp, imp.getStackIndex(cIdx + 1, lev + 1, fIdx + 1));
+ } else if (wholeDataset instanceof int[]) {
+ System.out.println("Datatype `int` is not supported. " + "Skipping whole frame!");
+ // int[] tmp = (int[])
+ // extractSubarray(wholeDataset,
+ // startIdx,
+ // numElements);
+ // if(datatypeIfUnsupported.getDatatypeClass()
+ // == Datatype.CLASS_FLOAT)
+ // {
+ // stack.setPixels(convertInt32ToFloat(tmp),
+ // imp.getStackIndex(cIdx+1,lev+1,fIdx+1));
+ // }
+ // if(datatypeIfUnsupported.getDatatypeClass()
+ // == Datatype.CLASS_INTEGER)
+ // {
+ // stack.setPixels(convertInt32ToShort(tmp),
+ // imp.getStackIndex(cIdx+1,lev+1,fIdx+1));
+ // }
+ } else if (wholeDataset instanceof long[]) {
+ System.out.println("Datatype `long` is not supported. " + "Skipping whole frame!");
+ // long[] tmp = (long[])
+ // extractSubarray(wholeDataset,
+ // startIdx,
+ // numElements);
+ // if(datatypeIfUnsupported.getDatatypeClass()
+ // == Datatype.CLASS_FLOAT)
+ // {
+ // stack.setPixels(convertInt64ToFloat(tmp),
+ // imp.getStackIndex(cIdx+1,lev+1,fIdx+1));
+ // }
+ // if(datatypeIfUnsupported.getDatatypeClass()
+ // == Datatype.CLASS_INTEGER)
+ // {
+ // stack.setPixels(convertInt64ToShort(tmp),
+ // imp.getStackIndex(cIdx+1,lev+1,fIdx+1));
+ // }
+ } else if (wholeDataset instanceof float[]) {
+ float[] tmp = (float[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.setPixels(tmp, imp.getStackIndex(cIdx + 1, lev + 1, fIdx + 1));
+ } else if (wholeDataset instanceof double[]) {
+ System.out.println("Datatype `double` is not supported. " + "Converting whole frame to `float`!");
+ float[] tmp = convertDoubleToFloat((double[]) extractSubarray(wholeDataset, startIdx, numElements));
+ stack.setPixels(tmp, imp.getStackIndex(cIdx + 1, lev + 1, fIdx + 1));
+ } else {
+ // try to put pixels on stack
+ stack.setPixels(extractSubarray(wholeDataset, startIdx, numElements), imp.getStackIndex(cIdx + 1, lev + 1, fIdx + 1));
+ }
+ }
+ }
+ }
+ IJ.showProgress(1.f);
+
+ System.out.println("Creating image plus");
+ // stack.trim();
+ imp = new ImagePlus(directory + name + ": " + groupedVarnames.getFormatString(), stack);
+
+ imp.setDimensions(nChannels, nSlices, nFrames);
+
+ if (nChannels > 1) {
+ System.out.println("Creating composite hyperstack with " + Integer.toString(nChannels) + " channels.");
+ imp = new CompositeImage(imp, CompositeImage.COMPOSITE);
+ } else {
+ System.out.println("Creating grayscale hyperstack.");
+ // imp = new CompositeImage(imp,
+ // CompositeImage.GRAYSCALE);
+ }
+
+ System.out.println("nFrames: " + Integer.toString(nFrames));
+ System.out.println("nSlices: " + Integer.toString(nSlices));
+
+ System.out.println("stackSize: " + Integer.toString(stack.getSize()));
+
+ // set element_size_um
+ imp.getCalibration().pixelDepth = elem_sizes[0];
+ imp.getCalibration().pixelHeight = elem_sizes[1];
+ imp.getCalibration().pixelWidth = elem_sizes[2];
+
+ // System.out.println(" Min = " + minMaxVal[0] +
+ // ", Max = " + minMaxVal[1]);
+ // imp.setDisplayRange(1.5*minMaxVal[0], 0.5*minMaxVal[1]);
+ // imp.resetDisplayRange();
+ int[] channelsIJ = { 4, 2, 1 };
+ for (int c = 0; c < nChannels; c++) {
+ // imp.setDisplayRange(minValChannel[c],
+ // maxValChannel[c],
+ // channelsIJ[c]);
+ // imp.setSlice(c+1);
+ imp.setPosition(c + 1, 1, 1);
+ System.out.println("Current channel: " + Integer.toString(imp.getChannel() - 1));
+
+ imp.setDisplayRange(minValChannel[c], maxValChannel[c]);
+ // ,
+ // channelsIJ[c]);
+ System.out.println("Setting display range for channel " + Integer.toString(c) + " (ij idx: " + Integer.toString(channelsIJ[c]) + "): \n\t" + Double.toString(minValChannel[c])
+ + "/" + Double.toString(maxValChannel[c]));
+ }
+
+ imp.show();
+ imp.updateStatusbarValue();
+ imp.setOpenAsHyperStack(true);
+ } else {
+ // not supported format
+ IJ.error("The file does not contain a supported data set structure!" + "\nChannels have to be 2D or 3D scalar data sets!");
+ }
+ }
+
+ // varList should have size=0 if only grouping is wanted
+ // use old style
+ for (int i = 0; i < varList.size(); ++i) {
+ if (gd.getNextBoolean()) {
+ Dataset var = varList.get(i);
+ int rank = var.getRank();
+ Datatype datatype = var.getDatatype();
+ Datatype datatypeIfUnsupported = null;
+ long[] extent = var.getDims();
+
+ System.out.println("Reading Variable: " + var.getName());
+ System.out.println(" Rank = " + rank + ", Data-type = " + datatype.getDatatypeDescription());
+ System.out.print(" Extent in px (level,row,col):");
+ for (int d = 0; d < rank; ++d)
+ System.out.print(" " + extent[d]);
+ System.out.println("");
+ IJ.showStatus("Reading Variable: " + var.getName() + " (" + extent[0] + " slices)");
+
+ Attribute elemsize_att = getAttribute(var, "element_size_um");
+ double[] elem_sizes = new double[3];
+ if (elemsize_att == null) {
+ elem_sizes[0] = 1.0;
+ elem_sizes[1] = 1.0;
+ elem_sizes[2] = 1.0;
+ } else {
+ System.out.println("Reading element_size_um");
+ Object tmp = elemsize_att.getValue();
+ if (tmp instanceof float[]) {
+ elem_sizes[0] = ((float[]) tmp)[0];
+ elem_sizes[1] = ((float[]) tmp)[1];
+ elem_sizes[2] = ((float[]) tmp)[2];
+ } else if (tmp instanceof double[]) {
+ elem_sizes[0] = ((double[]) tmp)[0];
+ elem_sizes[1] = ((double[]) tmp)[1];
+ elem_sizes[2] = ((double[]) tmp)[2];
+ } else {
+ String title = "Error Reading Element Size";
+ String msg = "The element_size_um attribute has " + "wrong format!\n" + "Setting to default size of (1,1,1)...";
+ new ij.gui.MessageDialog(null, title, msg);
+ elem_sizes[0] = 1.0;
+ elem_sizes[1] = 1.0;
+ elem_sizes[2] = 1.0;
+ }
+ }
+ System.out.println(" Element-Size in um (level,row,col): " + elem_sizes[0] + ", " + elem_sizes[1] + ", " + elem_sizes[2]);
+
+ // nice gadget to update the progress bar
+ long progressDivisor = extent[0] / progressSteps;
+ if (progressDivisor < 1)
+ progressDivisor = 1;
+
+ // check if we have an unsupported datatype
+ if (datatype.getDatatypeClass() == Datatype.CLASS_INTEGER && (datatype.getDatatypeSize() == 4 || datatype.getDatatypeSize() == 8)) {
+ System.out.println("Datatype not supported by ImageJ");
+ GenericDialog typeSelDiag = new GenericDialog("Datatype Selection");
+ typeSelDiag.addMessage("The datatype `" + datatype.getDatatypeDescription() + "` is not supported by ImageJ.\n\n");
+ typeSelDiag.addMessage("Please select your wanted datatype.\n");
+ String[] choices = new String[2];
+ choices[0] = "float";
+ choices[1] = "short";
+ typeSelDiag.addChoice(" Possible types are", choices, "float");
+ typeSelDiag.showDialog();
+
+ if (typeSelDiag.wasCanceled()) {
+ return;
+ }
+ int selection = typeSelDiag.getNextChoiceIndex();
+ if (selection == 0) {
+ System.out.println("float selected");
+ datatypeIfUnsupported = new H5Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, -1);
+ }
+ if (selection == 1) {
+ System.out.println("short selected");
+ int typeSizeInByte = 2;
+ datatypeIfUnsupported = new H5Datatype(Datatype.CLASS_INTEGER, typeSizeInByte, Datatype.NATIVE, -1);
+ }
+ }
+
+ // read dataset
+ if (rank == 5 && extent[4] == 3) {
+ System.out.println(" Detected HyperVolume (type RGB).");
+
+ // create a new image stack and fill in the data
+ ImageStack stack = new ImageStack((int) extent[3], (int) extent[2]);
+ // read the whole dataset, since reading chunked
+ // datasets
+ // slice-wise is too slow
+
+ long[] dims = var.getDims(); // the dimension sizes
+ // of the dataset
+ long[] selected = var.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ selected[0] = dims[0];
+ selected[1] = dims[1];
+ selected[2] = dims[2];
+ selected[3] = dims[3];
+ selected[4] = dims[4];// 3
+ // the selection
+ Object wholeDataset = var.read();
+ // check for unsigned datatype
+ int unsignedConvSelec = 0;
+ Datatype dType = var.getDatatype();
+ boolean isSigned16Bit = !dType.isUnsigned() && (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && (dType.getDatatypeSize() == 2);
+
+ if (isSigned16Bit) {
+ GenericDialog convDiag = new GenericDialog("Unsigend to signed conversion");
+ convDiag.addMessage("Detected unsigned datatype, which " + "is not supported.");
+ String[] convOptions = new String[2];
+ convOptions[0] = "cut off values";
+ convOptions[1] = "convert to float";
+ convDiag.addChoice("Please select an conversion option:", convOptions, convOptions[0]);
+ convDiag.showDialog();
+ if (convDiag.wasCanceled())
+ return;
+ unsignedConvSelec = convDiag.getNextChoiceIndex();
+ wholeDataset = convertToUnsigned(wholeDataset, unsignedConvSelec);
+ }
+
+ long stackSize = extent[2] * extent[3];
+ long singleVolumeSize = extent[1] * stackSize;
+
+ for (int volIDX = 0; volIDX < extent[0]; ++volIDX) {
+ if ((volIDX % progressDivisor) == 0)
+ IJ.showProgress((float) volIDX / (float) extent[0]);
+ // start[0] = volIDX;
+
+ for (int lev = 0; lev < extent[1]; ++lev) {
+ // select hyperslab for lev
+ // start[1] = lev;
+ // Object slice = var.read();
+ long startIdx = (volIDX * singleVolumeSize * 3) + (lev * stackSize * 3);
+ long numElements = stackSize * 3;
+
+ if (wholeDataset instanceof byte[]) {
+ byte[] tmp = (byte[]) extractSubarray(wholeDataset, startIdx, numElements);
+ byte[] rChannel = new byte[(int) stackSize];
+ byte[] gChannel = new byte[(int) stackSize];
+ byte[] bChannel = new byte[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (wholeDataset instanceof short[]) {
+ short[] tmp = (short[]) extractSubarray(wholeDataset, startIdx, numElements);
+ short[] rChannel = new short[(int) stackSize];
+ short[] gChannel = new short[(int) stackSize];
+ short[] bChannel = new short[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (wholeDataset instanceof int[]) {
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ float[] tmp = convertInt32ToFloat((int[]) extractSubarray(wholeDataset, startIdx, numElements));
+ float[] rChannel = new float[(int) stackSize];
+ float[] gChannel = new float[(int) stackSize];
+ float[] bChannel = new float[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ short[] tmp = convertInt32ToShort((int[]) extractSubarray(wholeDataset, startIdx, numElements));
+ short[] rChannel = new short[(int) stackSize];
+ short[] gChannel = new short[(int) stackSize];
+ short[] bChannel = new short[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ }
+ } else if (wholeDataset instanceof long[]) {
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ float[] tmp = convertInt64ToFloat((long[]) extractSubarray(wholeDataset, startIdx, numElements));
+ float[] rChannel = new float[(int) stackSize];
+ float[] gChannel = new float[(int) stackSize];
+ float[] bChannel = new float[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ short[] tmp = convertInt64ToShort((long[]) extractSubarray(wholeDataset, startIdx, numElements));
+ short[] rChannel = new short[(int) stackSize];
+ short[] gChannel = new short[(int) stackSize];
+ short[] bChannel = new short[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ }
+ } else if (wholeDataset instanceof float[]) {
+ float[] tmp = (float[]) extractSubarray(wholeDataset, startIdx, numElements);
+ float[] rChannel = new float[(int) stackSize];
+ float[] gChannel = new float[(int) stackSize];
+ float[] bChannel = new float[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (wholeDataset instanceof double[]) {
+ float[] tmp = convertDoubleToFloat((double[]) extractSubarray(wholeDataset, startIdx, numElements));
+ float[] rChannel = new float[(int) stackSize];
+ float[] gChannel = new float[(int) stackSize];
+ float[] bChannel = new float[(int) stackSize];
+ for (int row = 0; row < extent[2]; ++row) {
+ for (int col = 0; col < extent[3]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else {
+ // try to put pixels on stack
+ stack.addSlice(null, extractSubarray(wholeDataset, startIdx, numElements));
+ }
+ }
+ }
+
+ IJ.showProgress(1.f);
+ ImagePlus imp = new ImagePlus(directory + name + " " + var.getName(), stack);
+ // new for hyperstack
+ int nChannels = 3;
+ int nSlices = (int) extent[1];
+ int nFrames = (int) extent[0];
+ System.out.println("nFrames: " + Integer.toString(nFrames));
+ System.out.println("nSlices: " + Integer.toString(nSlices));
+
+ System.out.println("stackSize: " + Integer.toString(stack.getSize()));
+
+ imp.setDimensions(nChannels, nSlices, nFrames);
+ imp = new CompositeImage(imp, CompositeImage.COMPOSITE);
+ imp.setOpenAsHyperStack(true);
+ // imp = imp.createHyperStack(directory + name + " "
+ // + var.getName(),
+ // nChannels,
+ // nSlices,
+ // nFrames,32);
+ // imp.setStack(stack,nChannels,nSlices,nFrames);
+
+ imp.getCalibration().pixelDepth = elem_sizes[0];
+ imp.getCalibration().pixelHeight = elem_sizes[1];
+ imp.getCalibration().pixelWidth = elem_sizes[2];
+ // getMinMax();
+ // imp.setDisplayRange(0,229);
+ imp.resetDisplayRange();
+ imp.show();
+ } else if (rank == 4) {
+ if (extent[3] == 3) {
+ System.out.println(" Detected color Image (type RGB).");
+
+ // create a new image stack and fill in the data
+ ImageStack stack = new ImageStack((int) extent[2], (int) extent[1]);
+
+ long[] dims = var.getDims(); // the dimension sizes
+ // of the dataset
+ long[] selected = var.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ selected[0] = dims[0];
+ selected[1] = dims[1];
+ selected[2] = dims[2];
+ selected[3] = dims[3];
+ // long[] start = var.getStartDims(); // the off set
+ // of
+ // // the selection
+
+ Object wholeDataset = var.read();
+ // check for unsigned datatype
+ int unsignedConvSelec = 0;
+ Datatype dType = var.getDatatype();
+ boolean isSigned16Bit = !dType.isUnsigned() && (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && (dType.getDatatypeSize() == 2);
+ if (isSigned16Bit) {
+ GenericDialog convDiag = new GenericDialog("Unsigend to signed conversion");
+ convDiag.addMessage("Detected unsigned datatype, which " + "is not supported.");
+ String[] convOptions = new String[2];
+ convOptions[0] = "cut off values";
+ convOptions[1] = "convert to float";
+ convDiag.addChoice("Please select an conversion option:", convOptions, convOptions[0]);
+ convDiag.showDialog();
+ if (convDiag.wasCanceled())
+ return;
+ unsignedConvSelec = convDiag.getNextChoiceIndex();
+ wholeDataset = convertToUnsigned(wholeDataset, unsignedConvSelec);
+ }
+
+ long stackSize = extent[1] * extent[2] * 3;
+
+ for (int lev = 0; lev < extent[0]; ++lev) {
+ if ((lev % progressDivisor) == 0)
+ IJ.showProgress((float) lev / (float) extent[0]);
+
+ // // select hyperslab for lev
+ // start[0] = lev;
+ // Object slice = var.read();
+
+ long startIdx = lev * stackSize;
+ long numElements = stackSize;
+ Object slice = extractSubarray(wholeDataset, startIdx, numElements);
+
+ int size = (int) (extent[2] * extent[1]);
+ if (slice instanceof byte[]) {
+ byte[] tmp = (byte[]) slice;
+ byte[] rChannel = new byte[size];
+ byte[] gChannel = new byte[size];
+ byte[] bChannel = new byte[size];
+ for (int row = 0; row < extent[1]; ++row) {
+ for (int col = 0; col < extent[2]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof short[]) {
+ short[] tmp = (short[]) slice;
+ short[] rChannel = new short[size];
+ short[] gChannel = new short[size];
+ short[] bChannel = new short[size];
+ for (int row = 0; row < extent[1]; ++row) {
+ for (int col = 0; col < extent[2]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof int[]) {
+ int[] tmp = (int[]) slice;
+ int[] rChannel = new int[size];
+ int[] gChannel = new int[size];
+ int[] bChannel = new int[size];
+ for (int row = 0; row < extent[1]; ++row) {
+ for (int col = 0; col < extent[2]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof long[]) {
+ long[] tmp = (long[]) slice;
+ long[] rChannel = new long[size];
+ long[] gChannel = new long[size];
+ long[] bChannel = new long[size];
+ for (int row = 0; row < extent[1]; ++row) {
+ for (int col = 0; col < extent[2]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof float[]) {
+ float[] tmp = (float[]) slice;
+ float[] rChannel = new float[size];
+ float[] gChannel = new float[size];
+ float[] bChannel = new float[size];
+ for (int row = 0; row < extent[1]; ++row) {
+ for (int col = 0; col < extent[2]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof double[]) {
+ double[] tmp = (double[]) slice;
+ double[] rChannel = new double[size];
+ double[] gChannel = new double[size];
+ double[] bChannel = new double[size];
+ for (int row = 0; row < extent[1]; ++row) {
+ for (int col = 0; col < extent[2]; ++col) {
+ int offsetRGB = (row * (int) extent[2] * 3) + (col * 3);
+ int offset = (row * (int) extent[2]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ }
+ }
+ ImagePlus imp = new ImagePlus(directory + name + " " + var.getName(), stack);
+ // new for hyperstack
+ int nChannels = 3;
+ int nSlices = (int) extent[0];
+ int nFrames = 1;
+ imp.setDimensions(nChannels, nSlices, nFrames);
+ imp = new CompositeImage(imp, CompositeImage.COMPOSITE);
+ imp.setOpenAsHyperStack(true);
+
+ imp.getCalibration().pixelDepth = elem_sizes[0];
+ imp.getCalibration().pixelHeight = elem_sizes[1];
+ imp.getCalibration().pixelWidth = elem_sizes[2];
+
+ // getMinMax();
+ imp.resetDisplayRange();
+ imp.show();
+ imp.updateStatusbarValue();
+ } else // we have a HyperVolume
+ {
+ System.out.println(" Detected HyperVolume (type GREYSCALE).");
+
+ // create a new image stack and fill in the data
+ ImageStack stack = new ImageStack((int) extent[3], (int) extent[2]);
+ // read the whole dataset, since reading chunked
+ // datasets
+ // slice-wise is too slow
+
+ long[] dims = var.getDims(); // the dimension sizes
+ // of the dataset
+ long[] selected = var.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ selected[0] = dims[0];
+ selected[1] = dims[1];
+ selected[2] = dims[2];
+ selected[3] = dims[3];
+ // the selection
+ Object wholeDataset = var.read();
+ // check for unsigned datatype
+ int unsignedConvSelec = 0;
+ Datatype dType = var.getDatatype();
+ boolean isSigned16Bit = !dType.isUnsigned() && (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && (dType.getDatatypeSize() == 2);
+ if (isSigned16Bit) {
+ GenericDialog convDiag = new GenericDialog("Unsigend to signed conversion");
+ convDiag.addMessage("Detected unsigned datatype, which " + "is not supported.");
+ String[] convOptions = new String[2];
+ convOptions[0] = "cut off values";
+ convOptions[1] = "convert to float";
+ convDiag.addChoice("Please select an conversion option:", convOptions, convOptions[0]);
+ convDiag.showDialog();
+ if (convDiag.wasCanceled())
+ return;
+ unsignedConvSelec = convDiag.getNextChoiceIndex();
+ wholeDataset = convertToUnsigned(wholeDataset, unsignedConvSelec);
+ }
+
+ long stackSize = extent[2] * extent[3];
+ long singleVolumeSize = extent[1] * stackSize;
+
+ for (int volIDX = 0; volIDX < extent[0]; ++volIDX) {
+ if ((volIDX % progressDivisor) == 0)
+ IJ.showProgress((float) volIDX / (float) extent[0]);
+ // start[0] = volIDX;
+
+ for (int lev = 0; lev < extent[1]; ++lev) {
+ // select hyperslab for lev
+ // start[1] = lev;
+ // Object slice = var.read();
+ long startIdx = (volIDX * singleVolumeSize) + (lev * stackSize);
+ long numElements = stackSize;
+
+ if (wholeDataset instanceof byte[]) {
+ byte[] tmp = (byte[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.addSlice(null, tmp);
+ } else if (wholeDataset instanceof short[]) {
+ short[] tmp = (short[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.addSlice(null, tmp);
+ } else if (wholeDataset instanceof int[]) {
+ int[] tmp = (int[]) extractSubarray(wholeDataset, startIdx, numElements);
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ stack.addSlice(null, convertInt32ToFloat(tmp));
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ stack.addSlice(null, convertInt32ToShort(tmp));
+ }
+ } else if (wholeDataset instanceof long[]) {
+ long[] tmp = (long[]) extractSubarray(wholeDataset, startIdx, numElements);
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ stack.addSlice(null, convertInt64ToFloat(tmp));
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ stack.addSlice(null, convertInt64ToShort(tmp));
+ }
+ } else if (wholeDataset instanceof float[]) {
+ float[] tmp = (float[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.addSlice(null, tmp);
+ } else if (wholeDataset instanceof double[]) {
+ float[] tmp = convertDoubleToFloat((double[]) extractSubarray(wholeDataset, startIdx, numElements));
+ stack.addSlice(null, tmp);
+ } else {
+ // try to put pixels on stack
+ stack.addSlice(null, extractSubarray(wholeDataset, startIdx, numElements));
+ }
+ }
+ }
+
+ IJ.showProgress(1.f);
+ ImagePlus imp = new ImagePlus(directory + name + " " + var.getName(), stack);
+ // new for hyperstack
+ int nChannels = 1;
+ int nSlices = (int) extent[1];
+ int nFrames = (int) extent[0];
+ Integer nFramesI = new Integer(nFrames);
+ Integer nSlicesI = new Integer(nSlices);
+ System.out.println("nFrames: " + nFramesI.toString());
+ System.out.println("nSlices: " + nSlicesI.toString());
+
+ Integer myStackSize = new Integer(stack.getSize());
+ System.out.println("stackSize: " + myStackSize.toString());
+
+ imp.setDimensions(nChannels, nSlices, nFrames);
+ imp.setOpenAsHyperStack(true);
+
+ imp.getCalibration().pixelDepth = elem_sizes[0];
+ imp.getCalibration().pixelHeight = elem_sizes[1];
+ imp.getCalibration().pixelWidth = elem_sizes[2];
+ // getMinMax();
+ // imp.setDisplayRange(0,229);
+ imp.resetDisplayRange();
+ imp.show();
+ }
+ } else if (rank == 3 && extent[2] == 3) {
+ System.out.println("This is an rgb image");
+ // create a new image stack and fill in the data
+ ImageStack stack = new ImageStack((int) extent[1], (int) extent[0]);
+
+ long[] selected = var.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ selected[0] = extent[0];
+ selected[1] = extent[1];
+ selected[2] = extent[2];
+ Object slice = var.read();
+ // check for unsigned datatype
+ int unsignedConvSelec = 0;
+ Datatype dType = var.getDatatype();
+ boolean isSigned16Bit = !dType.isUnsigned() && (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && (dType.getDatatypeSize() == 2);
+ if (isSigned16Bit) {
+ GenericDialog convDiag = new GenericDialog("Unsigend to signed conversion");
+ convDiag.addMessage("Detected unsigned datatype, which " + "is not supported.");
+ String[] convOptions = new String[2];
+ convOptions[0] = "cut off values";
+ convOptions[1] = "convert to float";
+ convDiag.addChoice("Please select an conversion option:", convOptions, convOptions[0]);
+ convDiag.showDialog();
+ if (convDiag.wasCanceled())
+ return;
+ unsignedConvSelec = convDiag.getNextChoiceIndex();
+ slice = convertToUnsigned(slice, unsignedConvSelec);
+ }
+
+ int size = (int) (extent[1] * extent[0]);
+
+ // ugly but working: copy pixel by pixel
+ if (slice instanceof byte[]) {
+ byte[] tmp = (byte[]) slice;
+ byte[] rChannel = new byte[size];
+ byte[] gChannel = new byte[size];
+ byte[] bChannel = new byte[size];
+ for (int row = 0; row < extent[0]; ++row) {
+ for (int col = 0; col < extent[1]; ++col) {
+ int offsetRGB = (row * (int) extent[1] * 3) + (col * 3);
+ int offset = (row * (int) extent[1]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof short[]) {
+ short[] tmp = (short[]) slice;
+ short[] rChannel = new short[size];
+ short[] gChannel = new short[size];
+ short[] bChannel = new short[size];
+ for (int row = 0; row < extent[0]; ++row) {
+ for (int col = 0; col < extent[1]; ++col) {
+ int offsetRGB = (row * (int) extent[1] * 3) + (col * 3);
+ int offset = (row * (int) extent[1]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof int[]) {
+ int[] tmp = (int[]) slice;
+ int[] rChannel = new int[size];
+ int[] gChannel = new int[size];
+ int[] bChannel = new int[size];
+ for (int row = 0; row < extent[0]; ++row) {
+ for (int col = 0; col < extent[1]; ++col) {
+ int offsetRGB = (row * (int) extent[1] * 3) + (col * 3);
+ int offset = (row * (int) extent[1]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof long[]) {
+ long[] tmp = (long[]) slice;
+ long[] rChannel = new long[size];
+ long[] gChannel = new long[size];
+ long[] bChannel = new long[size];
+ for (int row = 0; row < extent[0]; ++row) {
+ for (int col = 0; col < extent[1]; ++col) {
+ int offsetRGB = (row * (int) extent[1] * 3) + (col * 3);
+ int offset = (row * (int) extent[1]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof float[]) {
+ float[] tmp = (float[]) slice;
+ float[] rChannel = new float[size];
+ float[] gChannel = new float[size];
+ float[] bChannel = new float[size];
+ for (int row = 0; row < extent[0]; ++row) {
+ for (int col = 0; col < extent[1]; ++col) {
+ int offsetRGB = (row * (int) extent[1] * 3) + (col * 3);
+ int offset = (row * (int) extent[1]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ } else if (slice instanceof double[]) {
+ double[] tmp = (double[]) slice;
+ double[] rChannel = new double[size];
+ double[] gChannel = new double[size];
+ double[] bChannel = new double[size];
+ for (int row = 0; row < extent[0]; ++row) {
+ for (int col = 0; col < extent[1]; ++col) {
+ int offsetRGB = (row * (int) extent[1] * 3) + (col * 3);
+ int offset = (row * (int) extent[1]) + col;
+ rChannel[offset] = tmp[offsetRGB + 0];
+ gChannel[offset] = tmp[offsetRGB + 1];
+ bChannel[offset] = tmp[offsetRGB + 2];
+ }
+ }
+ stack.addSlice(null, rChannel);
+ stack.addSlice(null, gChannel);
+ stack.addSlice(null, bChannel);
+ }
+ IJ.showProgress(1.f);
+ ImagePlus imp = new ImagePlus(directory + name + " " + var.getName(), stack);
+ // new for hyperstack
+ int nChannels = 3;
+ int nSlices = 1;
+ int nFrames = 1;
+ imp.setDimensions(nChannels, nSlices, nFrames);
+ imp = new CompositeImage(imp, CompositeImage.COMPOSITE);
+ imp.setOpenAsHyperStack(true);
+
+ imp.getCalibration().pixelDepth = elem_sizes[0];
+ imp.getCalibration().pixelHeight = elem_sizes[1];
+ imp.getCalibration().pixelWidth = elem_sizes[2];
+ // getMinMax();
+ imp.resetDisplayRange();
+ imp.show();
+ imp.updateStatusbarValue();
+ } else if (rank == 3) {
+ System.out.println("Rank is 3");
+
+ // create a new image stack and fill in the data
+ ImageStack stack = new ImageStack((int) extent[2], (int) extent[1]);
+
+ long[] selected = var.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ selected[0] = extent[0];
+ selected[1] = extent[1];
+ selected[2] = extent[2];
+ Object wholeDataset = var.read();
+ // check for unsigned datatype
+ int unsignedConvSelec = 0;
+ Datatype dType = var.getDatatype();
+ boolean isSigned16Bit = !dType.isUnsigned() && (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && (dType.getDatatypeSize() == 2);
+
+ if (isSigned16Bit) {
+ GenericDialog convDiag = new GenericDialog("Unsigend to signed conversion");
+ convDiag.addMessage("Detected unsigned datatype, which " + "is not supported.");
+ String[] convOptions = new String[2];
+ convOptions[0] = "cut off values";
+ convOptions[1] = "convert to float";
+ convDiag.addChoice("Please select an conversion option:", convOptions, convOptions[0]);
+ convDiag.showDialog();
+ if (convDiag.wasCanceled())
+ return;
+ unsignedConvSelec = convDiag.getNextChoiceIndex();
+ wholeDataset = convertToUnsigned(wholeDataset, unsignedConvSelec);
+ }
+
+ long stackSize = extent[1] * extent[2];
+
+ for (int lev = 0; lev < extent[0]; ++lev) {
+ if ((lev % progressDivisor) == 0)
+ IJ.showProgress((float) lev / (float) extent[0]);
+ // select hyperslab for lev
+ // start[0] = lev;
+ // Object slice = var.read();
+
+ long startIdx = lev * stackSize;
+ long numElements = stackSize;
+ if (wholeDataset instanceof byte[]) {
+ byte[] tmp = (byte[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.addSlice(null, tmp);
+ } else if (wholeDataset instanceof short[]) {
+ short[] tmp = (short[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.addSlice(null, tmp);
+ } else if (wholeDataset instanceof int[]) {
+ int[] tmp = (int[]) extractSubarray(wholeDataset, startIdx, numElements);
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ stack.addSlice(null, convertInt32ToFloat(tmp));
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ stack.addSlice(null, convertInt32ToShort(tmp));
+ }
+ } else if (wholeDataset instanceof long[]) {
+ long[] tmp = (long[]) extractSubarray(wholeDataset, startIdx, numElements);
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ stack.addSlice(null, convertInt64ToFloat(tmp));
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ stack.addSlice(null, convertInt64ToShort(tmp));
+ }
+ } else if (wholeDataset instanceof float[]) {
+ float[] tmp = (float[]) extractSubarray(wholeDataset, startIdx, numElements);
+ stack.addSlice(null, tmp);
+ } else if (wholeDataset instanceof double[]) {
+ float[] tmp = convertDoubleToFloat((double[]) extractSubarray(wholeDataset, startIdx, numElements));
+ stack.addSlice(null, tmp);
+ } else {
+ // try to put pixels on stack
+ stack.addSlice(null, extractSubarray(wholeDataset, startIdx, numElements));
+ }
+ }
+ IJ.showProgress(1.f);
+ ImagePlus imp = new ImagePlus(directory + name + " " + var.getName(), stack);
+ imp.getCalibration().pixelDepth = elem_sizes[0];
+ imp.getCalibration().pixelHeight = elem_sizes[1];
+ imp.getCalibration().pixelWidth = elem_sizes[2];
+ // getMinMax();
+ imp.resetDisplayRange();
+ imp.show();
+ imp.updateStatusbarValue();
+ } else if (rank == 2) {
+
+ // check if we have an unsupported datatype
+ if (datatype.getDatatypeClass() == Datatype.CLASS_INTEGER && (datatype.getDatatypeSize() == 4 || datatype.getDatatypeSize() == 8)) {
+ System.out.println("Datatype not supported by ImageJ");
+ GenericDialog typeSelDiag = new GenericDialog("Datatype Selection");
+ typeSelDiag.addMessage("The datatype `" + datatype.getDatatypeDescription() + "` is not supported by ImageJ.\n\n");
+ typeSelDiag.addMessage("Please select your wanted datatype.\n");
+ String[] choices = new String[2];
+ choices[0] = "float";
+ choices[1] = "short";
+ typeSelDiag.addChoice(" Possible types are", choices, "float");
+ typeSelDiag.showDialog();
+
+ if (typeSelDiag.wasCanceled()) {
+ return;
+ }
+ int selection = typeSelDiag.getNextChoiceIndex();
+ if (selection == 0) {
+ System.out.println("float selected");
+ datatypeIfUnsupported = new H5Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, -1);
+ }
+ if (selection == 1) {
+ System.out.println("short selected");
+ int typeSizeInByte = 2;
+ datatypeIfUnsupported = new H5Datatype(Datatype.CLASS_INTEGER, typeSizeInByte, Datatype.NATIVE, -1);
+ }
+ }
+ IJ.showProgress(0.f);
+ ImageStack stack = new ImageStack((int) extent[1], (int) extent[0]);
+ Object slice = var.read();
+ // check for unsigned datatype
+ int unsignedConvSelec = 0;
+ Datatype dType = var.getDatatype();
+ boolean isSigned16Bit = !dType.isUnsigned() && (dType.getDatatypeClass() == Datatype.CLASS_INTEGER) && (dType.getDatatypeSize() == 2);
+ if (isSigned16Bit) {
+ GenericDialog convDiag = new GenericDialog("Unsigend to signed conversion");
+ convDiag.addMessage("Detected unsigned datatype, which " + "is not supported.");
+ String[] convOptions = new String[2];
+ convOptions[0] = "cut off values";
+ convOptions[1] = "convert to float";
+ convDiag.addChoice("Please select an conversion option:", convOptions, convOptions[0]);
+ convDiag.showDialog();
+ if (convDiag.wasCanceled())
+ return;
+ unsignedConvSelec = convDiag.getNextChoiceIndex();
+ slice = convertToUnsigned(slice, unsignedConvSelec);
+ }
+
+ if (slice instanceof byte[]) {
+ byte[] tmp = (byte[]) slice;
+ stack.addSlice(null, tmp);
+ } else if (slice instanceof short[]) {
+ short[] tmp = (short[]) slice;
+ stack.addSlice(null, tmp);
+ } else if (slice instanceof int[]) {
+ int[] tmp = (int[]) slice;
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ stack.addSlice(null, convertInt32ToFloat(tmp));
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ stack.addSlice(null, convertInt32ToShort(tmp));
+ }
+ } else if (slice instanceof long[]) {
+ long[] tmp = (long[]) slice;
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_FLOAT) {
+ stack.addSlice(null, convertInt64ToFloat(tmp));
+ }
+ if (datatypeIfUnsupported.getDatatypeClass() == Datatype.CLASS_INTEGER) {
+ stack.addSlice(null, convertInt64ToShort(tmp));
+ }
+ } else if (slice instanceof float[]) {
+ float[] tmp = (float[]) slice;
+ stack.addSlice(null, tmp);
+ } else if (slice instanceof double[]) {
+ float[] tmp = convertDoubleToFloat((double[]) slice);
+
+ stack.addSlice(null, tmp);
+ } else {
+ // try to put pixels on stack
+ stack.addSlice(null, slice);
+ }
+ IJ.showProgress(1.f);
+ ImagePlus imp = new ImagePlus(directory + name + " " + var.getName(), stack);
+ imp.getProcessor().resetMinAndMax();
+ imp.show();
+
+ ImageProcessor ips = imp.getProcessor();
+
+ double imgMax = ips.getMax();
+ double imgMin = ips.getMin();
+
+ System.out.println(" Min = " + imgMin + ", Max = " + imgMax);
+ ips.setMinAndMax(imgMin, imgMax);
+ imp.updateAndDraw();
+ imp.show();
+ imp.updateStatusbarValue();
+ } else {
+ System.err.println(" Error: Variable Dimensions " + rank + " not supported (yet).");
+ IJ.showStatus("Variable Dimension " + rank + " not supported");
+ }
+ }
+ }
+
+ } catch (java.io.IOException err) {
+ System.err.println("Error while opening '" + directory + name + "'");
+ System.err.println(err);
+ IJ.showStatus("Error opening file.");
+ } catch (HDFException err) {
+ System.err.println("Error while opening '" + directory + name + "'");
+ System.err.println(err);
+ IJ.showStatus("Error opening file.");
+ } catch (HDF5Exception err) {
+ System.err.println("Error while opening '" + directory + name + "'");
+ System.err.println(err);
+ IJ.showStatus("Error opening file.");
+ } catch (Exception err) {
+ System.err.println("Error while opening '" + directory + name + "'");
+ System.err.println(err);
+ IJ.showStatus("Error opening file.");
+ } catch (OutOfMemoryError o) {
+ IJ.outOfMemory("Load HDF5");
+ }
+ // make sure the file is closed after working with it
+ // FIXME: should happen in catch-part, too!
+ try {
+ if (inFile != null)
+ inFile.close();
+ } catch (HDF5Exception err) {
+ System.err.println("Error while closing '" + directory + name + "'");
+ System.err.println(err);
+ IJ.showStatus("Error closing file.");
+ }
+
+ IJ.showProgress(1.0);
+ }
+
+ // int byteToUnsignedByte(int n)
+ // {
+ // if (n < 0)
+ // return (256 + n);
+ // return n;
+ // }
+
+ private int progressSteps = 50;
+
+ /*-----------------------------------------------------------------------
+ * helpers for hdf5 library
+ *-----------------------------------------------------------------------*/
+ private static List getDataSetList(Group g, List datasets) throws Exception {
+ if (g == null){
+ return datasets;
+ }
+
+ List members = g.getMemberList();
+ for (HObject obj: members) {
+ if (obj instanceof Dataset) {
+ ((Dataset) obj).init();
+ datasets.add((Dataset) obj);
+ // System.out.println(obj.getFullName());
+ } else if (obj instanceof Group) {
+ datasets = (getDataSetList((Group) obj, datasets));
+ }
+ }
+ return datasets;
+ }
+
+ private static List getAttrList(HObject ds) throws Exception {
+ if (ds == null)
+ return null;
+
+ List attributes = new ArrayList();
+ List> members = ds.getMetadata();
+ int n = members.size();
+ Metadata obj = null;
+ for (int i = 0; i < n; i++) {
+ obj = (Metadata) members.get(i);
+ if (obj instanceof Attribute) {
+ try {
+ System.out.println(((Attribute) obj).getName());
+ attributes.add((Attribute) obj);
+ } catch (java.lang.UnsupportedOperationException e) {
+ System.out.println("Caught UnsupportedOperationException datasets2.add((Dataset) obj)");
+ System.out.println(e.getMessage());
+ }
+ }
+ }
+ return attributes;
+ }
+
+ private static Attribute getAttribute(Dataset ds, String attrName) throws Exception {
+ List attrList = getAttrList((HObject) ds);
+ Iterator attrIter = attrList.iterator();
+
+ while (attrIter.hasNext()) {
+ Attribute attr = attrIter.next();
+ if (attr.getName().equals(attrName)) {
+ return attr;
+ }
+ }
+ return null;
+ }
+
+ private static Attribute getAttribute(HObject ds, String attrName) throws Exception {
+ List attrList = getAttrList(ds);
+ Iterator attrIter = attrList.iterator();
+
+ while (attrIter.hasNext()) {
+ Attribute attr = attrIter.next();
+ System.out.println(attr.getName());
+ if (attr.getName().equals(attrName)) {
+ return attr;
+ }
+ }
+ return null;
+ }
+
+ /*-----------------------------------------------------------------------
+ * minmax of array
+ *-----------------------------------------------------------------------*/
+ private double[] getMinMax(Object data, long stackSize) {
+ double[] minmax = new double[2];
+
+ if (data instanceof byte[]) {
+ byte[] tmp = (byte[]) data;
+ minmax[0] = tmp[0];
+ minmax[1] = tmp[0];
+ for (int i = 1; i < stackSize; i++) {
+ double val = (double) tmp[i];
+ // we only support unsigned
+ if (tmp[i] < 0)
+ val = (float) Byte.MAX_VALUE - (float) Byte.MIN_VALUE + (float) tmp[i] + 1;
+
+ if (val < minmax[0])
+ minmax[0] = val;
+ if (val > minmax[1])
+ minmax[1] = val;
+ }
+ } else if (data instanceof short[]) {
+ short[] tmp = (short[]) data;
+ minmax[0] = tmp[0];
+ minmax[1] = tmp[0];
+ for (int i = 1; i < stackSize; i++) {
+ double val = (double) tmp[i];
+ // we only support unsigned
+ if (tmp[i] < 0)
+ val = (float) Short.MAX_VALUE - (float) Short.MIN_VALUE + (float) tmp[i] + 1;
+
+ if (val < minmax[0])
+ minmax[0] = val;
+ if (val > minmax[1])
+ minmax[1] = val;
+ }
+ } else if (data instanceof int[]) {
+ int[] tmp = (int[]) data;
+ minmax[0] = tmp[0];
+ minmax[1] = tmp[0];
+ for (int i = 1; i < stackSize; i++) {
+ if (tmp[i] < minmax[0])
+ minmax[0] = tmp[i];
+ if (tmp[i] > minmax[1])
+ minmax[1] = tmp[i];
+ }
+ } else if (data instanceof long[]) {
+ long[] tmp = (long[]) data;
+ minmax[0] = tmp[0];
+ minmax[1] = tmp[0];
+ for (int i = 1; i < stackSize; i++) {
+ if (tmp[i] < minmax[0])
+ minmax[0] = tmp[i];
+ if (tmp[i] > minmax[1])
+ minmax[1] = tmp[i];
+ }
+ } else if (data instanceof float[]) {
+ float[] tmp = (float[]) data;
+ minmax[0] = tmp[0];
+ minmax[1] = tmp[0];
+ for (int i = 1; i < stackSize; i++) {
+ if (tmp[i] < minmax[0])
+ minmax[0] = tmp[i];
+ if (tmp[i] > minmax[1])
+ minmax[1] = tmp[i];
+ }
+ } else if (data instanceof double[]) {
+ double[] tmp = (double[]) data;
+ minmax[0] = tmp[0];
+ minmax[1] = tmp[0];
+ for (int i = 1; i < stackSize; i++) {
+ if (tmp[i] < minmax[0])
+ minmax[0] = tmp[i];
+ if (tmp[i] > minmax[1])
+ minmax[1] = tmp[i];
+ }
+ }
+ System.out.println("min: " + minmax[0] + ", max: " + minmax[1]);
+ return minmax;
+ }
+
+ /*-----------------------------------------------------------------------
+ * converter functions
+ *-----------------------------------------------------------------------*/
+ private float[] convertDoubleToFloat(double[] dataIn) {
+ float[] dataOut = new float[dataIn.length];
+ for (int index = 0; index < dataIn.length; index++) {
+ dataOut[index] = (float) dataIn[index];
+ }
+ return dataOut;
+ }
+
+ private float[] convertInt32ToFloat(int[] dataIn) {
+ float[] dataOut = new float[dataIn.length];
+ for (int index = 0; index < dataIn.length; index++) {
+ dataOut[index] = dataIn[index];
+ }
+ return dataOut;
+ }
+
+ private short[] convertInt32ToShort(int[] dataIn) {
+ short[] dataOut = new short[dataIn.length];
+ for (int index = 0; index < dataIn.length; index++) {
+ dataOut[index] = (short) dataIn[index];
+ }
+ return dataOut;
+ }
+
+ private float[] convertInt64ToFloat(long[] dataIn) {
+ float[] dataOut = new float[dataIn.length];
+ for (int index = 0; index < dataIn.length; index++) {
+ dataOut[index] = dataIn[index];
+ }
+ return dataOut;
+ }
+
+ private short[] convertInt64ToShort(long[] dataIn) {
+ short[] dataOut = new short[dataIn.length];
+ for (int index = 0; index < dataIn.length; index++) {
+ dataOut[index] = (short) dataIn[index];
+ }
+ return dataOut;
+ }
+
+ private Object convertToUnsigned(Object dataIn, int unsignedConvSelec) {
+ Object dataOut = null;
+ if (unsignedConvSelec == 0) {
+ // cut off values
+ if (dataIn instanceof short[]) {
+ short[] tmp = (short[]) dataIn;
+ for (int i = 0; i < tmp.length; i++)
+ if (tmp[i] < 0)
+ tmp[i] = 0;
+ dataOut = (Object) tmp;
+ }
+ } else if (unsignedConvSelec == 1) {
+ // convert to float
+ if (dataIn instanceof short[]) {
+ System.out.println("Converting to float");
+ short[] tmpIn = (short[]) dataIn;
+ float[] tmp = new float[tmpIn.length];
+ for (int i = 0; i < tmp.length; i++)
+ tmp[i] = (float) tmpIn[i];
+ dataOut = (Object) tmp;
+ }
+ }
+ return dataOut;
+ }
+
+ /*-----------------------------------------------------------------------
+ * extract subarrays
+ *-----------------------------------------------------------------------*/
+ Object extractSubarray(Object data, long startIdx, long numElements) {
+ Object subarray = null;
+
+ if (data instanceof byte[]) {
+ subarray = new byte[(int) numElements];
+ for (long idx = startIdx; idx < startIdx + numElements; idx++) {
+ ((byte[]) subarray)[(int) (idx - startIdx)] = ((byte[]) data)[(int) (idx)];
+ }
+ } else if (data instanceof short[]) {
+ subarray = new short[(int) numElements];
+ for (long idx = startIdx; idx < startIdx + numElements; idx++) {
+ ((short[]) subarray)[(int) (idx - startIdx)] = ((short[]) data)[(int) (idx)];
+ }
+ } else if (data instanceof int[]) {
+ subarray = new int[(int) numElements];
+ for (long idx = startIdx; idx < startIdx + numElements; idx++) {
+ ((int[]) subarray)[(int) (idx - startIdx)] = ((int[]) data)[(int) (idx)];
+ }
+ } else if (data instanceof long[]) {
+ subarray = new long[(int) numElements];
+ for (long idx = startIdx; idx < startIdx + numElements; idx++) {
+ ((long[]) subarray)[(int) (idx - startIdx)] = ((long[]) data)[(int) (idx)];
+ }
+ } else if (data instanceof float[]) {
+ subarray = new float[(int) numElements];
+ for (long idx = startIdx; idx < startIdx + numElements; idx++) {
+ ((float[]) subarray)[(int) (idx - startIdx)] = ((float[]) data)[(int) (idx)];
+ }
+ } else if (data instanceof double[]) {
+ subarray = new double[(int) numElements];
+ for (long idx = startIdx; idx < startIdx + numElements; idx++) {
+ ((double[]) subarray)[(int) (idx - startIdx)] = ((double[]) data)[(int) (idx)];
+ }
+ }
+ return subarray;
+ }
+
+ /** Adds AWT scroll bars to the given container. */
+ public static void addScrollBars(Container pane) {
+ GridBagLayout layout = (GridBagLayout) pane.getLayout();
+
+ // extract components
+ int count = pane.getComponentCount();
+ Component[] c = new Component[count];
+ GridBagConstraints[] gbc = new GridBagConstraints[count];
+ for (int i = 0; i < count; i++) {
+ c[i] = pane.getComponent(i);
+ gbc[i] = layout.getConstraints(c[i]);
+ }
+
+ // clear components
+ pane.removeAll();
+ layout.invalidateLayout(pane);
+
+ // create new container panel
+ Panel newPane = new Panel();
+ GridBagLayout newLayout = new GridBagLayout();
+ newPane.setLayout(newLayout);
+ for (int i = 0; i < count; i++) {
+ newLayout.setConstraints(c[i], gbc[i]);
+ newPane.add(c[i]);
+ }
+
+ // HACK - get preferred size for container panel
+ // NB: don't know a better way:
+ // - newPane.getPreferredSize() doesn't work
+ // - newLayout.preferredLayoutSize(newPane) doesn't work
+ Frame f = new Frame();
+ f.setLayout(new BorderLayout());
+ f.add(newPane, BorderLayout.WEST);
+ f.pack();
+ final Dimension size = newPane.getSize();
+ f.remove(newPane);
+ f.dispose();
+
+ // compute best size for scrollable viewport
+ size.width += 15;
+ size.height += 15;
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ int maxWidth = 3 * screen.width / 4;
+ int maxHeight = 3 * screen.height / 4;
+ if (size.width > maxWidth)
+ size.width = maxWidth;
+ if (size.height > maxHeight)
+ size.height = maxHeight;
+
+ // create scroll pane
+ ScrollPane scroll = new ScrollPane() {
+ private static final long serialVersionUID = 1L;
+ public Dimension getPreferredSize() {
+ return size;
+ }
+ };
+ scroll.add(newPane);
+
+ // add scroll pane to original container
+ GridBagConstraints constraints = new GridBagConstraints();
+ constraints.anchor = GridBagConstraints.WEST;
+ constraints.fill = GridBagConstraints.BOTH;
+ constraints.weightx = 1.0;
+ constraints.weighty = 1.0;
+ layout.setConstraints(scroll, constraints);
+ pane.add(scroll);
+ }
}
-
diff --git a/src/main/java/ch/psi/imagej/hdf5/HDF5_Writer_.java b/src/main/java/ch/psi/imagej/hdf5/HDF5_Writer_.java
index e839829..428ce76 100644
--- a/src/main/java/ch/psi/imagej/hdf5/HDF5_Writer_.java
+++ b/src/main/java/ch/psi/imagej/hdf5/HDF5_Writer_.java
@@ -1,22 +1,24 @@
package ch.psi.imagej.hdf5;
-/* =========================================================================
- *
- * Copyright 2011 Matthias Schlachter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *=========================================================================*/
+/*
+ * =========================================================================
+ *
+ * Copyright 2011 Matthias Schlachter
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * =========================================================================
+ */
import ij.*;
import ij.io.*;
@@ -33,839 +35,646 @@ import ncsa.hdf.object.*; // the common object package
import ncsa.hdf.object.h5.*; // the HDF5 implementation
import ncsa.hdf.hdf5lib.exceptions.HDF5Exception;
-public class HDF5_Writer_ implements PlugInFilter
-{
- private Boolean _batchMode = false;
- private String[] _batchVarNames = null;
- private String _batchFileName = null;
- public int setup(String arg, ImagePlus imp)
- {
- if (arg.equals("about"))
- {
- showAbout();
- return DONE;
- }
- // FIXME: set DOES_xx for image type here:
- // currently RGB-Types are still missing
- // see
- // http://rsb.info.nih.gov/ij/developer/api/ij/plugin/filter/PlugInFilter.html
- return DOES_8G + DOES_16 + DOES_32 + DOES_RGB
- + NO_CHANGES;
- }
+public class HDF5_Writer_ implements PlugInFilter {
+ private Boolean _batchMode = false;
+ private String _batchFileName = null;
- public void setToBatchMode(String filename, String [] varnames)
- {
- _batchMode = true;
- _batchFileName = filename;
- _batchVarNames = varnames;
- }
+ public int setup(String arg, ImagePlus imp) {
+ if (arg.equals("about")) {
+ showAbout();
+ return DONE;
+ }
+ // FIXME: set DOES_xx for image type here:
+ // currently RGB-Types are still missing
+ // see
+ // http://rsb.info.nih.gov/ij/developer/api/ij/plugin/filter/PlugInFilter.html
+ return DOES_8G + DOES_16 + DOES_32 + DOES_RGB + NO_CHANGES;
+ }
- public void run(ImageProcessor ip)
- {
- int[] wList = WindowManager.getIDList();
-
- if (wList == null)
- {
- IJ.error("No windows are open.");
- return;
- }
+ public void setToBatchMode(String filename, String[] varnames) {
+ _batchMode = true;
+ _batchFileName = filename;
+ }
- String filename = null;
- if(_batchMode)
- {
- filename = _batchFileName;
- }
- else
- {
- SaveDialog sd = new SaveDialog("Save HDF5 ...", "", ".h5");
- String directory = sd.getDirectory();
- String name = sd.getFileName();
- filename = directory + name;
+ public void run(ImageProcessor ip) {
+ int[] wList = WindowManager.getIDList();
- if (name == null)
- return;
- if (name == "")
- return;
- }
-
-
- // Retrieve an instance of the implementing class for the HDF5 format
- FileFormat fileFormat =
- FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5);
+ if (wList == null) {
+ IJ.error("No windows are open.");
+ return;
+ }
- // If the implementing class wasn't found, it's an error.
- if (fileFormat == null)
- {
- System.err.println("Cannot find HDF5 FileFormat.");
- return;
- }
+ String filename = null;
+ if (_batchMode) {
+ filename = _batchFileName;
+ } else {
+ SaveDialog sd = new SaveDialog("Save HDF5 ...", "", ".h5");
+ String directory = sd.getDirectory();
+ String name = sd.getFileName();
+ filename = directory + name;
- String[] varNames = null;
- if(_batchMode)
- {
- varNames = _batchVarNames;
- }
+ if (name == null)
+ return;
+ if (name == "")
+ return;
+ }
- ImagePlus imp = WindowManager.getCurrentImage();
+ // Retrieve an instance of the implementing class for the HDF5 format
+ FileFormat fileFormat = FileFormat.getFileFormat(FileFormat.FILE_TYPE_HDF5);
- GenericDialog gd = null;
- gd = new GenericDialog("Variable Name Selection");
-
- // check for hyperstack
- if(imp.getOpenAsHyperStack() || imp.isHyperStack())
- {
- System.out.println("This is a hyperstack");
- boolean splitChannels = true;
- gd.addCheckbox("Split frames and channels",splitChannels);
- gd.addStringField(imp.getTitle(), "/t$T/channel$C");
- String title = imp.getTitle();
- int nDims = imp.getNDimensions();
- int nFrames = imp.getNFrames();
- int nChannels = imp.getNChannels();
- int nLevs = imp.getNSlices();
- int nRows = imp.getHeight();
- int nCols = imp.getWidth();
- boolean isComposite = imp.isComposite() ;
- System.out.println("isComposite: "+Boolean.toString(isComposite));
- System.out.println("Saving image \""+title+"\"");
- System.out.println("nDims: "+Integer.toString(nDims));
- System.out.println("nFrames: "+Integer.toString(nFrames));
- System.out.println("nChannels: "+Integer.toString(nChannels));
- System.out.println("nSlices: "+Integer.toString(nLevs));
- System.out.println("nRows: "+Integer.toString(nRows));
- System.out.println("nCols: "+Integer.toString(nCols));
- gd.showDialog();
- if (gd.wasCanceled())
- {
- IJ.error("Plugin canceled!");
- return;
- }
- splitChannels = gd.getNextBoolean();
- String formatString = gd.getNextString();
- System.out.println("formatString: "+formatString);
- System.out.println("Bitdepth: "+ imp.getBitDepth());
- System.out.println("Saving HDF5 File: " + filename);
-
- int imgColorDepth = imp.getBitDepth();
- int imgColorType = imp.getType();
- Datatype type = null;
- if (imgColorType == ImagePlus.GRAY8)
- {
- System.out.println(" bit depth: " + imgColorDepth
- + ", type: GRAY8");
- type = new H5Datatype(Datatype.CLASS_CHAR, Datatype.NATIVE,
- Datatype.NATIVE, Datatype.SIGN_NONE);
- }
- else if (imgColorType == ImagePlus.GRAY16)
- {
- System.out.println(" bit depth: " + imgColorDepth
- + ", type: GRAY16");
- int typeSizeInByte = 2;
- type = new H5Datatype(Datatype.CLASS_INTEGER, typeSizeInByte,
- Datatype.NATIVE, Datatype.SIGN_NONE);
- }
- else if (imgColorType == ImagePlus.GRAY32)
- {
- System.out.println(" bit depth: " + imgColorDepth
- + ", type: GRAY32");
- int typeSizeInByte = 4;
- type = new H5Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE,
- Datatype.NATIVE, -1);
- }
-
- // open the outfile
- H5File outFile = null;
- try
- {
- outFile = (H5File) fileFormat.createFile(filename,
- FileFormat.FILE_CREATE_OPEN);
- if (!outFile.canWrite())
- {
- IJ.error("File `" + filename + "`is readonly!");
- return;
- }
- // open the file
- outFile.open();
-
- if(splitChannels)
- {
- // parse format string
- String[] formatTokens =
- HDF5_GroupedVarnames.
- parseFormatString(formatString,
- "[0-9]+"); // dummy regexp
- long[] channelDims = null;
- if(nLevs>1)
- {
- channelDims = new long[3];
- channelDims[0] = nLevs;
- channelDims[1] = nRows;
- channelDims[2] = nCols;
- }
- else
- {
- channelDims = new long[2];
- channelDims[0] = nRows;
- channelDims[1] = nCols;
- }
- // iterate over frames and channels
- ImageStack stack = imp.getStack();
- for(int f=0;f getAttrList(Dataset ds) throws Exception
- {
- if (ds == null)
- return null;
+ ImagePlus imp = WindowManager.getCurrentImage();
- List attributes = new ArrayList();
- List members = ds.getMetadata();
- int n = members.size();
- Metadata obj = null;
- for (int i = 0; i < n; i++)
- {
- obj = (Metadata) members.get(i);
- if (obj instanceof Attribute)
- {
- try
- {
- System.out.println(((Attribute) obj).getName());
- attributes.add((Attribute) obj);
- }
- catch (java.lang.UnsupportedOperationException e)
- {
- System.out
- .println("Caught UnsupportedOperationException datasets2.add((Dataset) obj)");
- System.out.println(e.getMessage());
- }
- }
- }
- return attributes;
- }
+ GenericDialog gd = null;
+ gd = new GenericDialog("Variable Name Selection");
- private static Attribute
- getAttribute(Dataset ds, String attrName) throws Exception
- {
- List attrList = getAttrList(ds);
- Iterator attrIter = attrList.iterator();
+ // check for hyperstack
+ if (imp.getOpenAsHyperStack() || imp.isHyperStack()) {
+ System.out.println("This is a hyperstack");
+ boolean splitChannels = true;
+ gd.addCheckbox("Split frames and channels", splitChannels);
+ gd.addStringField(imp.getTitle(), "/t$T/channel$C");
+ String title = imp.getTitle();
+ int nDims = imp.getNDimensions();
+ int nFrames = imp.getNFrames();
+ int nChannels = imp.getNChannels();
+ int nLevs = imp.getNSlices();
+ int nRows = imp.getHeight();
+ int nCols = imp.getWidth();
+ boolean isComposite = imp.isComposite();
+ System.out.println("isComposite: " + Boolean.toString(isComposite));
+ System.out.println("Saving image \"" + title + "\"");
+ System.out.println("nDims: " + Integer.toString(nDims));
+ System.out.println("nFrames: " + Integer.toString(nFrames));
+ System.out.println("nChannels: " + Integer.toString(nChannels));
+ System.out.println("nSlices: " + Integer.toString(nLevs));
+ System.out.println("nRows: " + Integer.toString(nRows));
+ System.out.println("nCols: " + Integer.toString(nCols));
+ gd.showDialog();
+ if (gd.wasCanceled()) {
+ IJ.error("Plugin canceled!");
+ return;
+ }
+ splitChannels = gd.getNextBoolean();
+ String formatString = gd.getNextString();
+ System.out.println("formatString: " + formatString);
+ System.out.println("Bitdepth: " + imp.getBitDepth());
+ System.out.println("Saving HDF5 File: " + filename);
- while (attrIter.hasNext())
- {
- Attribute attr = attrIter.next();
- if (attr.getName().equals(attrName))
- {
- return attr;
- }
- }
- return null;
- }
-
- private Object computeRgbSlice(Object pixels)
- {
- byte rgbslice[];
- int size = ((int[])pixels).length;
- rgbslice = new byte[size*3];
- for(int i=0;i> 16;
- int green= (((int[]) pixels)[i] & 0x00ff00) >> 8;
- int blue= ((int[]) pixels)[i] & 0x0000ff;
- rgbslice[3*i + 0] = (byte) red;
- rgbslice[3*i + 1] = (byte) green;
- rgbslice[3*i + 2] =(byte) blue;
- }
- return rgbslice;
- }
+ int imgColorDepth = imp.getBitDepth();
+ int imgColorType = imp.getType();
+ Datatype type = null;
+ if (imgColorType == ImagePlus.GRAY8) {
+ System.out.println(" bit depth: " + imgColorDepth + ", type: GRAY8");
+ type = new H5Datatype(Datatype.CLASS_CHAR, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);
+ } else if (imgColorType == ImagePlus.GRAY16) {
+ System.out.println(" bit depth: " + imgColorDepth + ", type: GRAY16");
+ int typeSizeInByte = 2;
+ type = new H5Datatype(Datatype.CLASS_INTEGER, typeSizeInByte, Datatype.NATIVE, Datatype.SIGN_NONE);
+ } else if (imgColorType == ImagePlus.GRAY32) {
+ System.out.println(" bit depth: " + imgColorDepth + ", type: GRAY32");
+// int typeSizeInByte = 4;
+ type = new H5Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, -1);
+ }
- private String makeDataSetName(String[] toks,int frame,int channel)
- {
- String dName =
- toks[0] +
- Integer.toString(frame) +
- toks[1] +
- Integer.toString(channel);
- if(toks.length>2)
- dName = dName + toks[2];
- return dName;
- }
-
-// end of class
+ // open the outfile
+ H5File outFile = null;
+ try {
+ outFile = (H5File) fileFormat.createFile(filename, FileFormat.FILE_CREATE_OPEN);
+ if (!outFile.canWrite()) {
+ IJ.error("File `" + filename + "`is readonly!");
+ return;
+ }
+ // open the file
+ outFile.open();
+
+ if (splitChannels) {
+ // parse format string
+ String[] formatTokens = HDF5_GroupedVarnames.parseFormatString(formatString, "[0-9]+"); // dummy
+ // regexp
+ long[] channelDims = null;
+ if (nLevs > 1) {
+ channelDims = new long[3];
+ channelDims[0] = nLevs;
+ channelDims[1] = nRows;
+ channelDims[2] = nCols;
+ } else {
+ channelDims = new long[2];
+ channelDims[0] = nRows;
+ channelDims[1] = nCols;
+ }
+ // iterate over frames and channels
+ ImageStack stack = imp.getStack();
+ for (int f = 0; f < nFrames; f++) {
+ IJ.showProgress(f, nFrames);
+ for (int c = 0; c < nChannels; c++) {
+ String fullName = makeDataSetName(formatTokens, f, c);
+ String dataSetName = getDataSetDescriptor(fullName);
+ System.out.println("dataset name: " + dataSetName);
+ String groupName = getGroupDescriptor(fullName);
+ System.out.println("group name: " + groupName);
+ // ensure group exists
+ Group group = createGroupRecursive(groupName, null, outFile);
+ // create data set
+ Dataset dataset = null;
+ // select hyperslabs
+ long[] maxdims = channelDims;
+ long[] chunks = null;
+ int gzip = 0; // no compression
+ try {
+ dataset = (Dataset) outFile.get(groupName + "/" + dataSetName);
+ } catch (Exception e) {
+ dataset = null;
+ }
+ if (dataset == null) {
+ try {
+ dataset = outFile.createScalarDS(dataSetName, group, type, channelDims, maxdims, chunks, gzip, null);
+ } catch (Exception err) {
+ IJ.error(err.getMessage());
+ return;
+ }
+ }
+ dataset.init();
+ long[] selected = dataset.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ // write levels
+
+ System.out.println("selected.length: " + Integer.toString(selected.length));
+ System.out.println("channelDims.length: " + Integer.toString(channelDims.length));
+ if (nLevs == 1) {
+ for (int d = 0; d < selected.length; d++) {
+ selected[d] = channelDims[d];
+ }
+ int stackIndex = imp.getStackIndex(c + 1, 1, f + 1);
+ System.out.println("Stackindex: " + Integer.toString(stackIndex));
+ // get raw data
+ Object slice = stack.getPixels(stackIndex);
+ assert (slice != null);
+ // write data
+ try {
+ dataset.write(slice);
+ } catch (Exception e) {
+ IJ.showStatus("Error writing data to file.");
+ }
+ } else {
+ selected[0] = 1;
+ for (int d = 1; d < selected.length; d++) {
+ selected[d] = channelDims[d];
+ }
+ long[] start = dataset.getStartDims(); // the
+ // off
+ // set
+ // of
+ // the selection
+ for (int lvl = 0; lvl < nLevs; ++lvl) {
+ // select hyperslab
+ start[0] = lvl;
+ int stackIndex = imp.getStackIndex(c + 1, lvl + 1, f + 1);
+ // get raw data
+ Object slice = stack.getPixels(stackIndex);
+ // write data
+ try {
+ dataset.write(slice);
+ } catch (Exception e) {
+ IJ.showStatus("Error writing data to file.");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // write one big array
+ }
+ outFile.close();
+ } catch (HDF5Exception err) {
+ IJ.error(err.getMessage());
+ return;
+ } catch (Exception err) {
+ IJ.error(err.getMessage());
+ return;
+ }
+ } else {
+ System.out.println("This is NO hyperstack");
+ // String title = imp.getTitle();
+ // int nDims = imp.getNDimensions();
+ // int nFrames = imp.getNFrames();
+ // int nChannels = imp.getNChannels();
+ // int nLevs = imp.getNSlices();
+ // int nRows = imp.getHeight();
+ // int nCols = imp.getWidth();
+ // boolean isComposite = imp.isComposite() ;
+ // System.out.println("isComposite: "+Boolean.toString(isComposite));
+ // System.out.println("Saving image \""+title+"\"");
+ // System.out.println("nDims: "+Integer.toString(nDims));
+ // System.out.println("nFrames: "+Integer.toString(nFrames));
+ // System.out.println("nChannels: "+Integer.toString(nChannels));
+ // System.out.println("nSlices: "+Integer.toString(nLevs));
+ // System.out.println("nRows: "+Integer.toString(nRows));
+ // System.out.println("nCols: "+Integer.toString(nCols));
+
+ gd.addStringField(imp.getTitle(), "");
+ gd.showDialog();
+ if (gd.wasCanceled()) {
+ IJ.error("Plugin canceled!");
+ return;
+ }
+
+ String varName = gd.getNextString();
+ if (varName == "") {
+ IJ.error("No data set name given. Plugin canceled!");
+ return;
+ }
+ // write data set
+ try {
+ H5File outFile = null;
+ try {
+ outFile = (H5File) fileFormat.createFile(filename, FileFormat.FILE_CREATE_OPEN);
+ if (!outFile.canWrite()) {
+ IJ.error("File `" + filename + "`is readonly!");
+ return;
+ }
+ } catch (HDF5Exception err) {
+ IJ.error(err.getMessage());
+ return;
+ }
+
+ outFile.open();
+ // first create all dimensions and variables
+
+ // Image color depth and color type
+ int imgColorDepth;
+ int imgColorType;
+
+ System.out.println("writing data to variable: " + varName);
+
+ String dataSetName = getDataSetDescriptor(varName);
+ System.out.println("dataset name: " + dataSetName);
+ String groupName = getGroupDescriptor(varName);
+ System.out.println("group name: " + groupName);
+
+ // ensure group exists
+ Group group = createGroupRecursive(groupName, null, outFile);
+
+ int nLevels = imp.getStackSize();
+ int nRows = imp.getHeight();
+ int nCols = imp.getWidth();
+
+ // get image type (bit depth)
+ imgColorDepth = imp.getBitDepth();
+ imgColorType = imp.getType();
+ long[] dims;
+ if (imgColorType == ImagePlus.COLOR_RGB || imgColorType == ImagePlus.COLOR_256) {
+ if (nLevels == 1) {
+ // color image
+ dims = new long[3];
+ dims[0] = nRows;
+ dims[1] = nCols;
+ dims[2] = 3;
+ } else {
+ // color images have 4 dimensions, grey value images
+ // have 3.
+ System.out.println("adding 4 dimensions");
+ dims = new long[4];
+ dims[0] = nLevels;
+ dims[1] = nRows;
+ dims[2] = nCols;
+ dims[3] = 3;
+ }
+ } else {
+ if (nLevels == 1) {
+ // color image
+ dims = new long[2];
+ dims[0] = nRows;
+ dims[1] = nCols;
+ } else {
+ System.out.println("adding 3 dimensions");
+ dims = new long[3];
+ dims[0] = nLevels;
+ dims[1] = nRows;
+ dims[2] = nCols;
+ }
+ }
+
+ // The following is a list of a few example of H5Datatype.
+ //
+ // 1. to create unsigned native integer
+ // H5Datatype type = new H5Dataype(CLASS_INTEGER, NATIVE,
+ // NATIVE, SIGN_NONE);
+ // 2. to create 16-bit signed integer with big endian
+ // H5Datatype type = new H5Dataype(CLASS_INTEGER, 2,
+ // ORDER_BE, NATIVE);
+ // 3. to create native float
+ // H5Datatype type = new H5Dataype(CLASS_FLOAT, NATIVE,
+ // NATIVE, -1);
+ // 4. to create 64-bit double
+ // H5Datatype type = new H5Dataype(CLASS_FLOAT, 8, NATIVE,
+ // -1);
+ // H5Datatype type = new
+ // H5Datatype(H5Datatype.CLASS_INTEGER,
+ // H5Datatype.NATIVE, H5Datatype.NATIVE,
+ // H5Datatype.SIGN_NONE);
+ Datatype type = null;
+ // supported data types
+ // FIXME: set the right signed and precision stuff
+ if (imgColorType == ImagePlus.GRAY8) {
+ System.out.println(" bit depth: " + imgColorDepth + ", type: GRAY8");
+ type = new H5Datatype(Datatype.CLASS_CHAR, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);
+ } else if (imgColorType == ImagePlus.GRAY16) {
+ System.out.println(" bit depth: " + imgColorDepth + ", type: GRAY16");
+ int typeSizeInByte = 2;
+ type = new H5Datatype(Datatype.CLASS_INTEGER, typeSizeInByte, Datatype.NATIVE, Datatype.SIGN_NONE);
+ } else if (imgColorType == ImagePlus.GRAY32) {
+ System.out.println(" bit depth: " + imgColorDepth + ", type: GRAY32");
+// int typeSizeInByte = 4;
+ type = new H5Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, -1);
+ } else if (imgColorType == ImagePlus.COLOR_RGB) {
+ System.out.println(" bit depth: " + imgColorDepth + ", type: COLOR_RGB");
+ type = new H5Datatype(Datatype.CLASS_CHAR, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);
+ } else if (imgColorType == ImagePlus.COLOR_256) {
+ // FIXME: not supported yet
+ System.out.println(" bit depth: " + imgColorDepth + ", type: COLOR_256");
+ System.out.println(" ERROR: untested, this might fail.");
+ type = new H5Datatype(Datatype.CLASS_CHAR, Datatype.NATIVE, Datatype.NATIVE, Datatype.SIGN_NONE);
+ }
+
+ // select hyperslabs
+ long[] maxdims = dims;
+ // long[] chunks = findOptimalChunksize( nDims,
+ // dims);
+ long[] chunks = null;
+ int gzip = 0; // no compression
+
+ // create dataset
+ Dataset dataset = null;
+
+ try {
+ dataset = (Dataset) outFile.get(groupName + "/" + dataSetName);
+ } catch (Exception e) {
+ dataset = null;
+ }
+ if (dataset == null) {
+
+ dataset = outFile.createScalarDS(dataSetName, group, type, dims, maxdims, chunks, gzip, null);
+ }
+ dataset.init();
+ long[] selected = dataset.getSelectedDims(); // the
+ // selected
+ // size of
+ // the
+ // dataet
+ ImageStack stack = imp.getStack();
+ if (nLevels == 1) {
+ for (int d = 0; d < selected.length; d++) {
+ selected[d] = dims[d];
+ }
+ // get raw data
+ Object slice = stack.getPixels(nLevels);
+ if (imgColorType == ImagePlus.COLOR_RGB)
+ slice = computeRgbSlice(stack.getPixels(nLevels));
+ // write data
+ dataset.write(slice);
+
+ } else {
+ selected[0] = 1;
+ for (int d = 1; d < selected.length; d++) {
+ selected[d] = dims[d];
+ }
+ long[] start = dataset.getStartDims(); // the off set of
+ // the selection
+ for (int lvl = 0; lvl < nLevels; ++lvl) {
+ IJ.showProgress(lvl, nLevels);
+ // select hyperslab
+ start[0] = lvl;
+
+ // get raw data
+ Object slice = stack.getPixels(lvl + 1);
+ if (imgColorType == ImagePlus.COLOR_RGB)
+ slice = computeRgbSlice(stack.getPixels(lvl + 1));
+ // write data
+ dataset.write(slice);
+ }
+ }
+ // get pixel sizes
+ ij.measure.Calibration cal = imp.getCalibration();
+ System.out.println(" Element-Size in um (level,row,col): " + cal.pixelDepth + ", " + cal.pixelHeight + ", " + cal.pixelWidth);
+
+ float[] element_sizes = new float[3];
+ element_sizes[0] = (float) cal.pixelDepth;
+ element_sizes[1] = (float) cal.pixelHeight;
+ element_sizes[2] = (float) cal.pixelWidth;
+ Datatype attrType = new H5Datatype(Datatype.CLASS_FLOAT, Datatype.NATIVE, Datatype.NATIVE, -1);
+ long[] attrDims = { 3 };
+ Attribute element_size_um = null;
+ try {
+ element_size_um = getAttribute(dataset, "element_size_um");
+ } catch (Exception e) {
+ element_size_um = null;
+ }
+ if (element_size_um == null) {
+ element_size_um = new Attribute("element_size_um", attrType, attrDims);
+ }
+ element_size_um.setValue(element_sizes);
+ // write element_size_um
+ dataset.writeMetadata(element_size_um);
+
+ outFile.close();
+ } catch (HDF5Exception err) {
+ System.err.println("Caught HDF5Exception");
+ err.printStackTrace();
+ } catch (java.io.IOException err) {
+ System.err.println("IO Error while writing '" + filename + "': " + err);
+ } catch (Exception err) {
+ System.err.println("Range Error while writing '" + filename + "': " + err);
+ }
+ }
+
+ }
+
+ int byteToUnsignedByte(int n) {
+ if (n < 0)
+ return (256 + n);
+ return n;
+ }
+
+ void showAbout() {
+ IJ.showMessage("About HDF5 Writer:", "Written by Matthias Schlachter\n" + "University of Freiburg, 2010");
+ }
+
+ private static Group createGroupRecursive(String groupRelativName, Group group, FileFormat file) {
+ if (groupRelativName == null || file == null)
+ return null;
+
+ if (group == null)
+ group = (Group) ((DefaultMutableTreeNode) file.getRootNode()).getUserObject();
+
+ while (groupRelativName.charAt(0) == '/') {
+ // trim leading slash
+ groupRelativName = groupRelativName.substring(1);
+ }
+ while (groupRelativName.charAt(groupRelativName.length() - 1) == '/') {
+ // trim last slash
+ groupRelativName = groupRelativName.substring(0, groupRelativName.length() - 2);
+ }
+
+ int posOfSlash = groupRelativName.indexOf('/');
+
+ if (posOfSlash == -1) {
+ try {
+ Group newGroup;
+ String newGroupName;
+ if (group.isRoot())
+ newGroupName = "/" + groupRelativName;
+ else
+ newGroupName = group.getFullName() + "/" + groupRelativName;
+ newGroup = (Group) file.get(newGroupName);
+ if (newGroup == null)
+ newGroup = file.createGroup(newGroupName, group);
+ return newGroup;
+ } catch (Exception e) {
+ return null;
+ }
+ } else {
+ String subgroupRelativName = groupRelativName.substring(posOfSlash);
+ String currentGroup = groupRelativName.substring(0, posOfSlash);
+ System.out.println("Create: " + currentGroup);
+ System.out.println("Call back for: " + subgroupRelativName);
+ try {
+ Group newGroup;
+ String newGroupName;
+ if (group.isRoot())
+ newGroupName = "/" + currentGroup;
+ else
+ newGroupName = group.getFullName() + "/" + currentGroup;
+
+ System.out.println("try opening: " + newGroupName);
+ newGroup = (Group) file.get(newGroupName);
+
+ if (newGroup == null)
+ newGroup = file.createGroup(newGroupName, group);
+
+ return createGroupRecursive(subgroupRelativName, newGroup, file);
+ } catch (Exception e) {
+ return null;
+ }
+
+ }
+ // never come here
+ }
+
+ private static String getGroupDescriptor(String absName) {
+ String groupName = absName;
+
+ while (groupName.charAt(0) == '/') {
+ // trim leading slash
+ groupName = groupName.substring(1);
+ }
+ while (groupName.charAt(groupName.length() - 1) == '/') {
+ // trim last slash
+ groupName = groupName.substring(0, groupName.length() - 2);
+ }
+ int posOfLastSlash = groupName.lastIndexOf('/');
+ if (posOfLastSlash == -1)
+ return null;
+ else
+ return groupName.substring(0, posOfLastSlash);
+ }
+
+ private static String getDataSetDescriptor(String absName) {
+ String dataSetName = absName;
+ while (dataSetName.charAt(0) == '/') {
+ // trim leading slash
+ dataSetName = dataSetName.substring(1);
+ }
+ while (dataSetName.charAt(dataSetName.length() - 1) == '/') {
+ // trim last slash
+ dataSetName = dataSetName.substring(0, dataSetName.length() - 2);
+ }
+ int posOfLastSlash = dataSetName.lastIndexOf('/');
+ if (posOfLastSlash == -1)
+ return dataSetName;
+ else
+ return dataSetName.substring(posOfLastSlash + 1);
+ }
+
+ long[] findOptimalChunksize(int Rank, long[] dataDims) {
+ long[] best_chunksize = new long[Rank];
+ int maxChunkVol = 262144;
+ // small sanity check first:
+ int data_volume = 1;
+ for (int d = 0; d < Rank; ++d)
+ data_volume *= dataDims[d];
+ if (data_volume < maxChunkVol) {
+ for (int d = 0; d < Rank; ++d)
+ best_chunksize[d] = dataDims[d];
+ return best_chunksize;
+ } else
+ return null;
+ }
+
+ private static List getAttrList(Dataset ds) throws Exception {
+ if (ds == null)
+ return null;
+
+ List attributes = new ArrayList();
+ List> members = ds.getMetadata();
+ int n = members.size();
+ Metadata obj = null;
+ for (int i = 0; i < n; i++) {
+ obj = (Metadata) members.get(i);
+ if (obj instanceof Attribute) {
+ try {
+ System.out.println(((Attribute) obj).getName());
+ attributes.add((Attribute) obj);
+ } catch (java.lang.UnsupportedOperationException e) {
+ System.out.println("Caught UnsupportedOperationException datasets2.add((Dataset) obj)");
+ System.out.println(e.getMessage());
+ }
+ }
+ }
+ return attributes;
+ }
+
+ private static Attribute getAttribute(Dataset ds, String attrName) throws Exception {
+ List attrList = getAttrList(ds);
+ Iterator attrIter = attrList.iterator();
+
+ while (attrIter.hasNext()) {
+ Attribute attr = attrIter.next();
+ if (attr.getName().equals(attrName)) {
+ return attr;
+ }
+ }
+ return null;
+ }
+
+ private Object computeRgbSlice(Object pixels) {
+ byte rgbslice[];
+ int size = ((int[]) pixels).length;
+ rgbslice = new byte[size * 3];
+ for (int i = 0; i < size; i++) {
+ int red = (((int[]) pixels)[i] & 0xff0000) >> 16;
+ int green = (((int[]) pixels)[i] & 0x00ff00) >> 8;
+ int blue = ((int[]) pixels)[i] & 0x0000ff;
+ rgbslice[3 * i + 0] = (byte) red;
+ rgbslice[3 * i + 1] = (byte) green;
+ rgbslice[3 * i + 2] = (byte) blue;
+ }
+ return rgbslice;
+ }
+
+ private String makeDataSetName(String[] toks, int frame, int channel) {
+ String dName = toks[0] + Integer.toString(frame) + toks[1] + Integer.toString(channel);
+ if (toks.length > 2)
+ dName = dName + toks[2];
+ return dName;
+ }
}
diff --git a/src/main/java/ch/psi/imagej/hdf5/TimeFrame.java b/src/main/java/ch/psi/imagej/hdf5/TimeFrame.java
index 26f5821..08f5266 100644
--- a/src/main/java/ch/psi/imagej/hdf5/TimeFrame.java
+++ b/src/main/java/ch/psi/imagej/hdf5/TimeFrame.java
@@ -1,102 +1,74 @@
package ch.psi.imagej.hdf5;
-/* =========================================================================
- *
- * Copyright 2011 Matthias Schlachter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- *=========================================================================*/
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.List;
-public class TimeFrame implements Comparable
-{
- public TimeFrame(int index)
- {
- frameIndex = index;
- }
+public class TimeFrame implements Comparable {
+
+ private final int frameIndex;
+ private final List channels = new ArrayList();
+
+ public TimeFrame(int index) {
+ frameIndex = index;
+ }
- public TimeFrame(String index)
- {
- frameIndex = Integer.parseInt(index);
- }
+ public TimeFrame(String index) {
+ frameIndex = Integer.parseInt(index);
+ }
- public void addChannel(int index)
- {
- Integer channelIndex = new Integer(index);
- if(!channels.contains(channelIndex))
- channels.add(new Integer(index));
- else
- System.out.println("channel" + channelIndex.toString()
- + " already in list!");
- }
+ public void addChannel(Integer index) {
+ if (!channels.contains(index)){
+ channels.add(new Integer(index));
+ }
+ }
- public void addChannel(String index)
- {
- addChannel(Integer.parseInt(index));
- }
+ public void addChannel(String index) {
+ addChannel(Integer.parseInt(index));
+ }
- public boolean equals(Object obj)
- {
- TimeFrame f = (TimeFrame) obj;
- if(f.frameIndex == frameIndex)
- return true;
- return false;
- }
+ public boolean equals(Object o) {
+ return (((TimeFrame)o).frameIndex == frameIndex);
+ }
- public String toString()
- {
- String s = "FrameIdx: " + Integer.toString(frameIndex) + "; ";
- s = s + "nChannels: " + Integer.toString(channels.size()) + "; ";
- s = s + "channels: ";
- for(int i=0;if.frameIndex)
- return 1;
- else
- return 0;
- }
-
- private final int frameIndex;
- private final ArrayList channels = new ArrayList();
+ public int getNChannels() {
+ return channels.size();
+ }
+
+ public int getFrameIndex() {
+ return frameIndex;
+ }
+
+ public int[] getChannelIndices() {
+ Object[] channelsAsArray = channels.toArray();
+ Arrays.sort(channelsAsArray);
+ int[] channelsIdx = new int[channelsAsArray.length];
+ for (int i = 0; i < channelsAsArray.length; i++){
+ channelsIdx[i] = ((Integer) channelsAsArray[i]).intValue();
+ }
+ return channelsIdx;
+ }
+
+ public int compareTo(TimeFrame f) {
+ if (frameIndex < f.frameIndex){
+ return -1;
+ }
+ else if (frameIndex > f.frameIndex){
+ return 1;
+ }
+ else{
+ return 0;
+ }
+ }
}
\ No newline at end of file