Changing DICOM tags using dcm4che

Posted on

Problem

I am stuck on a piece of code that I have written that uses dcm4che. I have made a whole heap of nested ifs and I want to find a way to convert to a switch-case (problem being I have no way of declaring an int that can distinguish between cases). Is there an alternative to making this code snippet appear less ugly?

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.dcm4che2.data.DicomObject;
import org.dcm4che2.data.Tag;
import org.dcm4che2.data.VR;
import org.dcm4che2.io.DicomInputStream;
import org.dcm4che2.io.DicomOutputStream;
import org.dcm4che2.io.StopTagInputHandler;
import org.dcm4che2.util.CloseUtils;



/**
 * Steps to doing this. 
 * 1.) Read from DCM file and convert to DCM Object
 * 2.) Read from text file 
 * 3.) Add tags to ArrayList
 * 4.) Compare ArrayList of tags to DCM Object
 * 5.) Match tags and associate tags with VR code which will automatically add Strings/values into tag.
 * 6.) Save new copy into a directory prompted by user.
 * @author Ryan
 *
 */
public class changeTags {
    Scanner input = new Scanner(System.in);
    public static DicomObject dcmObj;
    public static ArrayList<String> list = new ArrayList<String>();

    public void promptForTagLocation() throws IOException
    {
        //Turns DCM file into object
        System.out.println("Please Enter DICOM File Location: ");
        String dicomLocation = input.next();
        changeToDICOMObject(dicomLocation);

        //Reading text tag location
        System.out.println("From what TXT File are you reading the tags that need changing: ");
        String tagChangeText = input.next();
        readFromTextFile(tagChangeText);
    }
    public void changeToDICOMObject(String path)
    {
        DicomInputStream din = null;
        try {
            din = new DicomInputStream(new File(path));
            dcmObj = din.readDicomObject();
        }
        catch (IOException e) {
            e.printStackTrace();
            return;
        }
        finally {
            try {
                din.close();
            }
            catch (IOException ignore) {
            }
        }
        System.out.println("Now reading DCM File");
    }
    public void readFromTextFile(String path) throws IOException
    {
        Scanner read = new Scanner(new File(path));
        while (read.hasNext())
        {
            list.add(read.next());
        }
        System.out.println("Reading from tag List....");
        System.out.println("Changing dicom tags...");
        read.close();
        matchTags();
    }
    public void matchTags() throws IOException
    {
        try 
        {
            for(int i = 0; i < list.size(); i++)
            {
                String replaceTag = list.get(i).toString().replaceAll("[(),]", "");
                int valueofReplaceTag = (int)Long.parseUnsignedLong(replaceTag, 16);
                if(dcmObj.vrOf(valueofReplaceTag).equals(VR.DA))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "20150101");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.DT))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "20150101");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.SH))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "testingThis");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.AE))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "test");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.CS))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "testingThis");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.LO))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "testingThis");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.PN))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "testingThis");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.ST))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "testingThis");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.LT))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "testingThis");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.UT))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "testingThis");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.AS))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "25");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.DS))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "25");
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.UL))
                    {
                        dcmObj.putInt(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), 25);
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.SL))
                    {
                        dcmObj.putInt(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), 25);
                    }
                    else if(dcmObj.vrOf(valueofReplaceTag).equals(VR.TM))
                    {
                        dcmObj.putString(valueofReplaceTag, dcmObj.vrOf(valueofReplaceTag), "22:00");
                    }
            }
                System.out.println("Where is the new DCM file being saved to? Please enter directory (Include File name and Extension): ");
                String directoryPath = input.next();
                File out = new File(directoryPath);
                DicomOutputStream dos = new DicomOutputStream(new BufferedOutputStream(new FileOutputStream(out)));
                dos.writeDicomFile(dcmObj);

                CloseUtils.safeClose(dos);

        System.out.println("Tags have been successfully changed!");
        menu.showMenu();
        }
        catch (NumberFormatException e){
            System.err.println(e);
        }
    }
}

Solution

You could define a mapping of your replacements, as follows:

private static final Map<VR, String> stringReplacements = new HashedMap<>();
static {
  stringReplacements.put(VR.DA, "20150101");
  stringReplacements.put(VR.DT, "20150101");
  stringReplacements.put(VR.SH, "testingThis");
  // ....
}

private static final Map<VR, Integer> intReplacements = new HashedMap<>();
static {
  intReplacements.put(VR.UL, 25);
  // ....
}

Note that I’ve created two different maps, as you substitute both strings and ints. You could have one map of Object values, but then your replacement code needs to do instanceof checks.

Your long series of conditional statements then reduces to:

VR replaceTagVR = dcmObj.vrOf(valueofReplaceTag);

String s = stringReplacements.get(replaceTagVR);
if (s != null) {
  dcmObj.putString(valueofReplaceTag, replaceTagVR, s);
}

Integer i = intReplacements.get(replaceTagVR);
if (i != null) {
  dcmObj.putInt(valueofReplaceTag, replaceTagVR, i);
} 

Leave a Reply

Your email address will not be published. Required fields are marked *