OHIF Plugin is displaying MRI images, but not PDF or SR

I have an Orthanc instance where I send a brain T1 to analysis pipeline and receive it back into my Orthanc database. The output here is
• The original T1 image
• A coloured MR image indicating brain segments
• A coloured MR image showing grey vs. white matter
• A PDF report
• A Structured Report

I want to view this all via the OHIF plugin. Yet, when I navigate to the OHIF plugin, I cannot see the PDF (see image 1)

I know that this issue already exists for OHIF users who are using DCM4CHEE ( [Bug] PDFs Won't Load From DCM4CHEE · Issue #3826 · OHIF/Viewers · GitHub ), which I am not.
Similarly, I also cannot view the Structured Report. When I double click it in the menu, I get this error display (image 2)

When I use the regular OHIF viewer on a separate port, both the PDF and the Structured Report are being displayed normally.

As I am new to Orthanc & OHIF (and medical imaging processing in general), I was wondering if this is an error on my side or if it is some kind of bug that needs fixing? Any help would be highly appreciated.

Here is the relevant part of my docker-compose file:

version: "3.3"
services:
  orthanc:
    container_name: orthanc
    image: jodogne/orthanc-plugins
    ports:
      - 4242:4242 
      - 8042:8042
    volumes:
      - ./files/orthanc.json:/etc/orthanc/orthanc.json:ro
      - ./files/testdata_db:/var/lib/orthanc/db/
      - ./ohif.js:/usr/share/nginx/html/app-config.js:ro

  ohif_viewer:
    image: ohif/viewer
    ports:
      - 3002:80
    environment: 
      - APP_CONFIG:/usr/share/nginx/html/app-config.js
    volumes:
      - ./nginx_ohif.conf:/etc/nginx/conf.d/default.conf:ro
      - ./ohif.js:/usr/share/nginx/html/app-config.js:ro
      - ./logo.png:/usr/share/nginx/html/logo.png:ro

volumes: 
  testdata_db:

And here is my orthanc.json:

{ 
  "Name": "simulated PACS",
  "StorageDirectory": "/var/lib/orthanc/db",
  "IndexDirectory": "/var/lib/orthanc/db",
  "StorageCompression": false,
  "MaximumStorageSize": 0,
  "MaximumPatientCount": 0,
  "LuaScripts": [],
      "Plugins" : [ 
    "/usr/share/orthanc/plugins", "/usr/local/share/orthanc/plugins"
  ],

  "OHIF": {
   "UserConfiguration" : "/usr/share/nginx/html/app-config.js",
    "DataSource" : "dicom-web"
  },
  "ConcurrentJobs": 2,
  "HttpServerEnabled": true,
  "HttpPort": 8042,
  "HttpDescribeErrors": true,
  "HttpCompressionEnabled": true,
  "WebDavEnabled": false,
  "WebDavDeleteAllowed": false,
  "WebDavUploadAllowed": false,
  "DicomServerEnabled": true,
  "DicomAet": "ORTHANC",
  "DicomCheckCalledAet": false,
  "DicomPort": 4242,
  "DefaultEncoding": "Latin1",
  
  "AcceptedTransferSyntaxes" : [ 
    "1.2.840.10008.1.2",
    "1.2.840.10008.1.2.1",
    "1.2.840.10008.1.2.1.99",
    "1.2.840.10008.1.2.4.50",
    "1.2.840.10008.1.2.4.51",
    "1.2.840.10008.1.2.4.90",
    "1.2.840.10008.1.2.4.91",
    "1.2.840.10008.1.2.5"
  ],

  "DicomScuPreferredTransferSyntax" : "1.2.840.10008.1.2.1",
  "UnknownSopClassAccepted": false,
  "DicomScpTimeout": 30,
  "RemoteAccessAllowed": true,
  "SslEnabled": false,
  "SslCertificate": "certificate.pem",
  "SslVerifyPeers": false,
  "SslTrustedClientCertificates": "trustedClientCertificates.pem",
  "AuthenticationEnabled": false,
  "RegisteredUsers": {
  },
  "DicomModalitiesInDatabase": false,
  "DicomAlwaysAllowEcho": true,
  "DicomAlwaysAllowStore": true,
  "DicomCheckModalityHost": false,
  "DicomScuTimeout": 10,
  "OrthancPeers": {
  },
  "OrthancPeersInDatabase": false,
  "HttpProxy": "",
  "HttpVerbose": false,
  "HttpTimeout": 60,
  "HttpsVerifyPeers": true,
  "HttpsCACertificates": "/etc/ssl/certs/ca-certificates.crt",
  "UserMetadata": {
  },
  "UserContentType": {
  },
  "StableAge": 60,
  "StrictAetComparison": false,
  "StoreMD5ForAttachments": true,
  "LimitFindResults": 0,
  "LimitFindInstances": 0,
  "LimitJobs": 10,
  "LogExportedResources": false,
  "KeepAlive": true,
  "TcpNoDelay": true,
  "HttpThreadsCount": 50,
  "StoreDicom": true,
  "DicomAssociationCloseDelay": 5,
  "QueryRetrieveSize": 100,
  "CaseSensitivePN": false,
  "LoadPrivateDictionary": true,
  "Dictionary": {
  },
  "SynchronousCMove": true,
  "JobsHistorySize": 10,
  "SaveJobs": true,
  "OverwriteInstances": false,
  "MediaArchiveSize": 1,
  "StorageAccessOnFind": "Always",
  "MetricsEnabled": true,

  "ExecuteLuaEnabled": false,
  "HttpRequestTimeout": 30,
  "DefaultPrivateCreator": "",
  "StorageCommitmentReportsSize": 100,
  "TranscodeDicomProtocol": true,
  "BuiltinDecoderTranscoderOrder": "After",
  "DicomLossyTranscodingQuality": 90,
  "SyncStorageArea": true
}

If you need anything else, I will gladly provide it.

Any help would be greatly appreciated!

Stefan

Hi Steve,

Could you share the ohif.js and nginx_ohif.conf that you are using with your docker setup ?

That might help us understand the differences between the plugin and docker versions.

BR,

Alain

Hello Alain,

thank you for taking the time to look at my issue. I deleted my previous reply because there was an error in the code. I am not entirely sure what my last changes from a few days ago were, but I have been able to get it running again.

ohif.js:

window.config = {
  // default: '/'
  routerBasename: '/',
  extensions: [],
  showStudyList: true,
  filterQueryParam: false,
  servers: {
    dicomWeb: [
      {
        name: 'Orthanc',
        wadoUriRoot: '/orthanc/wado',
        qidoRoot: '/orthanc/dicom-web',
        wadoRoot: '/orthanc/dicom-web',
        qidoSupportsIncludeField: true,
        imageRendering: 'wadors',
        thumbnailRendering: 'wadors',
        enableStudyLazyLoad: true,
        supportsFuzzyMatching: true,
      },
    ],
  },

  hotkeys: [
    // ~ Global
    {
      commandName: 'incrementActiveViewport',
      label: 'Next Viewport',
      keys: ['right'],
    },
    {
      commandName: 'decrementActiveViewport',
      label: 'Previous Viewport',
      keys: ['left'],
    },
    // Supported Keys: https://craig.is/killing/mice
    // ~ Cornerstone Extension
    { commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] },
    { commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] },
    { commandName: 'invertViewport', label: 'Invert', keys: ['i'] },
    {
      commandName: 'flipViewportVertical',
      label: 'Flip Horizontally',
      keys: ['h'],
    },
    {
      commandName: 'flipViewportHorizontal',
      label: 'Flip Vertically',
      keys: ['v'],
    },
    { commandName: 'scaleUpViewport', label: 'Zoom In', keys: ['+'] },
    { commandName: 'scaleDownViewport', label: 'Zoom Out', keys: ['-'] },
    { commandName: 'fitViewportToWindow', label: 'Zoom to Fit', keys: ['='] },
    { commandName: 'resetViewport', label: 'Reset', keys: ['space'] },
    // clearAnnotations
    { commandName: 'nextImage', label: 'Next Image', keys: ['down'] },
    { commandName: 'previousImage', label: 'Previous Image', keys: ['up'] },
    // firstImage
    // lastImage
    {
      commandName: 'previousViewportDisplaySet',
      label: 'Previous Series',
      keys: ['pagedown'],
    },
    {
      commandName: 'nextViewportDisplaySet',
      label: 'Next Series',
      keys: ['pageup'],
    },
    // ~ Cornerstone Tools
    { commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
    // ~ Window level presets
    {
      commandName: 'windowLevelPreset1',
      label: 'W/L Preset 1',
      keys: ['1'],
    },
    {
      commandName: 'windowLevelPreset2',
      label: 'W/L Preset 2',
      keys: ['2'],
    },
    {
      commandName: 'windowLevelPreset3',
      label: 'W/L Preset 3',
      keys: ['3'],
    },
    {
      commandName: 'windowLevelPreset4',
      label: 'W/L Preset 4',
      keys: ['4'],
    },
    {
      commandName: 'windowLevelPreset5',
      label: 'W/L Preset 5',
      keys: ['5'],
    },
    {
      commandName: 'windowLevelPreset6',
      label: 'W/L Preset 6',
      keys: ['6'],
    },
    {
      commandName: 'windowLevelPreset7',
      label: 'W/L Preset 7',
      keys: ['7'],
    },
    {
      commandName: 'windowLevelPreset8',
      label: 'W/L Preset 8',
      keys: ['8'],
    },
    {
      commandName: 'windowLevelPreset9',
      label: 'W/L Preset 9',
      keys: ['9'],
    },
  ],
  cornerstoneExtensionConfig: {},

  // studyListFunctionsEnabled is set to true to enable DICOM uploading
  studyListFunctionsEnabled: true
  
  // Following property limits number of simultaneous series metadata requests.
  // For http/1.x-only servers, set this to 5 or less to improve
  //  on first meaningful display in viewer
  // If the server is particularly slow to respond to series metadata
  //  requests as it extracts the metadata from raw files everytime,
  //  try setting this to even lower value
  // Leave it undefined for no limit, sutiable for HTTP/2 enabled servers
  // maxConcurrentMetadataRequests: 5,
};

nginx_ohif.conf:


server {
  listen 80;
  # set client body size to 500M, this is to allow uploading of DICOMs, throws '413 request entity too large nginx' error otherwise #
  client_max_body_size 500M;
  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }

  # https://book.orthanc-server.com/faq/nginx.html#nginx
  location  /orthanc/  {
    proxy_pass http://orthanc:8042;
    proxy_set_header HOST $host;
    proxy_set_header X-Real-IP $remote_addr;
    rewrite /orthanc(.*) $1 break;
   }
}

By the way, here is an updated version of the orthanc.json, because one line was giving me an error in my attempt to fix it:
(I deleted the line “UserConfiguration” : “/usr/share/nginx/html/app-config.js” in the “OHIF” configuration

{ 
  "Name": "simulated PACS",
  "StorageDirectory": "/var/lib/orthanc/db",
  "IndexDirectory": "/var/lib/orthanc/db",
  "StorageCompression": false,
  "MaximumStorageSize": 0,
  "MaximumPatientCount": 0,
  "LuaScripts": [],
      "Plugins" : [ 
    "/usr/share/orthanc/plugins", "/usr/local/share/orthanc/plugins"
  ],

  "OHIF": {
    "DataSource" : "dicom-web"
  },
  "ConcurrentJobs": 2,
  "HttpServerEnabled": true,
  "HttpPort": 8042,
  "HttpDescribeErrors": true,
  "HttpCompressionEnabled": true,
  "WebDavEnabled": false,
  "WebDavDeleteAllowed": false,
  "WebDavUploadAllowed": false,
  "DicomServerEnabled": true,
  "DicomAet": "ORTHANC",
  "DicomCheckCalledAet": false,
  "DicomPort": 4242,
  "DefaultEncoding": "Latin1",
  
  "AcceptedTransferSyntaxes" : [ 
    "1.2.840.10008.1.2",
    "1.2.840.10008.1.2.1",
    "1.2.840.10008.1.2.1.99",
    "1.2.840.10008.1.2.4.50",
    "1.2.840.10008.1.2.4.51",
    "1.2.840.10008.1.2.4.90",
    "1.2.840.10008.1.2.4.91",
    "1.2.840.10008.1.2.5"
  ],

  "DicomScuPreferredTransferSyntax" : "1.2.840.10008.1.2.1",
  "UnknownSopClassAccepted": false,
  "DicomScpTimeout": 30,
  "RemoteAccessAllowed": true,
  "SslEnabled": false,
  "SslCertificate": "certificate.pem",
  "SslVerifyPeers": false,
  "SslTrustedClientCertificates": "trustedClientCertificates.pem",
  "AuthenticationEnabled": false,
  "RegisteredUsers": {
  },
  "DicomModalitiesInDatabase": false,
  "DicomAlwaysAllowEcho": true,
  "DicomAlwaysAllowStore": true,
  "DicomCheckModalityHost": false,
  "DicomScuTimeout": 10,
  "OrthancPeers": {
  },
  "OrthancPeersInDatabase": false,
  "HttpProxy": "",
  "HttpVerbose": false,
  "HttpTimeout": 60,
  "HttpsVerifyPeers": true,
  "HttpsCACertificates": "/etc/ssl/certs/ca-certificates.crt",
  "UserMetadata": {
  },
  "UserContentType": {
  },
  "StableAge": 60,
  "StrictAetComparison": false,
  "StoreMD5ForAttachments": true,
  "LimitFindResults": 0,
  "LimitFindInstances": 0,
  "LimitJobs": 10,
  "LogExportedResources": false,
  "KeepAlive": true,
  "TcpNoDelay": true,
  "HttpThreadsCount": 50,
  "StoreDicom": true,
  "DicomAssociationCloseDelay": 5,
  "QueryRetrieveSize": 100,
  "CaseSensitivePN": false,
  "LoadPrivateDictionary": true,
  "Dictionary": {
  },
  "SynchronousCMove": true,
  "JobsHistorySize": 10,
  "SaveJobs": true,
  "OverwriteInstances": false,
  "MediaArchiveSize": 1,
  "StorageAccessOnFind": "Always",
  "MetricsEnabled": true,

  "ExecuteLuaEnabled": false,
  "HttpRequestTimeout": 30,
  "DefaultPrivateCreator": "",
  "StorageCommitmentReportsSize": 100,
  "TranscodeDicomProtocol": true,
  "BuiltinDecoderTranscoderOrder": "After",
  "DicomLossyTranscodingQuality": 90,
  "SyncStorageArea": true
}

Hi Steve,

I gave your setup a try.
The first thing is that the OHIF versions are not identical. The ohif/viewer is actually an old image that is packaging version 4.12.51 while Orthanc integrates v 3.7.0.

You will have to believe me on this one but version 4.12.51 is actually anterior to 3.7.0 and actually packages OHIF 2.X.X. OHIF 3.X.X is actually a full rewrite.

I tried to add an OHIF v3 to your setup and, as expected, PDF and SR are not displaying. I have made this setup public for anyone who could provide a solution since you are not the first one to have this kind of issue.

@alireza : any idea about this PDF/SR issue ? I have seen that some PDF issues have been fixed recently but it still seems to fail with the latest released beta.

Best regards,

Alain.

1 Like

Hi @alireza,
have you had the time to look into this yet? Are there any news on this topic?

Best,
Steve

Hi Does it work in our demo? I’m trying to understand where the problem might be coming from

https://viewer-dev.ohif.org/
https://viewer-dev.ohif.org/localbasic

It can open the PDF report as well as the imaging data, but it cannot open the SR.

I get the error:
" Something went wrong

Something went wrongfalse.

Sorry, something went wrong there. Try again."

Thank you for looking into this.

Hi Alireza,

is there any news on this problem? Do you need anything else from me that could help?

Best
Steve

Hi @alireza ,

Any updates?

Hello,

I would advise you to discuss this directly with the OHIF community, instead of asking on the Orthanc forum. Indeed, your question is only related to OHIF (at least from what I understand).

Also, make sure to read the following post: Access segmentation viewer from OHIF - #34 by jodogne

Regards,
Sébastien-

hello @alireza

any update as regards this. I observed you rectified this in DCM4CHEE, please can this be extended to orthanc?