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