|
DICOM_Sorter |
|
package ij.plugin; import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import ij.util.*; /* Sorts a DICOM stack by image number. */ public class DICOM_Sorter implements PlugIn { static final int MAX_DIGITS = 5; public void run(String arg) { ImagePlus imp = IJ.getImage(); if (!isDicomStack(imp)) { IJ.showMessage("DICOM Sorter", "This command requires a DICOM stack"); return; } int stackSize = imp.getStackSize(); ImageStack stack = imp.getStack(); String[] strings = getSortStrings(stack, "0020,0013"); StringSorter.sort(strings); ImageStack stack2 = sortStack(stack, strings); if (stack2!=null) imp.setStack(null, stack2); } public ImageStack sort(ImageStack stack) { if (IJ.debugMode) IJ.log("DICOM_Sorter: sorting by image number"); if (stack.getSize()==1) return stack; String[] strings = getSortStrings(stack, "0020,0013"); if (strings==null) return stack; StringSorter.sort(strings); ImageStack stack2 = sortStack(stack, strings); return stack2!=null?stack2:stack; } 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(stack.getSliceLabel(slice), stack.getPixels(slice)); } stack2.update(stack.getProcessor(1)); return stack2; } String[] getSortStrings(ImageStack stack, String tag) { double series = getSeries(stack.getSliceLabel(1)); int n = stack.getSize(); String[] values = new String[n]; for (int i=1; i<=n; i++) { String tags = stack.getSliceLabel(i); if (tags==null) return null; double value = getNumericTag(tags, tag); if (Double.isNaN(value)) { if (IJ.debugMode) IJ.log(" "+tag+" tag missing in slice "+i); return null; } if (getSeries(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; } String toString(double value, int width) { String s = " " + IJ.d2s(value,0); return s.substring(s.length()-MAX_DIGITS); } boolean isDicomStack(ImagePlus imp) { if (imp.getStackSize()==1) return false; ImageStack stack = imp.getStack(); String label = stack.getSliceLabel(1); return label!=null && label.lastIndexOf("7FE0,0010")>0; } double getSeries(String tags) { double series = getNumericTag(tags, "0020,0011"); if (Double.isNaN(series)) series = 0; return series; } double getNumericTag(String hdr, String tag) { String value = getTag(hdr, tag); if (value.equals("")) return Double.NaN; int index3 = value.indexOf("\\"); if (index3>0) value = value.substring(0, index3); return Tools.parseDouble(value); } String getTag(String hdr, String tag) { if (hdr==null) return ""; int index1 = hdr.indexOf(tag); if (index1==-1) return ""; //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 ""; } index1 = hdr.indexOf(":", index1); if (index1==-1) return ""; int index2 = hdr.indexOf("\n", index1); String value = hdr.substring(index1+1, index2); return value; } }
|
DICOM_Sorter |
|