Hello,
In this post I am sharing some feedback about my experience hacking the OHIF codebase as an outside want-to-be contributor, as well as asking for guidance.
My lab develops a web backend service which stores DICOM instances. The DICOM can be queried and retrieved for over an HTTP API.
I want to implement support for using OHIF as a front-end to our service. So far, I was able to get query working but not “loading” (retrieval of the actual images from our backend to OHIF).
What Worked
It took me ~5 hours to get OHIF to be able to query our backend. I was able to create an extension by running yarn run cli create-extension
, yarn run cli lin-extension ...
, and making some edits to the config:
diff --git a/platform/app/public/config/default.js b/platform/app/public/config/default.js
index 97f506e70..ae01e34f6 100644
--- a/platform/app/public/config/default.js
+++ b/platform/app/public/config/default.js
@@ -24,6 +24,8 @@ window.config = {
},
// filterQueryParam: false,
defaultDataSourceName: 'dicomweb',
+ // defaultDataSourceName: 'trying-chris',
+
/* Dynamic config allows user to pass "configUrl" query string this allows to load config without recompiling application. The regex will ensure valid configuration source */
// dangerouslyUseDynamicConfig: {
// enabled: true,
@@ -35,6 +37,14 @@ window.config = {
// regex: /.*/,
// },
dataSources: [
+ {
+ namespace: 'ohif-extension-fnndsc-chris.dataSourcesModule.chris',
+ sourceName: 'trying-chris',
+ configuration: {
+ friendlyName: 'PACSFiles from cube.chrisproject.org',
+ name: 'trying-chris',
+ }
+ },
{
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
sourceName: 'dicomweb',
The extension created by the template did not work out-of-the-box. I created a bug report for the problem: [Bug] New extension template outdated dependency version @ohif/i18n · Issue #3656 · OHIF/Viewers · GitHub
I followed the documentation Module: Data Source | OHIF and was able to get query working by implementing query.studies.search
and query.series.search
.
What Didn’t Go Well
While the documentation mentions that retrieve.series.metadata
“is a crucial end point,” I did not know how to implement it because I couldn’t find the interface for the function’s return type. Another instance of missing documentation/docstring is where the documentation says “retrieve.bulkDataURI
: used to render RTSTUCTURESET in the viewport” however it is not explained what RTSTUCTURESET is nor what retrieve.bulkDataURI
is supposed to be.
The documentation did a good job giving an overview of the codebase organization, extensions architecture, and how extensions are used by modes. However, after another ~5 hours of reading code and reverse-engineering, I am still unable to understand how it all “comes together” at a lower level. Some (possibly misguided) questions I have include:
- Most broadly: what functions, interfaces, and configurations do I need to implement (in other words, where is the code I need to change) in order to change how OHIF loads image data?
- What is a
DisplaySet
(is it the same thing as animageSet
)?DisplaySet
is mentioned in the docs for SOP Class Handler and Viewport, but whatDisplaySet
is/represents is not explained. Also, there’s a syntax error in the example for an SOP class handler*. - How are “managers” and “services” to be used by extensions? From reading the source code, I can see that it’s necessary for
retrieve.series.metadata
to callDicomMetadataStore.addSeriesMetadata
andDicomMetadataStore.addInstances
, but without a parameter type interface I don’t know what shape the parameters should have. I also found it confusing howquery.studies.search
andquery.series.search
are to simply return the data howeverretrieve.series.metadata
should call methods ofDicomMetadataStore
instead of returning data.
*Discourse has a silly limitation where I can only supply 2 URLs per post…
Right now I’m stuck and can’t figure out where to go from here.
About Our Backend
Backend repo: on Github, FNNDSC/ChRIS_ultron_backEnd
For the most part, it’s a simple JSON web API. Example query:
# Search for DICOM instances where study date is "2022-12-06" and modality is "MR"
curl -u chris:chris1234 'https://cube.chrisproject.org/api/v1/pacsfiles/search/?StudyDate=2011-12-06&Modality=MR' -H 'Accept: application/json'
Example DICOM object retrieval:
curl -u chris:chris1234 'https://cube.chrisproject.org/api/v1/pacsfiles/2925/0054-1.3.12.2.1107.5.2.32.35235.2011120608042135173930307.dcm'