Package ij.util

Source Code of ij.util.DicomTools

package ij.util;
import ij.*;
import ij.process.*;
import ij.plugin.DICOM;

/** DICOM utilities */
public class DicomTools {
  private static final int MAX_DIGITS = 5;
  private static String[] sliceLabels;

  /** Sorts a DICOM stack by image number. */
  public static ImageStack sort(ImageStack stack) {
    if (IJ.debugMode) IJ.log("Sorting by DICOM image number");
    if (stack.getSize()==1) return stack;
    String[] strings = getSortStrings(stack, "0020,0013");
    if (strings==null) return stack;
    StringSorter.sort(strings);
    ImageStack stack2 = null;
    if (stack.isVirtual())
      stack2 = ((VirtualStack)stack).sortDicom(strings, sliceLabels, MAX_DIGITS);
    else
      stack2 = sortStack(stack, strings);
    return stack2!=null?stack2:stack;
  }
 
  private static ImageStack sortStack(ImageStack stack, String[] strings) {
    ImageProcessor ip = stack.getProcessor(1);
    ImageStack stack2 = new ImageStack(ip.getWidth(), ip.getHeight(), ip.getColorModel());
    for (int i=0; i<stack.getSize(); i++) {
      int slice = (int)Tools.parseDouble(strings[i].substring(strings[i].length()-MAX_DIGITS), 0.0);
      if (slice==0) return null;
      stack2.addSlice(sliceLabels[slice-1], stack.getPixels(slice));
    }
    stack2.update(stack.getProcessor(1));
    return stack2;
  }

  private static String[] getSortStrings(ImageStack stack, String tag) {
    double series = getSeriesNumber(getSliceLabel(stack,1));
    int n = stack.getSize();
    String[] values = new String[n];
    sliceLabels = new String[n];
    for (int i=1; i<=n; i++) {
      String tags = getSliceLabel(stack,i);
      if (tags==null) return null;
      sliceLabels[i-1] = tags;
      double value = getNumericTag(tags, tag);
      if (Double.isNaN(value)) {
        if (IJ.debugMode) IJ.log("  "+tag+"  tag missing in slice "+i);
        return null;
      }
      if (getSeriesNumber(tags)!=series) {
        if (IJ.debugMode) IJ.log("  all slices must be part of the same series");
        return null;
      }
      values[i-1] = toString(value, MAX_DIGITS) + toString(i, MAX_DIGITS);
    }
    return values;
  }

  private static String toString(double value, int width) {
    String s = "       " + IJ.d2s(value,0);
    return s.substring(s.length()-MAX_DIGITS);
  }
 
  private static String getSliceLabel(ImageStack stack, int n) {
    String info = stack.getSliceLabel(n);
    if ((info==null || info.length()<100) && stack.isVirtual()) {
      String dir = ((VirtualStack)stack).getDirectory();
      String name = ((VirtualStack)stack).getFileName(n);
      DICOM reader = new DICOM();
      info = reader.getInfo(dir+name);
      if (info!=null)
        info = name + "\n" + info;
    }
    return info;
  }

  /** Calculates the voxel depth of the specified DICOM stack based
    on the distance between the first and last slices. */
  public static double getVoxelDepth(ImageStack stack) {
    if (stack.isVirtual()) stack.getProcessor(1);
    String pos0 = getTag(stack.getSliceLabel(1), "0020,0032");
    String posn = null;
    double voxelDepth = -1.0;
    if (pos0!=null) {
      String[] xyz = pos0.split("\\\\");
      if (xyz.length!=3) return voxelDepth;
      double z0 = Double.parseDouble(xyz[2]);
      if (stack.isVirtual()) stack.getProcessor(stack.getSize());
      posn = getTag(stack.getSliceLabel(stack.getSize()), "0020,0032");
      if (posn==null) return voxelDepth;
      xyz = posn.split("\\\\");
      if (xyz.length!=3) return voxelDepth;
      double zn = Double.parseDouble(xyz[2]);
      voxelDepth = Math.abs((zn - z0) / (stack.getSize() - 1));
    }
    if (IJ.debugMode) IJ.log("DicomTools.getVoxelDepth: "+voxelDepth+"  "+pos0+"  "+posn);
    return voxelDepth;
  }

  /** Returns the value (as a string) of the specified DICOM tag id (in the form "0018,0050")
    of the specified image or stack slice. Returns null if the tag id is not found. */
  public static String getTag(ImagePlus imp, String id) {
    String metadata = null;
    if (imp.getStackSize()>1) {
      ImageStack stack = imp.getStack();
      String label = stack.getSliceLabel(imp.getCurrentSlice());
      if (label!=null && label.indexOf('\n')>0) metadata = label;
    }
    if (metadata==null)
      metadata = (String)imp.getProperty("Info");
    return getTag(metadata, id);
  }
 
  private static double getSeriesNumber(String tags) {
    double series = getNumericTag(tags, "0020,0011");
    if (Double.isNaN(series)) series = 0;
    return series;
  }

  private static double getNumericTag(String hdr, String tag) {
    String value = getTag(hdr, tag);
    if (value==null) return Double.NaN;
    int index3 = value.indexOf("\\");
    if (index3>0)
      value = value.substring(0, index3);
    return Tools.parseDouble(value);
  }

  private static String getTag(String hdr, String tag) {
    if (hdr==null) return null;
    int index1 = hdr.indexOf(tag);
    if (index1==-1) return null;
    //IJ.log(hdr.charAt(index1+11)+"   "+hdr.substring(index1,index1+20));
    if (hdr.charAt(index1+11)=='>') {
      // ignore tags in sequences
      index1 = hdr.indexOf(tag, index1+10);
      if (index1==-1) return null;
    }
    index1 = hdr.indexOf(":", index1);
    if (index1==-1) return null;
    int index2 = hdr.indexOf("\n", index1);
    String value = hdr.substring(index1+1, index2);
    return value;
  }

}
TOP

Related Classes of ij.util.DicomTools

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.