Orthanc DicomMap Singleton is not thread safe ?

Hi Author,

I am using the newest version of Orthanc and OrthancDicomWeb utilizing feature MainDicomTag. Here is my setting in orthanc.json

“ExtraMainDicomTags” : {
“Instance” : [
“WindowCenter”, //“WindowCenter”,
“WindowWidth”, //“WindowWidth”,
“Rows”,
“Columns”,
“ImageType”,
“SOPClassUID”,
“ContentDate”,
“ContentTime”,
“FrameOfReferenceUID”,
“PixelSpacing”,
“SpecificCharacterSet”,
“BitsAllocated”,
“BitsStored”
],
“Series” : [
“TimezoneOffsetFromUTC”,
“00400244”, // PerformedProcedureStepStartDate
“PerformedProcedureStepStartTime”
],
“Study”: [
“TimezoneOffsetFromUTC”
],
“Patient”: []
},

“DicomWeb” : {
“Enable” : true, // Whether DICOMweb support is enabled
“Root” : “/wado-rs/”, // Root URI of the DICOMweb API (for QIDO-RS, STOW-RS and WADO-RS)
//“Root” : “/dicom-web/”, // Root URI of the DICOMweb API (for QIDO-RS, STOW-RS and WADO-RS)
“EnableWado” : true, // Whether WADO-URI (previously known as WADO) support is enabled
“WadoRoot” : “/wado”, // Root URI of the WADO-URI (aka. WADO) API
“Ssl” : false, // Whether HTTPS should be used for subsequent WADO-RS requests
“QidoCaseSensitive” : true, // For QIDO-RS server, whether search is case sensitive (since release 0.5)
“Host” : “localhost”, // Hard-codes the name of the host for subsequent WADO-RS requests (deprecated)
“SeriesMetadata” : “MainDicomTags”, // How series-level metadata is retrieved (since release 1.1, cf. section below)

Accessing /instances/{publicID} gives me the correct values of additional dicom tags: WindowCenter, WindowWidth. However if I retrieve series metadata from : /dicom-web/studies/{studyIUID}/series/{seriesIUID}/metadata, the result does not contain WindowCenter and WindowWidth. Further digging into the Orthanc code and OrthancDicomWeb, I see that the singleton DicomMap::MainDicomTagsConfiguration::GetInstance() is not thread-safe. It’s being called twice.
The first one call is from DicomMap::AddMainDicomTag, in OrthancInitialization.cpp:269 in static function LoadMainDicomTags (in OrthancDicomWeb plugin), In this function DicomMap::MainDicomTagsConfiguration::GetInstance() is called, then it resets default main dicom tags.

The second one call is from MainDicomTagsCache::ReadResource, in WadoRs.cpp:520. It calls: dicom.ParseMainDicomTags(value[MAIN_DICOM_TAGS], level);, at this point DicomMap::MainDicomTagsConfiguration::GetInstance() and this singleton again resets default main dicom tags.

The second call to reset main dicom tags erases the previous set value MainDicomTag. That’s why OrthancDicomWeb cannot return the desired Tags from configuration.

Can you please help to confirm whether it’s a bug ? The dicom file is attached

This is the API to retrieve series metadata
localhost:8042/wado-rs/studies/1.2.840.113619.2.404.3.2831156996.875.1599094730.441/series/1.2.840.113619.2.404.3.2831156996.875.1599094730.453.5/metadata

The result is
{“00080005”:{“Value”:[“ISO_IR 100”],“vr”:“CS”},“00080012”:{“Value”:[“20200903”],“vr”:“DA”},“00080013”:{“Value”:[“113350”],“vr”:“TM”},“00080018”:{“Value”:[“1.2.840.113619.2.404.3.2831156996.875.1599094730.534.246”],“vr”:“UI”},“00080020”:{“Value”:[“20200903”],“vr”:“DA”},“00080021”:{“Value”:[“20200903”],“vr”:“DA”},“00080030”:{“Value”:[“112958”],“vr”:“TM”},“00080031”:{“Value”:[“113215”],“vr”:“TM”},“00080050”:{“Value”:[“1041912”],“vr”:“SH”},“00080060”:{“Value”:[“CT”],“vr”:“CS”},“00080070”:{“Value”:[“GE MEDICAL SYSTEMS”],“vr”:“LO”},“00080080”:{“Value”:[“PHONG KHAM Y KHOA HA NOI”],“vr”:“LO”},“00080090”:{“vr”:“PN”},“00081010”:{“Value”:[“ctbay99”],“vr”:“SH”},“00081030”:{“Value”:[“LONG NGUC”],“vr”:“LO”},“0008103E”:{“Value”:[“1.25mm Stnd”],“vr”:“LO”},“00081070”:{“vr”:“PN”},“00100010”:{“Value”:[{“Alphabetic”:“HOANG THAI CONG”}],“vr”:“PN”},“00100020”:{“Value”:[“2009000039”],“vr”:“LO”},“00100030”:{“Value”:[“19930101”],“vr”:“DA”},“00100040”:{“Value”:[“M”],“vr”:“CS”},“00101000”:{“vr”:“LO”},“00181030”:{“Value”:[“5.1 Routine Chest/NGUC THUONG QUY”],“vr”:“LO”},“0020000D”:{“Value”:[“1.2.840.113619.2.404.3.2831156996.875.1599094730.441”],“vr”:“UI”},“0020000E”:{“Value”:[“1.2.840.113619.2.404.3.2831156996.875.1599094730.453.5”],“vr”:“UI”},“00200010”:{“Value”:[“3314”],“vr”:“SH”},“00200011”:{“Value”:[5],“vr”:“IS”},“00200012”:{“Value”:[1],“vr”:“IS”},“00200013”:{“Value”:[246],“vr”:“IS”},“00200032”:{“Value”:[-163.2,-180,-24.75],“vr”:“DS”},“00200037”:{“Value”:[1,0,0,0,1,0],“vr”:“DS”},“00400254”:{“Value”:[“LONG NGUC”],“vr”:“LO”}}

dda6fc9e-3657-4348-b249-f21ea5e70ca3.dcm (516 KB)

Hi Tran,

Thanks for the detailed analysis and reproducible example !

Yes, it is a bug because there are 2 instances of that singleton !!!

One instance is created by the Core of Orthanc at its initialization.
The Dicom plugin uses the Orthanc Framework as a static library and therefore, the singleton it creates is in another “namespace” and is therefore another instance. The plugin could actually even use another version of the Framework and have another definition of that class hence with 2 different object structures.

I’ve added it to our TODO. A quick hack is probably to load the ExtraMainDicomTags from the DicomWeb plugin too to have the same configuration on both singleton.

Best regards,

Alain