Sidebar
0 votes
150 views
by nathan-c-4426 (720 points)
edited by nathan-c-4426

I have a question about QIE's postDICOMRequest() method. I have an HTTP listener channel that receives a JSON payload that contains all the relevant information to perform a C-FIND by patientId. My plan is to find all DICOM studies for the patient by looking in various PACS that I have setup as DICOM connections within QIE. This is the code:

var destinationAET = "PACS_B";
var patientId = source.getNode("/patientId");
var request = qie.createDICOMRequest("1.2.840.10008.5.1.4.1.2.1.1", 0x20, 0); // Patient Root, STUDY level
var msgResponse = "";
request.setNode("/0010,0020", patientId); // Patient ID
request.setNode("/0008,0005", "ISO_IR 100"); // Avoids a Character set mismatch, If Orthanc stored the DICOM using non-default charset, but your C-FIND doesn’t include this...then it can silently fail to find matches
request.setNode("/0008,0052", "STUDY"); // Query Retrieve Level (STUDY/SERIES/IMAGE)

// You must explicitly request the fields you want to receive in the response by including them in the C-FIND request with empty values.
request.setNode("/0020,000d", ""); // Study Instance UID e.g. 1.2.840.10008.114051.26918.2025022511095516.3990029820
request.setNode("/0020,0010", ""); // StudyID human-entered identifier, often assigned by the imaging facility's RIS or PACS. e.g. 11540
request.setNode("/0008,0020", ""); // StudyDate
request.setNode("/0008,0030", ""); // StudyTime
request.setNode("/0008,1030", ""); // Study Description
request.setNode("/0008,0050", ""); // Accession Number
request.setNode("/0008,0061", ""); // Modalities in Study
var token = qie.postDICOMRequest(request, destinationAET);
var matchingStudiesList = [];

try {
   var response = qie.getResponseToDICOMRequest(token);
   while (response !== null) {
      var matchingStudy = "" + response.getNode("/0020,000d"); // grab the study UID
      if (StringUtils.isNotBlank(matchingStudy)) {
        matchingStudiesList.push(matchingStudy);
      }
      response = qie.getResponseToDICOMRequest(token);
   }
   qie.debug("CFIND studyUIDs from " + destinationAET + ": " + JSON.stringify(matchingStudiesList));
   msgResponse =
   `HTTP Status: 200 OK
      
   Content-Type="application/json"
   {"matchingStudiesFound":${JSON.stringify(matchingStudiesList)}}`;
} catch (err) {
   qie.warn(err);
   msgResponse = `HTTP Status: 500
   
   Content-Type="application/json"
   {"error":"${err}"}
   `;
}

qie.postMessageResponse(msgResponse);

This is the error I get:


[line: 18] WrappedException: Wrapped 
com.qvera.qie.web.exception.MappingFailureException: 
Channel 'C-FIND via JSON' is not running.
Stack Trace:
at script [line: 18]

1 Answer

0 votes

Here’s why QIE forces you to split things out into:


  • A DICOM connection (the “where do I send my request?” config, acting as SCU → SCP)
  • A DICOM channel (the “where do I listen for responses?” config, acting as SCP on your side)

This mirrors how DICOM associations actually behave in the real world:


  • Many DICOM services are asynchronous. When you send a request (N-ACTION-RQ, C-MOVE, etc.), the SCP may send multiple responses over time (intermediate pending responses, final responses).
  • Some services (especially C-MOVE) don’t even return the actual images in the same association — instead, the SCP initiates new C-STORE sub-associations back to the SCU (your side). That requires your system to be running as an SCP, waiting for those stores.

If QIE just “spun up a socket” inside your HL7 channel and blocked waiting for one response, it wouldn’t be able to handle these multi-response or callback situations correctly.


The enforced split is Qvera saying “we’re going to model DICOM correctly, including async behavior, whether you’re using it in that way today or not.”


We are aware this can cause some confusion. Hence this KB article wink. We're also aware that sometimes the timeouts of the receiving channel come into play and appear to override the timeouts configured in the DICOM connection, so watch out for that as well as it can be a "gotcha"




Now in your specific example above, the error you're receiving:
Channel 'C-FIND via JSON' is not running.
is due to the fact that all qie.postDICOMRequest() calls must have a DICOM channel as mentioned above to receive the responses. In this case the channel is an HTTP listener with a JSON payload, not a DICOM Listener. Although the documentation for the call says that the "channel*" is optional, it's really only optional in the sense that it defaults to the current channel and expects it to be a DICOM listener.

by nathan-c-4426 (720 points)
edited by nathan-c-4426
...