Part 3: Batch DICOM Operations with CTP and XNAT

 

NOT YET READY, COMING SOON

RSNA Clinical Trial Processor (CTP) is a standalone Java program with many valuable capabilities for handling DICOM.  This practical will demonstrate some of the ways CTP can be used in conjunction with XNAT, such as routing, recoding, and anonymization of DICOM. 

Remote Scan Site

In this scenario we demonstrate how CTP can be use to facilitate transfer of DICOM from a remote site to your XNAT.  The easiest path to transfer data from a scanner to XNAT is generally to do a DICOM send.  However, because DICOM is not a secure transfer protcol, we can't use it to send over the internet.  In this case we configure CTP to receive DICOM from the scanner, but then export the data to XNAT over HTTPS.  CTP handles data through what the documentation calls Pipelines (not to be confused with XNAT pipelines).  These pipelines are composed of one or more stages called Processors and Services provided by CTP or even custom ones.  The pipelines on a CTP server are declared in the config.xml file.  In the config.xml file shown below we have the following CTP-defined stages in our pipeline:  DicomImportService, DicomAnonymizer, FileStorageService, HttpExportService. 

  config.xml

Configuration>
    <Server
        maxThreads="20"
        port="1080"/>
    <Pipeline name="XNAT Relay Pipeline">
        <DicomImportService
            class="org.rsna.ctp.stdstages.DicomImportService"
            logConnections="no"
            name="DICOM Import from Scanner"
            port="8104"
            quarantine="/data/ctp/quarantines/dicom-import"
            root="/data/ctp/dicom-import">
            <accept calledAET="CTP"/>
        </DicomImportService>
        <DicomAnonymizer
            name="Set XNAT Project Routing Info"
            class="org.rsna.ctp.stdstages.DicomAnonymizer"
            root="/data/ctp/anonymizer"
            script="scripts/ProjectReroute.script"
            quarantine="/data/ctp/quarantines/anonymizer" />
        <FileStorageService
            class="org.rsna.ctp.stdstages.FileStorageService"
            fsNameTag="00100020"
            name="30 Day File Cache"
            quarantine="/data/ctp/quarantines/storage"
            returnStoredFile="no"
            root="/data/ctp/storage"
            timeDepth="30"
            type="day"/>
        <HttpExportService
            acceptXmlObjects="no"
            acceptZipObjects="no"
            class="org.rsna.ctp.stdstages.HttpExportService"
            name="HTTP Export to XNAT"
            quarantine="/data/ctp/quarantines/http-export"
            root="/data/ctp/http-export"
            sendDigestHeader="yes"
            interval="5000"
            url="http://<hostname>/data/services/import?import-handler=DICOM-zip&amp;inbody=true">
            <compressor
                cacheSize="100"
                defaultString="unknown"
                structure="(0010,0020).(0008,0060).(0008,0020).(0008,0030).(0020,0011).(0020,0013).(0019,10A2)"/>
            <xnat
                cookieName="JSESSIONID"
                password=""
                url="http://<hostname>/data/JSESSION"
                username="CTP"/>
        </HttpExportService>
    </Pipeline>
</Configuration>

As we mentioned, the first stage enabled the Dicom Import.  The next stage is called DicomAnonymizer, however, in this case we're really using it for routing.  The ProjectReroute.script below provides routing.  If you recall in the Anonymization portion of the practical from yesterday, we can use DICOM tag (0010,4000) Patient Comments to add routing information.  

ProjectReroute.script

<script>
<e en="T" t="001021B0" n="AdditionalPatientHistory">@keep()</e>
<e en="T" t="00104000" n="PatientComments">@always()@if(AdditionalPatientHistory,isblank){Project:MULTI_SITE AA:TRUE}{@contents(AdditionalPatientHistory) AA:TRUE}</e>
</script>

Create project MULTI_SITE

turn on CTP

dcmsend -aec CTP +r --scan-directories <file_path> <hostname> 8104

Practical Session Complete!

You have completed the XNAT DevOps Practical Session

$label.name