org.dcm4che.net Java programming

688 views
Skip to first unread message

Jonas

unread,
Jan 6, 2014, 3:52:17 AM1/6/14
to dcm...@googlegroups.com
I'm extending a clinical java application with DICOM net features, and chosen dcm4che as library. All forum posts and docs seems to be on the server application and not how to use dcm4che net as a java library!

Can someone provide any reference to examples or help on java programming with dcm4che v3.0 for network communication (find/move)?

I've been browsing the git repository alot, and done some unit testing on the Device, ApplicationEntity, Connection and AAssociateRQ classes, but there must be a better way of doing it. Today I just found the BasicCEchoSCP class but cannot figure out how to use it!

fleetwoodfc

unread,
Jan 6, 2014, 7:54:22 AM1/6/14
to dcm...@googlegroups.com
The source distribution includes many sample applications under the dcm4che-tool directory e.g the dcm4che-tool-movescu.

Jonas

unread,
Jan 6, 2014, 9:38:33 AM1/6/14
to dcm...@googlegroups.com
Thanks fleetwoodfc,

The code for the provided tools have been my primary inspiration for writing an echo test. Unfortunately, it is quite complicated to figure out the configuration as you cannot call all the code in the tools. Eg. the "main" function of FindSCU utilize some of the private members of the FindSCU class that is not accessable for code outside. Unless I'm doing something wrong dcm4che requires to manually create an instance of a Device, two Connections, an ApplicationEntity, AAssociateRQ and handle some of the communication.

I've done similay projects in C# using the ClearCanvas library and this can be done using only a few line of code! This is my dcm4che code reinventing the find tool to do a simple query:

class DicomConnection {
private final Device device = new Device("tvs");
   private final ApplicationEntity ae = new ApplicationEntity("TVS");
   private final Connection conn = new Connection();
   private final Connection remote = new Connection();
   private final AAssociateRQ rq = new AAssociateRQ();
   
   private Attributes keys = new Attributes();
   
   private Association as;
   private OutputStream out = null;//System.out;
   
   public DicomConnection() {
    device.addConnection(conn);
       device.addApplicationEntity(ae);
       ae.addConnection(conn);
   }
   
   public void configureConnect(String aet, String host, int port) {
    //CLIUtils.configureConnect(main.remote, main.rq, cl);
    rq.setCalledAET(aet);
       remote.setHostname(host);
       remote.setPort(port);
   }
   
   public void configureBind(String aet, String host, int port) {
       //CLIUtils.configureBind(main.conn, main.ae, cl);
    ae.setAETitle(aet);
    conn.setHostname(host);
            conn.setPort(port);
   }
   
   public void configure() {
       //CLIUtils.configure(main.conn, cl);
    //..
   
    remote.setTlsProtocols(conn.getTlsProtocols());
            remote.setTlsCipherSuites(conn.getTlsCipherSuites());
            
            //configureServiceClass(main, cl);
            String cuid = UID.StudyRootQueryRetrieveInformationModelFIND; // InformationModel.StudyRoot
            String[] tss = {UID.ImplicitVRLittleEndian, UID.ExplicitVRLittleEndian, UID.ExplicitVRBigEndian }; //IVR_LE_FIRST 
            rq.addPresentationContext(new PresentationContext(1, cuid, tss));
   }
   
   public void query(String level, String patientId) {
    // search query
    keys.setString(Tag.QueryRetrieveLevel, VR.CS, level);
    keys.setString(Tag.PatientID, VR.LO, patientId);
   
    // tags to return
    keys.setString(Tag.PatientID, VR.LO);
    keys.setString(Tag.PatientName, VR.PN);
    keys.setString(Tag.StudyDate, VR.DA);
    keys.setString(Tag.StudyTime, VR.TM);
    keys.setString(Tag.StudyInstanceUID, VR.UI);
    keys.setString(Tag.StudyID, VR.SH);
    keys.setString(Tag.SeriesDate, VR.DA);
    keys.setString(Tag.SeriesTime, VR.TM);
    keys.setString(Tag.SeriesDescription, VR.PN);
    keys.setString(Tag.SeriesInstanceUID, VR.UI);
   }
   
   public void request(String level, String patientId) {
    keys.setString(Tag.QueryRetrieveLevel, VR.CS, level);
    keys.setString(Tag.PatientID, VR.LO, patientId);
   }
   
   public void go() {
    ExecutorService executorService = Executors.newSingleThreadExecutor();
            ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
            
            device.setExecutor(executorService);
            device.setScheduledExecutor(scheduledExecutorService);
            
            try {
                open();
                handle();
            }
            catch(Exception ex) {
            String str = ex.toString();
            }
            finally {
            try { close(); }
            catch(Exception ex) {}
                executorService.shutdown();
                scheduledExecutorService.shutdown();
            }
   }
   
   public void open() throws IOException, InterruptedException, IncompatibleConnectionException, GeneralSecurityException {
    as = ae.connect(conn, remote, rq);
   }

public void close() throws IOException, InterruptedException {
   if (as != null && as.isReadyForDataTransfer()) {
       as.waitForOutstandingRSP();
       as.release();
   }
   
   SafeClose.close(out);
   out = null;
}

   private void handle() throws IOException, InterruptedException {
    DimseRSPHandler rspHandler = new DimseRSPHandler(as.nextMessageID()) {
    public void onDimseRSP(Association as, Attributes cmd, Attributes data) {
               super.onDimseRSP(as, cmd, data);
               int status = cmd.getInt(Tag.Status, -1);
               if (Status.isPending(status)) {
                   onResult(data);
               }
           }
    };
   
    String cuid = UID.StudyRootQueryRetrieveInformationModelFIND;
    int priority = Priority.NORMAL;
    //as.cecho();
            as.cfind(cuid, priority, keys, null, rspHandler);
   }
   
   private void writeln(String name, int tag, Attributes data) throws IOException {
    if(data.contains(tag)) {
    String str = data.getString(tag);
    out.write((name+": "+str+"\\n").getBytes());
    }
   }
   
   private void onResult(Attributes data) {
    try {

    if (out == null) {
               File f = new File("C:\\tvs.out.txt");
               out = new BufferedOutputStream(new FileOutputStream(f));
           }
   
    out.write("== Dicom Result ==\\n".getBytes());
   
    writeln("PatientID", Tag.PatientID, data);
    writeln("PatientName", Tag.PatientName, data);
    writeln("StudyDate", Tag.StudyDate, data);
    writeln("StudyTime", Tag.StudyTime, data);
    writeln("StudyInstanceUID", Tag.StudyInstanceUID, data);
    writeln("StudyID", Tag.StudyID, data);
    writeln("SeriesDate", Tag.SeriesDate, data);
    writeln("SeriesTime", Tag.SeriesTime, data);
    writeln("SeriesDescription", Tag.SeriesDescription, data);
    writeln("SeriesInstanceUID", Tag.SeriesInstanceUID, data);
   
    out.flush();
    }
    catch (Exception e) {
           e.printStackTrace();
           SafeClose.close(out);
           out = null;
       }
   }
}
public void dicomQuery() {
// findscu -b JONASPC@localhost:5678 -c MOP...@xxx.xxx.xxx.xxx:4000 -m PatientID=yyyy -L STUDY -r PatientName
DicomConnection main = new DicomConnection();
        main.configureConnect("MOP_SCP", "xxx.xxx.xxx.xxx", 4000); // "-c" options
        main.configureBind("JONASPC", "localhost", 5678); // "-b" options
        main.configure();
        main.query("STUDY", "yyyy"); // "-m" options (search query)
        
        main.go();
}


Reply all
Reply to author
Forward
0 new messages