Enet4 / dicom-rs

Rust implementation of the DICOM standard

Home Page:https://dicom-rs.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ERROR dicom_findscu: status code from response is missing

jennydaman opened this issue · comments

I seem to be unable to run dicom-findscu with Orthanc.

I set up Orthanc like this:

https://github.com/FNNDSC/oxidicom/blob/ad8582e90c1ef793871d3618048f0d6fe57fe1b0/docker-compose.yml#L5-L9

With this data:

https://github.com/datalad/example-dicom-structural

Using dcmtk works:

findscu -xi -S -k AccessionNumber -k AcquisitionProtocolDescription -k AcquisitionProtocolName -k InstanceNumber -k ModalitiesInStudy -k Modality -k NumberOfPatientRelatedInstances -k NumberOfPatientRelatedSeries -k NumberOfPatientRelatedStudies -k NumberOfSeriesRelatedInstances -k NumberOfStudyRelatedInstances -k NumberOfStudyRelatedSeries -k PatientAge -k PatientBirthDate -k PatientID -k PatientName=Jane_Doe -k PatientSex -k PerformedStationAETitle -k ProtocolName -k QueryRetrieveLevel=STUDY -k SeriesDate -k SeriesDescription -k SeriesInstanceUID -k StudyDate -k StudyDescription -k StudyInstanceUID -aec OXIORTHANCTEST -aet OXIDICOMTEST localhost 4242 

But dicom-findscu of dicom-rs causes an error:

$ cargo run --bin dicom-findscu -- localhost:4242 --calling-ae-title=OXIDICOMTEST --called-ae-title=OXIORTHANCTEST --study -q PatientName='Jane_Doe'

------------------------ Match #0 ------------------------
(0008,0005) SpecificCharacterSet         CS (1, 10 bytes): "ISO_IR 100"
(0008,0052) QueryRetrieveLevel           CS (1,  6 bytes): "STUDY"
(0008,0054) RetrieveAETitle              AE (1, 14 bytes): "OXITESTORTHANC"
(0010,0010) PatientName                  PN (1,  8 bytes): "Jane_Doe"
2024-03-19T04:12:57.046352Z ERROR dicom_findscu: status code from response is missing

Thank you for reporting. Would you be able to include some verbose output of that call to Dcmtk's findscu?

In any case, this might be a regression from the changes done in #434.

D: $dcmtk: findscu v3.6.8 2023-12-19 $
D:
D: DcmDataDictionary: Loading file: /usr/share/dcmtk-3.6.8/dicom.dic
D: Request Parameters:
D: ====================== BEGIN A-ASSOCIATE-RQ =====================
D: Our Implementation Class UID:      1.2.276.0.7230010.3.0.3.6.8
D: Our Implementation Version Name:   OFFIS_DCMTK_368
D: Their Implementation Class UID:
D: Their Implementation Version Name:
D: Application Context Name:    1.2.840.10008.3.1.1.1
D: Calling Application Name:    OXIDICOMTEST
D: Called Application Name:     OXIORTHANCTEST
D: Responding Application Name:
D: Our Max PDU Receive Size:    16384
D: Their Max PDU Receive Size:  0
D: Presentation Contexts:
D:   Context ID:        1 (Proposed)
D:     Abstract Syntax: =FINDStudyRootQueryRetrieveInformationModel
D:     Proposed SCP/SCU Role: Default
D:     Proposed Transfer Syntax(es):
D:       =LittleEndianImplicit
D: Requested Extended Negotiation: none
D: Accepted Extended Negotiation:  none
D: Requested User Identity Negotiation: none
D: User Identity Negotiation Response:  none
D: ======================= END A-ASSOCIATE-RQ ======================
I: Requesting Association
D: setting network send timeout to 60 seconds
D: setting network receive timeout to 60 seconds
D: Constructing Associate RQ PDU
D: PDU Type: Associate Accept, PDU Length: 184 + 6 bytes PDU header
D:   02  00  00  00  00  b8  00  01  00  00  4f  58  49  4f  52  54
D:   48  41  4e  43  54  45  53  54  20  20  4f  58  49  44  49  43
D:   4f  4d  54  45  53  54  20  20  20  20  00  00  00  00  00  00
D:   00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
D:   00  00  00  00  00  00  00  00  00  00  10  00  00  15  31  2e
D:   32  2e  38  34  30  2e  31  30  30  30  38  2e  33  2e  31  2e
D:   31  2e  31  21  00  00  19  01  00  00  00  40  00  00  11  31
D:   2e  32  2e  38  34  30  2e  31  30  30  30  38  2e  31  2e  32
D:   50  00  00  3a  51  00  00  04  00  00  40  00  52  00  00  1b
D:   31  2e  32  2e  32  37  36  2e  30  2e  37  32  33  30  30  31
D:   30  2e  33  2e  30  2e  33  2e  36  2e  38  55  00  00  0f  4f
D:   46  46  49  53  5f  44  43  4d  54  4b  5f  33  36  38
D: Parsing an A-ASSOCIATE PDU
D: Association Parameters Negotiated:
D: ====================== BEGIN A-ASSOCIATE-AC =====================
D: Our Implementation Class UID:      1.2.276.0.7230010.3.0.3.6.8
D: Our Implementation Version Name:   OFFIS_DCMTK_368
D: Their Implementation Class UID:    1.2.276.0.7230010.3.0.3.6.8
D: Their Implementation Version Name: OFFIS_DCMTK_368
D: Application Context Name:    1.2.840.10008.3.1.1.1
D: Calling Application Name:    OXIDICOMTEST
D: Called Application Name:     OXIORTHANCTEST
D: Responding Application Name: OXIORTHANCTEST
D: Our Max PDU Receive Size:    16384
D: Their Max PDU Receive Size:  16384
D: Presentation Contexts:
D:   Context ID:        1 (Accepted)
D:     Abstract Syntax: =FINDStudyRootQueryRetrieveInformationModel
D:     Proposed SCP/SCU Role: Default
D:     Accepted SCP/SCU Role: Default
D:     Accepted Transfer Syntax: =LittleEndianImplicit
D: Requested Extended Negotiation: none
D: Accepted Extended Negotiation:  none
D: Requested User Identity Negotiation: none
D: User Identity Negotiation Response:  none
D: ======================= END A-ASSOCIATE-AC ======================
I: Association Accepted (Max Send PDV: 16372)
I: Sending Find Request
D: ===================== OUTGOING DIMSE MESSAGE ====================
D: Message Type                  : C-FIND RQ
D: Presentation Context ID       : 1
D: Message ID                    : 1
D: Affected SOP Class UID        : FINDStudyRootQueryRetrieveInformationModel
D: Data Set                      : present
D: Priority                      : medium
D: ======================= END DIMSE MESSAGE =======================
I: Request Identifiers:
I:
I: # Dicom-Data-Set
I: # Used TransferSyntax: Little Endian Explicit
I: (0008,0020) DA (no value available)                     #   0, 0 StudyDate
I: (0008,0021) DA (no value available)                     #   0, 0 SeriesDate
I: (0008,0050) SH (no value available)                     #   0, 0 AccessionNumber
I: (0008,0052) CS [STUDY]                                  #   6, 1 QueryRetrieveLevel
I: (0008,0060) CS (no value available)                     #   0, 0 Modality
I: (0008,0061) CS (no value available)                     #   0, 0 ModalitiesInStudy
I: (0008,1030) LO (no value available)                     #   0, 0 StudyDescription
I: (0008,103e) LO (no value available)                     #   0, 0 SeriesDescription
I: (0010,0010) PN [Jane_Doe]                               #   8, 1 PatientName
I: (0010,0020) LO (no value available)                     #   0, 0 PatientID
I: (0010,0030) DA (no value available)                     #   0, 0 PatientBirthDate
I: (0010,0040) CS (no value available)                     #   0, 0 PatientSex
I: (0010,1010) AS (no value available)                     #   0, 0 PatientAge
I: (0018,1030) LO (no value available)                     #   0, 0 ProtocolName
I: (0018,9423) LO (no value available)                     #   0, 0 AcquisitionProtocolName
I: (0018,9424) LT (no value available)                     #   0, 0 AcquisitionProtocolDescription
I: (0020,000d) UI (no value available)                     #   0, 0 StudyInstanceUID
I: (0020,000e) UI (no value available)                     #   0, 0 SeriesInstanceUID
I: (0020,0013) IS (no value available)                     #   0, 0 InstanceNumber
I: (0020,1200) IS (no value available)                     #   0, 0 NumberOfPatientRelatedStudies
I: (0020,1202) IS (no value available)                     #   0, 0 NumberOfPatientRelatedSeries
I: (0020,1204) IS (no value available)                     #   0, 0 NumberOfPatientRelatedInstances
I: (0020,1206) IS (no value available)                     #   0, 0 NumberOfStudyRelatedSeries
I: (0020,1208) IS (no value available)                     #   0, 0 NumberOfStudyRelatedInstances
I: (0020,1209) IS (no value available)                     #   0, 0 NumberOfSeriesRelatedInstances
I: (0040,0241) AE (no value available)                     #   0, 0 PerformedStationAETitle
I:
D: DcmDataset::read() TransferSyntax="Little Endian Implicit"
D: DcmDataset::read() TransferSyntax="Little Endian Implicit"
I: Received Find Response 1
D: ===================== INCOMING DIMSE MESSAGE ====================
D: Message Type                  : C-FIND RSP
D: Message ID Being Responded To : 1
D: Affected SOP Class UID        : FINDStudyRootQueryRetrieveInformationModel
D: Data Set                      : present
D: DIMSE Status                  : 0xff00: Pending: Matches are continuing
D: ======================= END DIMSE MESSAGE =======================
D: Response Identifiers:
D:
D: # Dicom-Data-Set
D: # Used TransferSyntax: Little Endian Implicit
D: (0008,0005) CS [ISO_IR 100]                             #  10, 1 SpecificCharacterSet
D: (0008,0020) DA [20130717]                               #   8, 1 StudyDate
D: (0008,0021) DA [20130717]                               #   8, 1 SeriesDate
D: (0008,0050) SH (no value available)                     #   0, 0 AccessionNumber
D: (0008,0052) CS [STUDY ]                                 #   6, 1 QueryRetrieveLevel
D: (0008,0054) AE [OXITESTORTHANC]                         #  14, 1 RetrieveAETitle
D: (0008,0060) CS [MR]                                     #   2, 1 Modality
D: (0008,0061) CS [MR]                                     #   2, 1 ModalitiesInStudy
D: (0008,1030) LO [Hanke_Stadler^0024_transrep ]           #  28, 1 StudyDescription
D: (0008,103e) LO [anat-T1w]                               #   8, 1 SeriesDescription
D: (0010,0010) PN [Jane_Doe]                               #   8, 1 PatientName
D: (0010,0020) LO [02]                                     #   2, 1 PatientID
D: (0010,0030) DA [19660101]                               #   8, 1 PatientBirthDate
D: (0010,0040) CS [F ]                                     #   2, 1 PatientSex
D: (0010,1010) AS [42]                                     #   2, 1 PatientAge
D: (0018,1030) LO [anat-T1w]                               #   8, 1 ProtocolName
D: (0018,9423) LO (no value available)                     #   0, 0 AcquisitionProtocolName
D: (0018,9424) LT (no value available)                     #   0, 0 AcquisitionProtocolDescription
D: (0020,000d) UI [1.2.826.0.1.3680043.2.1143.2592092611698916978113112155415165916] #  64, 1 StudyInstanceUID
D: (0020,000e) UI [1.2.826.0.1.3680043.2.1143.515404396022363061013111326823367652] #  64, 1 SeriesInstanceUID
D: (0020,0013) IS [1 ]                                     #   2, 1 InstanceNumber
D: (0020,1200) IS (no value available)                     #   0, 0 NumberOfPatientRelatedStudies
D: (0020,1202) IS (no value available)                     #   0, 0 NumberOfPatientRelatedSeries
D: (0020,1204) IS (no value available)                     #   0, 0 NumberOfPatientRelatedInstances
D: (0020,1206) IS [1 ]                                     #   2, 1 NumberOfStudyRelatedSeries
D: (0020,1208) IS [384 ]                                   #   4, 1 NumberOfStudyRelatedInstances
D: (0020,1209) IS (no value available)                     #   0, 0 NumberOfSeriesRelatedInstances
D: (0040,0241) AE (no value available)                     #   0, 0 PerformedStationAETitle
D:
D: DcmDataset::read() TransferSyntax="Little Endian Implicit"
I: Received Final Find Response
D: ===================== INCOMING DIMSE MESSAGE ====================
D: Message Type                  : C-FIND RSP
D: Message ID Being Responded To : 1
D: Affected SOP Class UID        : FINDStudyRootQueryRetrieveInformationModel
D: Data Set                      : none
D: DIMSE Status                  : 0x0000: Success: Matching is complete
D: ======================= END DIMSE MESSAGE =======================
I: Releasing Association

I took a look at #434 and blindly tried to undo it:

diff --git a/findscu/src/main.rs b/findscu/src/main.rs
index 0b176b5..8168d60 100644
--- a/findscu/src/main.rs
+++ b/findscu/src/main.rs
@@ -281,6 +281,7 @@ fn run() -> Result<(), Error> {
                         .dump_object_to(stderr(), &cmd_obj)
                         .context(DumpOutputSnafu)?;
                 }
+
                 let status = cmd_obj
                     .get(tags::STATUS)
                     .whatever_context("status code from response is missing")?
@@ -324,9 +325,10 @@ fn run() -> Result<(), Error> {
                     // upon sending the response data
                     let status = dcm
                         .get(tags::STATUS)
-                        .whatever_context("status code from response is missing")?
-                        .to_int::<u16>()
-                        .whatever_context("failed to read status code")?;
+                        .map(|ele| ele.to_int::<u16>())
+                        .transpose()
+                        .whatever_context("failed to read status code")?
+                        .unwrap_or(0);
 
                     if status == 0 {
                         if verbose {

The result of dicom-findscu is now that it exits gracefully, nor do I see errors in Orthanc's logs. However I don't actually know what the protocol is so I am not sure whether this is a well-behaved solution.