How can I do a DICOM query and retrieve from a Ginkgo PACS (or any other) using dcm4che - dicom

I'm writing a "simple" HL7 listener and then using the dcm4che binary utility movescu to make a query and retrieve operation from a remote PACS
I need to retrieve a Study and I have (00080050) AccessionNumber from the HL7 data, then I do the following:
./movescu -b LOCALAET#{local_ip}:044 -c REMOTEAET#{remote_ip}:104 --dest LOCALAET#{local_ip}:104 -m 00080050={known_accession_number}
with a remote PACS I am getting this:
(0000,0002) UI [1.2.840.10008.5.1.4.1.2.2.2] AffectedSOPClassUID
(0000,0100) US [32801] CommandField
(0000,0120) US [1] MessageIDBeingRespondedTo
(0000,0800) US [257] CommandDataSetType
(0000,0900) US [49152] Status
(0000,0902) LO [Error querying db (ImageRetrieve)] ErrorComment
(0000,1020) US [0] NumberOfRemainingSuboperations
(0000,1021) US [0] NumberOfCompletedSuboperations
(0000,1022) US [0] NumberOfFailedSuboperations
(0000,1023) US [0] NumberOfWarningSuboperations
And with a local Ginkgo I am getting:
17:12:58,906 DEBUG - LOCALAET->REMOTEAET(1): enter state: Sta6 - Association established and ready for data transfer
17:12:58,946 INFO - LOCALAET->REMOTEAET(1) >> A-ABORT[source: 0 - service-user, reason: 0]
17:12:58,946 INFO - LOCALAET->REMOTEAET(1): close Socket[addr=/XXX.XXX.X.XX,port=8080,localport=36105]
17:12:58,947 DEBUG - LOCALAET->REMOTEAET(1): enter state: Sta1 - Idle
movescu: Sta1 - Idle
org.dcm4che3.net.AssociationStateException: Sta1 - Idle
at org.dcm4che3.net.State.writeAReleaseRQ(State.java:223)
at org.dcm4che3.net.Association.release(Association.java:326)
at org.dcm4che3.tool.movescu.MoveSCU.close(MoveSCU.java:331)
at org.dcm4che3.tool.movescu.MoveSCU.main(MoveSCU.java:268)
(using different port on Ginkgo)
So what am I missing?

I do not know the Ginkgo PACS, but quite likely your retrieval fails because your request is malformed.
See PS3.4, C.4.2.1.4.1 Request Identifier Structure
Your request must include the attribute Query Retrieve Level (0008,0052) which I assume will be "STUDY" in your case since the Accession Number is a study-level attribute.
Furthermore it must contain
"Unique Key Attributes, which may include Patient ID (0010,0020),
Study Instance UIDs (0020,000D), Series Instance UIDs (0020,000E), and
the SOP Instance UIDs (0008,0018)"
That is, you have to specify the scope of your retrieve request by providing unique identifiers for the patient/study/series/image(s) you want to move - and nothing else!
So Accession Number may be used to query (C-FIND) for the corresponding Study Instance UID that you need for the C-MOVE. But it is not allowed in the C-MOVE-Request.
Caution: Whether or not you must include or omit the Patient-ID (0010,0020) in your C-MOVE request depends on the information model that you have negotiated during association establishment and that you select by choosing the presentation context for your message. You must include it in Patient Root, you must not include it in Study Root.

Related

Multiple states in same contract is failing at verify

This is what I have implemented in my CordApp:
Now while doing flow test, It's passing till Contract C. But the flow test for Contract D is failing. According to logs, it's trying to validate all states(i.e i/p and o/p) using same Command.
I found one similar question: Transaction verification failed when using different type of states as input and output
But if that was true than my Contract C Flow test cases should have also failed?
Nevertheless, as mentioned in answer, I removed validation for input states in contract D, so that one contract will validate only one state. But still same error is coming.
Any pointer on what is going wrong?
Note that:
Contracts do not verify individual states, they verify entire transactions
When verifying a transaction, the contracts of both the input and output states are run
So in your case, if I understand your diagram correctly:
The first transaction (from the left) has no inputs, output StateA, and is verified by running ContractA (associated with StateA)
The second transaction has no inputs, output StateB, and is verified by running ContractB (associated with StateB)
The third transaction has input StateB, output StateC, and is verified by running ContractB (associated with StateB) and ContractC (associated with StateC)
The fourth transaction (on the far-right) has inputs StateA and StateC, output StateD, and is verified by running ContractA (associated with StateA), ContractC (associated with StateC) and ContractD (associated with StateD)

DICOM : Is this a valid Associate Response?

My application is Storage SCU. It pushes NM and CT instances to third party PACS. I am proposing four presentation context in my association (Associate Request). PACS is responding (Associate Response) like below:
Application Context: DICOM Application Context Name
Implementation Class: 1.2........
Implementation Version: XYZ
Maximum PDU Size: 32768
Called AE Title: PACS
Calling AE Title: MyApp
Presentation Contexts: 4
Presentation Context: 1 [Accept]
Abstract: Nuclear Medicine Image Storage
Transfer: Explicit VR Little Endian
Presentation Context: 3 [Reject - Transfer Syntaxes Not Supported]
Abstract: Nuclear Medicine Image Storage
Transfer: JPEG 2000 Lossy
Presentation Context: 5 [Proposed]
Abstract: CT Image Storage
Transfer: Explicit VR Little Endian
Presentation Context: 7 [Reject - Transfer Syntaxes Not Supported]
Abstract: CT Image Storage
Transfer: JPEG 2000 Lossy
Second and fourth (id 3 and 7) presentation context is rejected as expected. PACS DICOM Conformance statement states that it does not support that transfer syntax.
First (id 1) presentation context is accepted as expected.
Look at third (id 5) presentation context. It's status says [Proposed].
In my understanding, PACS should either accept the presentation context or reject it. It must not keep the status [Proposed] as is which was set by SCU i.e. my application.
Is my understanding correct?
I am looking in to specifications to find something concluding; no success so far. Please point me to the location in specifications where this is explained.
Edit 1:
PS 3.7-2011 - Message Exchange
D.3.2 Presentation contexts negotiation
c. the Association-acceptor may accept or reject each Presentation
Context individually.
Look at the may in specifications. What does this mean? Is it up to the SCP to "accept or reject (or leave as is i.e. [proposed])" the status?
"Proposed" means that the SCP didn't include in the reply the abstract syntax with the proper code:
0 acceptance​
1 user-rejection​
2 no-reason (provider rejection)​
3 abstract-syntax-not-supported (provider rejection)​
4 transfer-syntaxes-not-supported (provider rejection)​
Therefore DCMTK leaves in the abstract syntax the original status of "Not yet negotiated" (printed as "proposed" in the logs).
In DCMTK this status is represented by the constant ASC_P_NOTYETNEGOTIATED.
It looks like the SCP is to blame here

DCMTK findscu returns multiple results when one is expected

I am trying to run a c-move to get a RTDOSe from a given RTPlan, first I tried to find the rtdose that references my rtplan. I expected that result to be a single item but I am getting multiple items. Here is my find scu:
findscu -v -aet DCMTK -aec VMSDBD1 -S -k "0008,0052=IMAGE" -k "0008,0016=1.2.840.10008.5.1.4.1.1.481.2" -k "0020,000D=1.2.xxx.xxx.71.1.xxx173684671.xxxx20.20160817145909" -k "(300c,0002)[0].ReferencedSOPInstanceUID=1.2.xxx.xxx.71.5.xxxx73684671.xxxx31.2016092318xxxx" xx.xx.xx.20 5678
I get a result like:
W: Find Response: 1 (Pending)
(...)
W: Find Response: 2 (Pending)
I: ===================== INCOMING DIMSE MESSAGE ====================
I: Message Type : C-FIND RSP
I: Message ID Being Responded To : 1
I: Affected SOP Class UID : FINDStudyRootQueryRetrieveInformationModel
I: Data Set : none
I: DIMSE Status : 0x0000: Success
I: ======================= END DIMSE MESSAGE =======================
I: Releasing Association
Question 1: why am I getting multiple results instead of the one dose that references the RTpLAN ?
Question 2: after replacing findscu by movescu I get an error about the syntax:
"(300c,0002)[0].ReferencedSOPInstanceUID= ...
Is this syntax not supported for movescu ?
Given an RTPLAN object, how would you query the corresponding RTDOSE ?
Thank you.
GT
Your C-FIND request (using findscu) is not standard conformant: When querying on IMAGE level in Study Root Information Model you also have to specify the Series Instance UID. Furthermore, you should make sure that your other query keys are actually supported by the SCP.
Is this syntax not supported for movescu ?
This C-MOVE request (using movescu) is also not standard conformant: When retrieving DICOM objects on IMAGE level in Study Root Information Model you have to specify the Study Instance UID, the Series Instance UID and the SOP Instance UID. The Referenced SOP Instance UID (as part of the Referenced RT Plan Sequence) is not supported for this service / message.
See DICOM PS3.4 for details on the Query/Retrieve Service.
Added on 2016-01-09:
I forgot to answer your final question:
Given an RTPLAN object, how would you query the corresponding RTDOSE ?
I would check whether the Referenced Dose Sequence (300C,0080) is present in the RT Plan object, and if so, use the Referenced SOP Instance UID(s) from the contained item(s) for a subsequent retrieve (i.e. C-MOVE request).

Yet another catch 22 in BizTalk generating 999

I have asked another question with almost same scenario, A catch 22 in generating 999 file
Basically, I am inbounding HIPPA 837 files and am required to generate 999 response file.
Today I inbounded a file with ST02 element missing.
The TA1 created with Accept status, cause it only cares ISA-IEA level and that part is good.
BizTalk inbounded the file, found the issue, and actually generated a 999 message, but it failed to send out as a physical file because:
Unable to read the stream produced by the pipeline.
Details: Error: 1 (Field level error)
SegmentID: AK2
Position in TS: 3
Data Element ID: AK202
Position in Segment: 2
Data Value:
1: Mandatory data element missing
So here's the catch 22: A 999 should be created to report error for this incoming 837 file, The 999's AK202 is a required field reference to incoming file's transactionnumber defined in ST02.
And the error of the incoming file is it is missing this ST02.
Now, for this scenario, it ends up with an accept TA1 and a pending message in BizTalk messageBox.
In our trading partners view, they send a file and ONLY get a TA1 response with accept status.
My question goes here:
1. Which is the right file to report this kind of error (ST02 missing), TA1 or 999?
Is there anyway to bypass this error and have the 999 created?
There's an RFI on this at x12.org: http://rfi.x12.org/Request/Details/55?stateViewModel=WPC.RFI.Models.ViewModels.RequestViewModel
The TLDR version: you should reject the entire functional group, and use the control identifier from the functional group in AK202.
Here's the relevant text:
Description
What Segments/Data Elements should be used in the 997 when reporting an error in ST02 (Transaction Set Control Number) when the error is related to syntax or min/max? If you attempt to create a 997 back to the submitter with the inbound data from ST02 in AK202 of the 997 you would be creating an invalid 997 transaction. It appears there may be a gap in the 997 standard for reporting errors at this level. If we have misinterpreted the use of the transaction and it can be reported, please let us know how.
Response
Data elements AK102 and AK202 located within transaction set 997 and transaction set 999 are to be used to convey the values of control numbers in the functional group or transaction sets being acknowledged. If including a copy of the value of a data element in the 997 or 999 would cause a syntax violation in the 997 or 999, then if the violation is to be reported at the level at which it was found it must be reported at the next higher level.
Recommendation
The official response to a formal RFI is a letter from the current ASC X12 chair. This website often displays a summary of the RFI. Click here to view a PDF of the letter for this RFI.
When reporting errors after the syntactic analysis of the transaction set, the data analyzed must be able to be reported within the acknowledgment. While data element AK404 supports reporting the value of a data element that fails syntactic analysis without violating the syntax of the 997, the same does not apply to AK202. There are two generally accepted methods of acknowledging transaction sets: 1) acknowledge all transaction sets within the functional group or 2) acknowledge only those transaction sets containing errors. It is not recommended to accept a functional group with errors if the transaction set control number in error cannot be reported in AK202. For the example in your request, the appropriate action is to reject the entire functional group containing the ST02 value which when echoed in AK202 would create a syntactically invalid 997. In addition, the same logic applies to the functional group control number;, the appropriate action is to reject the entire interchange containing the syntactically invalid data.

IPCS message passing related queries

I am dealing with Message Passing IPCS method. I do have few question regarding this:
KEY field in ipcs -q shows me 0x00000000 what does this means ?
Can i see what messsage is passes using msqid ?
If two entries are present (for a particular user) after executing command ipcs -q. Does this means that two messages were passed by this particular user ?
If used-bytes and message fields are set as 0 what does this mean?
Is there away to see if message queue is full or not?
How many queues can we have for one particular user?
I tried goggling, but was not able to find answer to these questions.
Please help
1. The "key" field of the Shared memory segments is usually 0x00000000. This indicates the IPC_PRIVATE key specified during creation of the shared memory segment. The manual of shmget() contains more details.
2. AFAIK, this cannot be done. If any msg is "de-queued" from the msgQ, then the intended receiver will not see it.
3. The 2 entries in the list of message queues indicates that there are currently 2 active message queues on the system identified by their corresponding unique keys.
Creating additional msgQ : ipcmk -Q
Deleting an existing msgQ : ipcrm -Q <unique-key>
4. The used-bytes and messages fields set to 0 indicate that currently no transfers have occurred using that particular msgQ.
5. Currently one way to do this to obtain the number of msgs currently queued-up in the msgQ programmatically as shown in the following C snippet. Next this can be compared with the size of the msgQ as demonstrated in this answer.
int ret = msgctl(msqid, IPC_STAT, &buf);
uint msg = (uint)(buf.msg_qnum);
printf("msgs in Q = %u\n", msg);
6. There exists a limit on the total memory used by all the msgQs on the system combined together. This can be obtained by ulimit -q. The amount of bytes used in a msgQ is listed under the used-bytes column in the output of ipcs -Q. The total number of msgQs is limited only by the amount of memory available to create a new msgQ from the msgQ memory pool limit seen above.
Also checkout the latter part of this answer for a few sample operations on POSIX message queues.

Resources