-
Notifications
You must be signed in to change notification settings - Fork 113
Concepts
General overview about important classes and how they are connected.
To capsulate DICOM datasets there is a class called DICOMZero
. One important member property is datasets
which represents an array of DICOM instances. Storing the result of a request in such a container object is useful to propagate the information to a viewer object.
The DICOMZero
class also offers methods to handle the reading of local DICOM files or extracting zipped DICOM files.
The class DICOMWEB
offers methods to retrieve information on different levels. Since you get meta data information with patients()
, studies()
, series()
, instances()
by automatically doing a QIDO-RS request, you actually retrieving pixel data only with calling instance()
which leads to a WADO-RS request.
function downloadProgress(progressEvent) {
status(`Downloaded ${(progressEvent.loaded / 1024 / 1024).toFixed(2)} MB so far... `);
}
const rootURL = 'http://<HOST>:<PORT>/dcm4chee-arc/aets/DCM4CHEE';
const dicomweb = new dcmjs.DICOMWEB({
progressCallback: downloadProgress,
rootURL: rootURL,
});
The rootURL
parameter is mandatory.
The result of every of the mentioned DICOMWEB
class methods is a Promise
object, which avoids blocking the main thread. In order to deal with the results you have to wait until the Promise is resolved.
dicomweb.instance(studyInstanceUID, seriesInstanceUID, sopInstanceUID).then(arrayBuffer => {
// do something with the arrayBuffer...
});
Here is an actual example how to chain the methods instances()
and instance()
which first get the meta data of all instances within a given DICOM series and then use the instance UID to retrieve the data for every instance.
function loadDicomSeries(studyInstanceUID, seriesInstanceUID, seriesContainer){
let promise = new Promise(function (resolve, reject) {
dicomweb.instances(studyInstanceUID, seriesInstanceUID).then(instancesResponses => {
console.log("download series " + seriesInstanceUID)
instancesResponses.forEach(instancesResponse => {
let response = DCMJS.data.DicomMetaDictionary.namifyDataset(instancesResponse);
let sopInstanceUID = response.SOPInstanceUID.Value[0]; dicomweb.instance(studyInstanceUID, seriesInstanceUID, sopInstanceUID).then(arrayBuffer => {
let dataset = seriesContainer.datasetFromArrayBuffer(arrayBuffer);
seriesContainer.datasets.push(dataset);
if (seriesContainer.datasets.length == instancesResponses.length) {
console.log("download finished")
resolve()
}
});
});
});
});
return promise;
}
The result of this method
loadDicomSeries
also returns a Promise which can be used in an application to wait until the data is loaded an then visualize it. Besides the series information, the method expects an object of the container classDICOMZero
where the data is downloaded and preserved to transfer it to a viewer.
The Viewer
class is responsible to take the mentioned datasets
property of a DICOMZero
object to be prepared for display it.
Example to create a Viewer:
var viewerOptions = {
'width': 350,
'height': 350,
}
viewerLeft = new Viewer(dicomZero.datasets, viewerOptions);
viewerLeft.display('#viewer');
This example expects the dicomZero to be an instance of
DICOMZero
containing datasets. Also on the HTML DOM tree there has to be an element with an ID namedviewer
.
Example on the HTML side:
<div id="viewer" style="width:350px; height:350px; background-color:black"></div>
Since the display method of Viewer
is called, the custom cornerstone image loader are registered. These loaders are using a id schema by which cornerstone decides which loader is used to load the actual image data correctly.
But first, the Viewer must be informed that there is a dicom dataset which is referenced by a cornerstone image id. To create those image ids there are some add-*
methods.
The data stored within Viewer.datasets
is added to the so called Viewer.baseStack
by just calling Viewer.display()
which uses one of the add methods according to the type of image:
At the moment these loaders are implemented:
- dcmjsImageLoader: standard single frame DICOM image loader
- dcmjsSEGImageLoader: multiframe DICOM SEG image loader
- dcmjsMultiframeImageLoader: multiframe DICOM image loader
- dcmjsPMImageLoader: multiframe DICOM PM image loader (for example an ADC map)
- dcmjsPMOverlayLoader: multiframe DICOM PM image overlay loader (for example a local difference measure map)
To add DICOM overlay on a second layer use the methods.
- addSegmentation(dataset)
- addParametricMapOverlay(dataset)
The methods are creating a new Cornerstone stack which is added to the tool state.