image hash question: 1.5.8 versus 1.9.0

Hi all,

I’m using Orthanc 1.5.8 in an MRI research group, and built a test small suite for my code. Its great to have a lightweight, free, open-source DICOM receiver. Thanks!

I’m using as close to the default configuration as I can, sqlite database in particular. I just compiled v1.9.0 to try it out, but one of my tests is now failing.

That test compares a sha256sum of an image before I send it into Orthanc (using dcmsend, creating a whole study consisting of one image) and a hash of the image after downloading from Orthanc as a .zip archive (curl http://…/studies/…/archive --output file.zip --silent). I then unzip to access the .dcm file, and get the hash.

In 1.5.8, I see an exact match of pre & post hash values, meaning its the same image bit for bit. In 1.9.0, the hashes do not match (wildly different), whereas all other of my tests are passing.

Is this expected behavior? What is now changing in transit? (Sorry if this has been asked before, I searched and could not find anything on this.)

Thanks,

–Jeremy

Dear Jeremy,

I suspect your question is related to the introduction of ingest transcoding between 1.5.8 and 1.9.0:
https://book.orthanc-server.com/faq/transcoding.html

The configuration option “AcceptedTransferSyntaxes” might be worth a review:

// The transfer syntaxes that are accepted by Orthanc C-STORE SCP.
// This is an array listing the accepted transfer syntax UIDs. Each
// entry can contain wildcards (“?” or “"). By default, all the
// known transfer syntaxes are accepted. (new in Orthanc 1.9.0)
“AcceptedTransferSyntaxes” : [ "1.2.840.10008.1.
” ],

In order to provide further support, we would need a full minimal working example (configuration file, sample DICOM image, a sequence of command lines, and observed vs. expected results) in order for the community to independently reproduce your issue:
https://book.orthanc-server.com/users/support.html#discussing-a-minimal-working-example

Regards,
Sébastien-

Thanks Sébastien. Very interesting. I’m trying to speed up transfer from the scanner to Orthanc, so might eventually want lossless compression / decompression. For now, I’d just like to ensure I understand the issues.

I reviewed the page you linked, could not find “AcceptedTransferSyntaxes” but these looked promising
TranscodeDicomProtocol: false
IngestTranscodingOfUncompressed: false

But I get the same observed behavior, so I would appreciate community help.

–Jeremy

Sample image: attached, phantom1.dcm

My explicit config:
{

“StorageDirectory”: “***”,
“StorageCompression”: false,
“MaximumStorageSize”: 600,
“IngestTranscodingOfUncompressed”: false,
“TranscodeDicomProtocol”: false,
“KeepAlive”: true,
“TcpNoDelay”: true

“Name”: “",
“DicomAet”: "
”,
“StableAge”: 3,
“LogExportedResources”: false,
“RemoteAccessAllowed”: false,
“OrthancExplorerEnabled” : false,
“DicomCheckCalledAet” : true

“DicomPort”: 4241,
“HttpPort”: 8041,
“WebDavEnabled”: false
}
From the log at startup:
W0401 06:59:16.216617 main.cpp:1850] Orthanc version: 1.9.0
I0401 06:59:16.216689 main.cpp:1882] Architecture: 64-bit, little endian

I0401 06:59:16.246882 ServerContext.cpp:372] Automated transcoding of incoming DICOM instances is disabled
I0401 06:59:16.246936 ServerContext.cpp:402] (dicom) Preferred transfer syntax for Orthanc C-STORE SCU: 1.2.840.10008.1.2.1

Sequence of commands to reproduce:
sha256sum phantom1.dcm

dcmsend -ma --call ${DICOMAET} localhost 4241 phantom1.dcm
curl http://localhost:8041/studies/4741d915-c79a191f-2e713fb6-363fb97d-645a33a6/archive --output file.zip --silent
unzip -q file.zip -d expanded
find expanded -type f -exec sha256sum {} ;

Expected / Observed

  1. Expect identical sha256sums. Observed:
    df118dd6885e51ea663d1e14d097191c1c63a1cb3801d708f4c687d7a8bb6a13 phantom1.dcm
    4d6a4d7298c08c1deb10e13bcb37f81d1d6e61e4dfe0deef8a7a4d65f966512e expanded/M750…/MR000000.dcm

  2. As expected and observed: the DICOM headers report the same transfer syntax pre and post:

(0002, 0010) Transfer Syntax UID UI: Explicit VR Little Endian

phantom1.dcm (260 KB)

Same result with a thinner example, same image file

Configs:
{
“IngestTranscodingOfUncompressed”: false,
“TranscodeDicomProtocol”: false,
“DicomPort”: 4241,
“HttpPort”: 8041
}

Commands (bash):
sha256sum phantom1.dcm
dcmsend localhost 4241 phantom1.dcm
curl http://localhost:8041/studies/4741d915-c79a191f-2e713fb6-363fb97d-645a33a6/archive --output file.zip --silent
unzip -q file.zip -d expanded
find expanded -type f -exec sha256sum {} ;

Hi Jeremy,
Maybe you’ve tried done this already but it might be useful to use some utility to dump out the DICOM headers of the “before” and “after” images to separate text files and compare those files to see if any attributes have been added, deleted or modified during the round trip.
Cheers,
Wilf.

Thanks Wilf, good idea, but there are no clues there that I can see, at least not when using dcmdump or pydicom.read_file(). Identical headers before and after (using diff or a hash), 230 lines each from dcmdump, 206 lines each from pydicom.read_file()

Hello,

Here are the results of my investigations. Contrarily to my assumption in my previous message, this is not at all related to transcoding. I have run the following commands on my Ubuntu 18.04 (the version of DCMTK is 3.6.2), starting Orthanc without any configuration file (i.e. with all the default options):

$ dcmsend localhost 4242 phantom1.dcm
$ curl http://localhost:8042/instances/67036751-1373a473-607e4de7-ec109167-d78bdcd0/file > orthanc.dcm

$ dcm2xml phantom1.dcm > phantom1.xml
$ dcm2xml orthanc.dcm > orthanc.xml

$ diff phantom1.xml orthanc.xml

9,10c9,10
< 1.2.276.0.7230010.3.0.3.6.4
< OFFIS_DCMTK_364

Drat, my mistake, there ARE two differences in the headers before & after when using 1.9.0 (per below) that are not there for 1.5.8:

< (0002,0012) UI [1.2.276.0.7230010.3.0.3.6.4] # 28, 1 ImplementationClassUID
< (0002,0013) SH [OFFIS_DCMTK_364] # 16, 1 ImplementationVersionName

Thanks Sébastien! Yes, I made a static build of 1.9.0. Confirmed, using the REST API instead of dcmsend gives me identical pre-post hashes, super. Time to rewrite my test. I’ve also learned about transcoding, so thanks for that as well.

I see below that the mystery is resolved! Great news!