Openclinica integration

  • This post documents on the integration of OpenClinica clinical trial database solution (or ECRF) and Conquest dicom and web server as gateway machine. This setup allow uploading anonymized DICOM data from any PACS to a central (DICOM) server through SFTP while populating the ECRF with the correct anonymized UIDs.


    This work has been done at NKI/AVL as part of the CTMM AirForce project.


    I have added a step by step description here on how all systems are setup. This is some explanation of the the setup that allows copying anonymized PACS data to a central SFTP server while storing the anonymized patient ID's in the ECRF:

    1) OPENCLINICA (central) with an added javascript file initiates a HTML connection to a local web server inside the hospitals firewall


    2) Conquest WEB SERVER (local) runs OPENCLINICA specific lua scripts controlling the DICOM server and sending UIDs to OPENCLINICA


    3) Conquest DICOM server (local) Makes contact with the PACS and collects, anonymizes, zips and sends data to central SFTP server


    Both conquest systems run on a single gateway computer that has to be installed locally in each hospital inside the firewall.

    A single custom Javascript file is added to an OpenCLinica install (i.e., in the TomCat includes folder)
    The eCRF designer adds the following items to the excel file defining the eCRF:

    LEFT_ITEM_TEXT: <A HREF=# onclick="javascript:link(8,1,'CT'); return false;">Name of exam:</A>
    RIGHT_ITEM_TEXT: .
    HEADER: Diagnostic scans:<script type="text/javascript" language="JavaScript" src=http:includes/marcel.js></script>
    SUBHEADER: PACS link: <A HREF=# onclick="javascript:openconfig(); return false;">Configure</A>
    RESPONSE TYPE: calculation
    RESPONSE_VALUES_OR_CALCULATIONS: func: getExternalValue("http://dummy",right,600,400)


    The javascript functions do the following:
    openconfig(): (has to be clicked once for each new computer where ECRFs are entered)
    asks (and saves in cooky) for web adress of gateway server and shows gateway config. The rest of the configuration is done by the hospital's IT people on the gateway computer and is shared between all users

    link(item, date, modality):
    asks (and remembers) SubjectID to Hospital Patient ID link in cooky on the computer
    opens browser window to query/view the PACS images and select the one to be linked to ECRF
    parameters:
    item number where the anonymized PACS link will be stored in the eCRF
    item number where the scan date is found, or an empty string if no date is known
    item number where the DICOM modality is found, a constant string, or an empty string if no modality is known

    The OpenCLinica interface
    Clicking on the left item text allows entering the PACS link
    The right item text and its hyperlink are not used, its code just forces OpenClinica to generates a window 'listener'


    Clicking 'link' and 'collect' will transfer all selected images to the gateway
    Clicking 'submit' will send the images to the central server

  • This is the code of the javascript to be put in the OpenClinica server in the includes folder with all the other js stuff.


    marcel.js

  • Here I will put the conquest web server lua scripts. The configuration of the gateway is done through the dicom.ini file in cgi-bin. The scripts are under cgi-bin/OpenClinica.


    To make the server recongnize the scripts put this section in the dicom.ini of cgi-bin:


    # DefaultPage
    [DefaultPage]
    source = *.lua


    The actual configuration of the gateway is here. Item Source sets AE of the PACS to be connected to. (local) means from the DICOM server running on the gateway (it then acts a a slave allowing only tranmission of objects pushed into there before). Item TargetServer sets the address and folder in the SFTP server where the data is to be uploaded. Other relevant configuration items are in the dicom server.


    [OpenClinica]
    Source=(local)
    PatientIDkeep=cookie
    AnonymizeOn=transmission
    TargetServer=user@sftp-server.domain:
    password=XXXXXXXXXXX


    The items PatientIDkeep and AnonymizeOn are for future expansion and need not be set.


    This is the first script: OpenClinica/Config.lua

  • This is the code of the page allowing browsing the PACS.


    File OpenClinica/Link.lua

  • This is the script that processes the data.


    File OpenClinica/Process.lua

  • This is a small WADO viewer.


    File OpenClinica/wadoviewer.lua

  • These is the anonymization script that needs to be put in the dicom server folder.


    File dicomserver/anonymize_script.cq

    Code
    lua "dofile('anonymize_script.lua')"


    File dicomserver/anonymize_script.lua

  • Here I will put the step by step manual to setup the gateway server.


    Install a windows server or workstation according to hospital policy


    Enable access to the following ports:
    80 from inside the hospital
    5678 or the configured DICOM port from inside the hospital
    22 for SFTP access to the central server outside the hospital


    Install XAMPP or another version of apache web server (mysql is not used) in c:\xampp
    start the web server
    verify that localhost can access the web server


    download the zip file containing conquestdicomserver1.4.17(alpha or later) from this forum
    unpack the zip file in folder c:\dicomserver
    start conquestdicomserver.exe
    select SQLite database
    modify its AE title and port if required
    save configuration
    push (Re-)initalize database
    check that the dicom server is working by looking at the Browse database page


    copy the contents of the c:\dicomserver\webserver folder to c:\xampp\cgi-bin
    manually edit c:\xampp\cgi-bin\dicom.ini there and set:


    TCPPort = 5678
    MyACRNema = AE
    WebScriptAddress = http://pcname/cgi-bin/dgate.exe


    check that the web server is up by opening


    http://pcname/cgi-bin/dgate.exe/mode=top


    It should show a conquest screen and allow viewing the sample data


    Finally setup these items the OpenCLinica section in c:\xampp\cgi-bin\dicom.ini


    [OpenClinica]
    Source=(local)
    TargetServer=user@server.station.domain:
    password=XXXXXXX


    if source is (local), submission is from the gateway dicom server. If it is set to the AE of the PACS system, this AE has also to be setup in the 'known dicom providers' page of the conquest dicom server and the conquest AE, address and port needs to be setup in the PACS.

  • Hi Marcel,


    I am still working on the OC+ConQuest integration. Your scripts were helpful but I need a different workflow so I have to do it at the end differently. However, I found a better way of working with data which are in CRF fields which could be helpful also for your use case.


    In CRF it is possible to RIGHT_ITEM_TEXT field in order to crate a named <div > element in final webpage of OC. E.g. by putting this text into CRF defintion:
    <div id="divPatientID">&nbsp;</div>


    I can be sure that the input field of PatientID in OCR will be inside named div "divPatientID".


    The names of divs which I want to access from my javascript could be specified also in CRF as parameters for javascript function :
    <A HREF=# onclick="javascript:loadViewer('divPatientID', 'divDICOMSeriesID'); return false;">View DICOM</A>



    function getFieldInput(divFieldName) {
    var fieldRow = document.getElementById(divFieldName).parentNode.parentNode;
    var input = fieldRow.getElementsByTagName('input');


    var inputValue = "";
    if (input.length > 1) {
    alert("Error: more than one field with the same div name in the form.");
    }
    else {
    inputValue = input[0].value;


    //alert("Debug: " + divFieldName + " = " + inputValue);
    }


    return inputValue;
    }


    function loadViewer(divPatientID, divDICOMSeriesID) {
    var patientIdValue = getFieldInput(divPatientID);
    var seriesIdValue = getFieldInput(divDICOMSeriesID);


    if (patientIdValue != "" && seriesIdValue != "") {
    var url = "http://website.de?" + &patientId=" + patientIdValue + "&seriesUID" + seriesIdValue;


    window.open(url, "_blank", "width=1100,height=600,scrollbars=1");
    }
    else {
    alert("Warning: patientId and seriesId must be specified in order to locate DICOM data on PACS server.")
    }
    }


    the important part is getFieldInput function which takes the name of the div we are looking for, and locate the the proper row in the main form table. Afterwards the input field is located which should be only on in a row for normal string data type element of CRF.


    If it is helpful for you, feel free to share this in the forum.


    best


    --
    Tomas Skripcak

  • Hi all,


    Just a small update. I was able to integrate conquest DICOM zip download functionality directly into OpenClinica CRF from. It is possible to accomplish this, the same way as the viewer integration. Basically I have a new function in javascript file which is included into CRF which is looking like following:


    Code
    function downloadStudyData(divDICOMPatientID, divDICOMStudyID) { var patientIdValue = getFieldInput(divDICOMPatientID); var studyIdValue = getFieldInput(divDICOMStudyID); if (patientIdValue != "" && studyIdValue != "") { var url = "myproxyportal/pacs/dicomStudyDownload.faces?" + "&study=" + patientIdValue + ":" + studyIdValue; window.open(url, "_blank", "width=1100,height=600,scrollbars=1"); } else { alert("Warning: patientId and studyId must be specified in order to locate DICOM data on PACS server.")


    I redirect to my own java based web app, which is working as a proxy to ConQuest web server. (I dont want to expose ConQuest web directly). But for people who does not need this abstraction they can directly invoke link.lua mode of conqest web server (as it is already described in this thread). In that case the following a snapshot of code which can be added to link.lua to generate a download links:


    Code
    print([[<a href=# onclick="javascript:PopupCenter(
    ']]..script_name..[[?mode=zipstudy&study=]]..
    series[i].PatientID..':'..series[i].StudyInstanceUID..'&dum=.zip'..
    [[', 'Download', 400, 500)">[download DICOM study]</a>]])
    print([[<a href=# onclick="javascript:PopupCenter(
    ']]..script_name..[[?mode=zipseries&series=]]..
    series[i].PatientID..':'..series[i].SeriesInstanceUID..'&dum=.zip'..
    [[', 'Download', 400, 500)">[download DICOM series]</a>]])


    best


    Tomas

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!