It all started when I was sitting in a cubicle with a customer, looking at the code of their workstation performing a Query/Retrieve cycle and though everything did look familiar and pretty much straight forward something bothered me.
Query/Retrieve, or Q/R for short, is the DICOM service for searching images on the PACS and getting a copy of them to the workstation where they can be displayed.
Q/R is a fundamental service and every workstation implements it. This sounds like a trivial task, just like downloading a zip file from a web site but there are a lot of details to take care of and while writing this post I realized that I will have to split it to a little sub-series. Today's post will be about the Query part and in the next post I'll get to the Retrieve.
To search the PACS we use the DICOM command C-FIND. This command takes as an argument a DICOM object that represent a query. The PACS transforms the object that we send to a query, probably to SQL, runs it and then transform every result record back into a DICOM object and send it back to us in a C-FIND response. The PACS sends one C-FIND response for every result record. While still running, the status field of the C-FIND response command is pending (0xFF00). The last response has a status success. It may of course fail and then RZDCX will throw an exception with the failure reason and status. It may also succeed but with no matches (empty results set).
To search the PACS we use the DICOM command C-FIND. This command takes as an argument a DICOM object that represent a query. The PACS transforms the object that we send to a query, probably to SQL, runs it and then transform every result record back into a DICOM object and send it back to us in a C-FIND response. The PACS sends one C-FIND response for every result record. While still running, the status field of the C-FIND response command is pending (0xFF00). The last response has a status success. It may of course fail and then RZDCX will throw an exception with the failure reason and status. It may also succeed but with no matches (empty results set).
Let's do some examples. This code constructs a query for searching patients:
// Fill the query object
DCXOBJ obj = new DCXOBJ();
DCXELM el = new DCXELM();
el.Init((int)DICOM_TAGS_ENUM.QueryRetrieveLevel);
el.Value = "PATIENT";
obj.insertElement(el);
el.Init(0x00100010);
el.Value = "R*";
obj.insertElement(el);
el.Init(0x00100020);
obj.insertElement(el);
el.Init((int)DICOM_TAGS_ENUM.PatientsSex);
obj.insertElement(el);
el.Init((int)DICOM_TAGS_ENUM.PatientsBirthDate);
obj.insertElement(el);