DICOMweb server returns altered DICOM data

Hi,

I’m using the jodogne/orthanc-plugins:latest Docker image to run a DICOMweb server with the following minimum config:
{
“StorageDirectory”: “/var/lib/orthanc/db”,
“IndexDirectory”: “/var/lib/orthanc/db”,
“RemoteAccessAllowed”: true,
“AuthenticationEnabled”: false,
“Plugins”: [“/usr/local/share/orthanc/plugins”]
}

When I upload a certain DICOM RT Dose file (doesn’t seem to matter how), the (3004,000E) Dose Grid Scaling tag comes back altered when accessing the instance with the DICOMweb API. It’s correct the first time it’s accessed, but on all subsequent downloads, the tag comes back 1 when it should be 5.71519e-005. It’s also correct if I use the Orthanc REST API instead of DICOMweb.

This is using the attached DICOM file and the following URL to access:

http://localhost:8042/dicom-web/studies/2.16.840.1.114362.1.6.6.6.16802.9495211678.449811783.969.4346/series/2.16.840.1.114337.1.1.1502227388.0.1.3/instances/2.16.840.1.114337.1.1.1502227388.2

Anyone know what could cause this?

Thanks

dose.dcm (20.6 KB)

Hi Christopher,

Could you provide a script or accurate instructions for us to reproduce the issue ? e.g a script with a client that retrieves and parses the response and extracts the value of the given tag ?

Thanks for your help.

Alain.

Hi Alain,

To be clear about the steps:

  1. “docker run -d -p 8055:8042 -v $PWD/orthanc_config:/etc/orthanc jodogne/orthanc-plugins” where ./orthanc_config contains an orthanc.json with the config from my original post.

  2. “curl -X POST http://localhost:8055/instances --data-binary @dose.dcm” to upload the dose file attached in my original post.

  3. Access with Postman the first time:
    1st.png

  4. Resending the same request gets the altered result. See the highlighted value and the different Content-Length:
    2nd.png

Also, see the attached DICOM files which are these responses saved with the multipart headers removed manually in a hex editor.

1st.dcm (20.9 KB)

2nd.dcm (20.9 KB)

Hi Christopher,

Sorry for the long email, I was writing while investigating.

I have made a few tests with jodogne/orthanc-plugins and with osimis/orthanc (and running with my Orthanc dev version locally)
I’m observing the same weird behaviour as you only with the jodogne/orthanc-plugins images (tested with 1.10.0 and 1.11.0).

At some point, I downloaded the same LSB binaries as the ones used in jodogne/orthanc-plugins (Orthanc 1.11.0 & DicomWeb 1.7) and, when run locally, I do not observe the error !!!

What I have found so far:

  • there is a relation with transcoding: By default, DicomWeb return files in 1.2.840.10008.1.2.1 in Explicit VR and, by default, the file is stored in Implicit VR (1.2.840.10008.1.2) in Orthanc.
  • if I configure “IngestTranscoding” to “1.2.840.10008.1.2.1”, it works with jodogne/orthanc-plugins images too
  • when there’s no IngestTranscoding configured, every time it works, I see that transcoding happens in the logs:
    I0106 08:53:55.501004 HttpServer.cpp:1244] (http) GET /dicom-web/studies/2.16.840.1.114362.1.6.6.6.16802.9495211678.449811783.969.4346/series/2.16.840.1.114337.1.1.1502227388.0.1.3/instances/2.16.840.1.114337.1.1.1502227388.2
    I0106 08:53:55.501069 OrthancPlugins.cpp:2443] (plugins) Delegating HTTP request to plugin for URI: /dicom-web/studies/2.16.840.1.114362.1.6.6.6.16802.9495211678.449811783.969.4346/series/2.16.840.1.114337.1.1.1502227388.0.1.3/instances/2.16.840.1.114337.1.1.1502227388.2
    I0106 08:53:55.501373 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/series (built-in API)
    I0106 08:53:55.501583 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/study (built-in API)
    I0106 08:53:55.501705 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/metadata/TransferSyntax (built-in API)
    I0106 08:53:55.501775 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/file (built-in API)
    I0106 08:53:55.501840 StorageCache.cpp:101] Read attachment “cb02aea0-26bb-49a8-aa95-ef37d27ed019” with content type 1 from cache
    I0106 08:53:55.501972 DcmtkTranscoder.cpp:306] DCMTK transcoding from 1.2.840.10008.1.2 to one of: 1.2.840.10008.1.2.1
    I0106 08:53:55.502026 FromDcmtkBridge.cpp:1610] (dicom) Transcoded an image from transfer syntax 1.2.840.10008.1.2 to 1.2.840.10008.1.2.1

And this transcoding step does not happen with the jodogne/orthanc-plugins docker image:

I0106 07:57:51.608112 HttpServer.cpp:1244] (http) GET /dicom-web/studies/2.16.840.1.114362.1.6.6.6.16802.9495211678.449811783.969.4346/series/2.16.840.1.114337.1.1.1502227388.0.1.3/instances/2.16.840.1.114337.1.1.1502227388.2
I0106 07:57:51.608195 OrthancPlugins.cpp:2443] (plugins) Delegating HTTP request to plugin for URI: /dicom-web/studies/2.16.840.1.114362.1.6.6.6.16802.9495211678.449811783.969.4346/series/2.16.840.1.114337.1.1.1502227388.0.1.3/instances/2.16.840.1.114337.1.1.1502227388.2
I0106 07:57:51.608532 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/series (built-in API)
I0106 07:57:51.608817 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/study (built-in API)
I0106 07:57:51.608956 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/metadata/TransferSyntax (built-in API)
I0106 07:57:51.609022 OrthancPlugins.cpp:3123] (plugins) Plugin making REST GET call on URI /instances/3ade0c90-8e31904e-69eeace2-394b120e-afa8618c/file (built-in API)
I0106 07:57:51.609077 StorageCache.cpp:101] Read attachment “55d4062d-90b0-42bd-bc33-13790c27cd88” with content type 1 from cache

  • the logs are identical the first and second time the route is called. In all cases, the file is read from the cache so there’s no reason to modify the content !

When running the LSB files locally, I’m using:
/home/alain/Releases/Orthanc-1.11.0 orthanc-lsb.json --verbose

with this config file
{
“HttpPort”: 8055,
“StorageDirectory”: “/tmp/dw/storage”,
“IndexDirectory”: “/tmp/dw/storage”,
“RemoteAccessAllowed”: true,
“AuthenticationEnabled”: false,
“Plugins”: [“/home/alain/Releases/libOrthancDicomWeb-1.7.so”]
//“IngestTranscoding”: “1.2.840.10008.1.2.1”
}

When running jodogne/orthanc-plugins images,
docker run -p 8055:8042 -v $PWD/orthanc_config:/etc/orthanc jodogne/orthanc-plugins:1.11.0 /etc/orthanc/ --verbose

with this config file:
{
“StorageDirectory”: “/var/lib/orthanc/db”,
“IndexDirectory”: “/var/lib/orthanc/db”,
“RemoteAccessAllowed”: true,
“AuthenticationEnabled”: false,
“Plugins”: [“/usr/local/share/orthanc/plugins”]
// “IngestTranscoding”: “1.2.840.10008.1.2.1”
}

  • At this point, I realized that if I’m loading only the DicomWeb plugin with jodogne/orthanc-plugins, then, it works ! (The “transcoding logs” do appear in the logs !)
  • As soon as I add the GDCM plugin, it stops working, the transcoding logs are not displayed but I assume that GDCM is transcoding silently - the transcoding logs are displayed by the DCMTK built-in transcoder. .
  • GDCM is activated by default in osimis/orthanc images and it worked there.

The final reason is:

  • it seems there’s a bug in the GDCM plugin when transcoding from Implicit VR to Explicit VR (and this happens only the second time !!!)
  • By default, the jodogne/orthanc-plugins image does not contain any configuration for the GDCM plugin which means GDCM is used for all transcodings.
  • By default, the osimis/orthanc image contains this configuration for the GDCM plugin which configures it to handle only J2K conversions since all other conversions are handled correctly by the built-in DCMTK decoder:
  "Gdcm": {
    "Throttling": 4,
    "RestrictTransferSyntaxes": [
      "1.2.840.10008.1.2.4.90",
      "1.2.840.10008.1.2.4.91",
      "1.2.840.10008.1.2.4.92",
      "1.2.840.10008.1.2.4.93"
    ]
  }
}

So, the solutions for you are:

  • disable the GDCM plugin completely
  • configure it with the above configuration.

I’m adding this report in the GDCM plugin TODO list to investigate later.

Best regards,

Alain.

1st.png

2nd.png