Skip to content

Fix Harmowy worklist server#528

Merged
Enet4 merged 1 commit intoEnet4:masterfrom
qarmin:fix_topcon_worklist_server
Jun 28, 2024
Merged

Fix Harmowy worklist server#528
Enet4 merged 1 commit intoEnet4:masterfrom
qarmin:fix_topcon_worklist_server

Conversation

@qarmin
Copy link
Copy Markdown

@qarmin qarmin commented Jun 27, 2024

Fixes #527
Fixes #522

After several attempts, it turned out that Harmony sends all the data at once, unlike orthanc and https://dicomserver.co.uk/

Now downloading patient data from Harmony works fine

Screenshot from 2024-06-27 10-41-37

@qarmin qarmin force-pushed the fix_topcon_worklist_server branch from ecdc685 to 0817636 Compare June 27, 2024 08:50
@Enet4 Enet4 added bug This is a bug A-tool Area: tooling C-findscu Crate: dicom-findscu labels Jun 27, 2024
Copy link
Copy Markdown
Owner

@Enet4 Enet4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the chance to test it out with some other DICOM SCPs, no issues were detected. The code is also sound.

Thank you very much for the patch! 👍

@Enet4 Enet4 merged commit 8b4b676 into Enet4:master Jun 28, 2024
if data.is_empty() {
error!("Empty PData response");
break;
} else if ![1, 2].contains(&data.len()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Enet4 thanks for mentioning my issue so I can see this!

I know this is already merged, but where is this specified in the standard, I see this section, but that seems to indicate that we should allow multiple command and data fragments within the same PDU, just not send them:

It is strongly recommended that two consecutive PDVs in the same P-DATA Request primitive (therefore containing fragments of the same message using the same Presentation Context ID) do not contain two message Control Headers with the same type (Command or Data). These should have been combined in a single PDV by the sender. However, receivers must be able to receive and process such PDVs.

https://dicom.nema.org/medical/dicom/current/output/chtml/part08/chapter_E.html

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know of any server that would send such data, to be able to test potential fix?

I know that this PR not provided fix for all possible situations in dicom standard but I was only able to test 1 command + 1 data message

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know of an open source server that does this. I've been writing a query-retrieve program against (I think) a GE PACS server deployed as the main PACS for a hospital, and it sometimes does that. I was meaning to contribute something back here once I have the time. Basically what I came up with was like this:

pub fn read_pdata(
    data: Vec<PDataValue>,
    ts: &TransferSyntax,
) -> Result<(Option<InMemDicomObject>, Option<InMemDicomObject>), Error> {
    let mut ds_buffer = Vec::new();
    let mut cs_buffer = Vec::new();
    for pdata in data {
        match pdata.value_type {
            PDataValueType::Command => {
                cs_buffer.extend(pdata.data);
            }
            PDataValueType::Data => {
                ds_buffer.extend(pdata.data);
            }
        }
    }
    let data_set = if ds_buffer.len() > 0 {
        Some(
            InMemDicomObject::read_dataset_with_ts(&ds_buffer[..], ts)
                .whatever_context("Could not parse dicom dataset")?,
        )
    } else {
        None
    };
    let command_set = if cs_buffer.len() > 0 {
        Some(
            InMemDicomObject::read_dataset_with_ts(
                &cs_buffer[..],
                &entries::IMPLICIT_VR_LITTLE_ENDIAN.erased(),
            )
            .whatever_context("Could not parse dicom command set")?,
        )
    } else {
        None
    };
    Ok((command_set, data_set))
}

And then in my downstream findscu and movescu I use

...
    loop {
        let rsp = scu.receive().unwrap();
        match rsp {
            Pdu::PData { data } => {
                let (maybe_cmd, _maybe_ds) =
                    read_pdata(data, ts).whatever_context("Failed to read response data")?;
                let cmd = maybe_cmd.whatever_context("No command set preset in PDU")?;
...

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I ended up accepting because it covers all the reasonably probable scenarios I could think of:

  • 1 PDV per PData (Command/Data interleaved)
  • 2 PDVs in a single PData (1 command and 1 data)
  • 0 PDVs (?)
  • 1 Command PDV reporting status code 0 (no results)

I did not envision the scenario of having multiple PDVs of the same type, though it's good to know that it might happen in some exotic implementation. I was also imagining a scenario of a single PData holding more than one Cmd-Data pair, but it did not seem to be very likely (though it seems to be valid per the standard!).

Copy link
Copy Markdown
Owner

@Enet4 Enet4 Jun 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, there is nothing preventing us from reiterating on findscu further, with other PRs. For example, the idea of splitting these tools into a library and binary is worth conceiving at some point in the project.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yea, no problem for sure. Sometime in the next few weeks I will probably contribute a bit of that (modularizing find-scu) and potentially this multi-data-pdv function as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-tool Area: tooling bug This is a bug C-findscu Crate: dicom-findscu

Projects

None yet

Development

Successfully merging this pull request may close these issues.

findscu not working when dataset is included in C-FIND-RSP

3 participants