ohif-viewer/extensions/dicom-microscopy/src/DicomMicroscopySopClassHandler.js
M.D 075008c674
feat(microscopy): add dicom microscopy extension and mode (#3247)
* skeleton for dicom-microscopy extension

* skeleton for microscopy mode

* [feat] ported @radicalimaging/microscopy-dicom to OHIF's default extension

* [feat] ported microscopy mode from private repo

* added new definitions to the package.json

* webpack configuration update for microscopy extension

* register new icons for microscopy tools

* fixes to the microscopy extension and mode

* trivial error fix - typescript type import error

* link microscopy extension with default OHIF app plugin config

* demo config fix

* fix logs

* remove unsed imports

* [fix] loading of microscopy

* [fix] webworker script loading, normalizing denaturalized dataset

* found the latest version of dicom-microscopy-viewer that works with current OHIF extension : 0.35.2

* hide thumbnail pane by default, as we have issues with

* comments

* remove unused code

* [feat] microscopy - annotation selection

* [feat] microscopy - edit annotation label

* wip

* [bugfix] dicom-microscopy tool

* [bugfix] dicom microscopy annotations

* [fix] mixed-content blocking caused by BulkDataURI

* [fix] microscopy measurements panel - center button

* [fix] microscopy measurements panel - styling

* [fix] microscopy - controls

* fix local loading of microscopy

* fix local loading of dicom microscopy

* fix typo - indexof to indexOf

* [fix] remove unused icons

* remove commented out lines from webpack configuration

* platform/viewer/public/config/default.js - revert accidental changes

* [refactor] redirecting to microscopy mode on Local mode

* attribution to DMV and SLIM viewer

* [fix] code review feedbacks

* fix thumbnails

* [fix] microscopy - fix old publisher.publish() to PubSubService._broadcastEvent()

* [fix] interactions, webpack config, roi selection

* [feat] microscopy - remove select tool  from UI

* microscopy author

* [fix] saving and loading SR

* [bugfix] - missing publish() function in MicroscopyService, replace with _broadcastEvent

* remove author section from readme

* refactor SR saving feature

* fix webpack config after merge

* [bugfix] repeated import

* fix e2e

* webpack configuration

* hide "Create report" button for microscopy
2023-04-27 20:53:52 -04:00

133 lines
3.9 KiB
JavaScript

import OHIF from '@ohif/core';
const { utils } = OHIF;
const SOP_CLASS_UIDS = {
VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE: '1.2.840.10008.5.1.4.1.1.77.1.6',
};
const SOPClassHandlerId =
'@ohif/extension-dicom-microscopy.sopClassHandlerModule.DicomMicroscopySopClassHandler';
function _getDisplaySetsFromSeries(
instances,
servicesManager,
extensionManager
) {
// If the series has no instances, stop here
if (!instances || !instances.length) {
throw new Error('No instances were provided');
}
const instance = instances[0];
let singleFrameInstance = instance;
let currentFrames = +singleFrameInstance.NumberOfFrames || 1;
for (const instanceI of instances) {
const framesI = +instanceI.NumberOfFrames || 1;
if (framesI < currentFrames) {
singleFrameInstance = instanceI;
currentFrames = framesI;
}
}
let imageIdForThumbnail = null;
if (singleFrameInstance) {
if (currentFrames == 1) {
// Not all DICOM server implementations support thumbnail service,
// So if we have a single-frame image, we will prefer it.
imageIdForThumbnail = singleFrameInstance.imageId;
}
if (!imageIdForThumbnail) {
// use the thumbnail service provided by DICOM server
const dataSource = extensionManager.getActiveDataSource()[0];
imageIdForThumbnail = dataSource.getImageIdsForInstance({
instance: singleFrameInstance,
thumbnail: true,
});
}
}
const {
FrameOfReferenceUID,
SeriesDescription,
ContentDate,
ContentTime,
SeriesNumber,
StudyInstanceUID,
SeriesInstanceUID,
SOPInstanceUID,
SOPClassUID,
} = instance;
instances = instances.map(inst => {
// NOTE: According to DICOM standard a series should have a FrameOfReferenceUID
// When the Microscopy file was built by certain tool from multiple image files,
// each instance's FrameOfReferenceUID is sometimes different.
// Even though this means the file was not well formatted DICOM VL Whole Slide Microscopy Image,
// the case is so often, so let's override this value manually here.
//
// https://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.7.4.html#sect_C.7.4.1.1.1
inst.FrameOfReferenceUID = instance.FrameOfReferenceUID;
return inst;
});
const othersFrameOfReferenceUID = instances
.filter(v => v)
.map(inst => inst.FrameOfReferenceUID)
.filter((value, index, array) => array.indexOf(value) === index);
if (othersFrameOfReferenceUID.length > 1) {
console.warn(
'Expected FrameOfReferenceUID of difference instances within a series to be the same, found multiple different values',
othersFrameOfReferenceUID
);
}
const displaySet = {
plugin: 'microscopy',
Modality: 'SM',
altImageText: 'Microscopy',
displaySetInstanceUID: utils.guid(),
SOPInstanceUID,
SeriesInstanceUID,
StudyInstanceUID,
FrameOfReferenceUID,
SOPClassHandlerId,
SOPClassUID,
SeriesDescription: SeriesDescription || 'Microscopy Data',
// Map ContentDate/Time to SeriesTime for series list sorting.
SeriesDate: ContentDate,
SeriesTime: ContentTime,
SeriesNumber,
firstInstance: singleFrameInstance, // top level instance in the image Pyramid
instance,
numImageFrames: 0,
numInstances: 1,
imageIdForThumbnail, // thumbnail image
others: instances, // all other level instances in the image Pyramid
othersFrameOfReferenceUID,
};
return [displaySet];
}
export default function getDicomMicroscopySopClassHandler({
servicesManager,
extensionManager,
}) {
const getDisplaySetsFromSeries = instances => {
return _getDisplaySetsFromSeries(
instances,
servicesManager,
extensionManager
);
};
return {
name: 'DicomMicroscopySopClassHandler',
sopClassUids: [SOP_CLASS_UIDS.VL_WHOLE_SLIDE_MICROSCOPY_IMAGE_STORAGE],
getDisplaySetsFromSeries,
};
}