Conversation
ecdc685 to
0817636
Compare
Enet4
left a comment
There was a problem hiding this comment.
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! 👍
| if data.is_empty() { | ||
| error!("Empty PData response"); | ||
| break; | ||
| } else if ![1, 2].contains(&data.len()) { |
There was a problem hiding this comment.
@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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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")?;
...There was a problem hiding this comment.
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!).
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
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