* fix: 🐛 Local file: failing when retrieving segmentation data Fix segmentation data retrieval issues for local file. Changed from fecthing to use cornerstone loadAndCache method BREAKING CHANGE: DICOM Seg Closes: part of #838 * Switch SEG retrieval to WADO-RS * Forgot a debugger * refactor: 💡 Code refactor. Minor changes into methods * fix: 🐛 Load local files: PDF Items: 1. FileLoaderService: used for serveral operations on local files(load it, get list of studies, group them, accepting dicom and pdf) 2. DicomLoaderService: used for loading dicom based on dataset and studies. Depending on type of dicom loader might change. WIP 3. Refactor PDF and handleSegmentationStorage to use DicomLoaderService * fix: 🐛 Code review * fix: 🐛 Code review. Changed:Folder organization and dicom file Move fileLoaderService and others to a specific folder. When loading dicom file change to only retrieve the file(not use cornerstone to cache or anything else). * fix: 🐛 Code review. Move dicomLoaderService to core Moved dicomLoaderService to ohif/core and localFileLoaders to a specific folder. * fix: 🐛 Code review Simplified method to get study for dicom file. Added error handling on file loading. DicomLoaderService to be exposed on ohif/core/utils instead. * fix: 🐛 Reduce local load to one method only Reduced local file load to one method only * fix: 🐛 HTML to use dicomLoaderService. Prefer wadors than (uri) * fix: 🐛 Code implementation for multiframe files * fix: 🐛 Code review. Default local loader to dicom Closes: 838 * fix: 🐛 Code review. Use relative path to require DICOMWeb Closes: 838 * fix: 🐛 Code review. Fix unit test. Added DicomLoaderService mod Closes: 838 * fix: 🐛 Code review. Add 'Seg' on left thumb When getting/creating dataset get modality for file/image read Closes: 838
129 lines
3.2 KiB
JavaScript
129 lines
3.2 KiB
JavaScript
import * as dcmjs from 'dcmjs';
|
|
|
|
import OHIF from '@ohif/core';
|
|
import cornerstone from 'cornerstone-core';
|
|
import cornerstoneTools from 'cornerstone-tools';
|
|
|
|
const { StackManager, DicomLoaderService } = OHIF.utils;
|
|
|
|
function getDisplaySet(studies, studyInstanceUid, displaySetInstanceUid) {
|
|
const study = studies.find(
|
|
study => study.studyInstanceUid === studyInstanceUid
|
|
);
|
|
|
|
const displaySet = study.displaySets.find(set => {
|
|
return set.displaySetInstanceUid === displaySetInstanceUid;
|
|
});
|
|
|
|
return displaySet;
|
|
}
|
|
|
|
function getDisplaySetsBySeries(studies, studyInstanceUid, seriesInstanceUid) {
|
|
const study = studies.find(
|
|
study => study.studyInstanceUid === studyInstanceUid
|
|
);
|
|
|
|
return study.displaySets.filter(set => {
|
|
return set.seriesInstanceUid === seriesInstanceUid;
|
|
});
|
|
}
|
|
|
|
function parseSeg(arrayBuffer, imageIds) {
|
|
return dcmjs.adapters.Cornerstone.Segmentation.generateToolState(
|
|
imageIds,
|
|
arrayBuffer,
|
|
cornerstone.metaData
|
|
);
|
|
}
|
|
|
|
function addSegMetadataToCornerstoneToolState(
|
|
segMetadata,
|
|
toolState,
|
|
displaySetInstanceUid
|
|
) {
|
|
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(
|
|
toolState
|
|
);
|
|
|
|
const brushModule = cornerstoneTools.store.modules.brush;
|
|
|
|
for (let i = 0; i < segMetadata.length; i++) {
|
|
brushModule.setters.metadata(displaySetInstanceUid, i, segMetadata[i]);
|
|
}
|
|
}
|
|
|
|
async function handleSegmentationStorage(
|
|
studies,
|
|
studyInstanceUid,
|
|
displaySetInstanceUid
|
|
) {
|
|
const study = studies.find(
|
|
study => study.studyInstanceUid === studyInstanceUid
|
|
);
|
|
const displaySet = getDisplaySet(
|
|
studies,
|
|
studyInstanceUid,
|
|
displaySetInstanceUid
|
|
);
|
|
|
|
const arrayBuffer = await DicomLoaderService.findDicomDataPromise(
|
|
displaySet,
|
|
studies
|
|
);
|
|
const dicomData = dcmjs.data.DicomMessage.readFile(arrayBuffer);
|
|
const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
|
|
dicomData.dict
|
|
);
|
|
|
|
dataset._meta = dcmjs.data.DicomMetaDictionary.namifyDataset(dicomData.meta);
|
|
|
|
const seriesInstanceUid = dataset.ReferencedSeriesSequence.SeriesInstanceUID;
|
|
const displaySets = getDisplaySetsBySeries(
|
|
studies,
|
|
studyInstanceUid,
|
|
seriesInstanceUid
|
|
);
|
|
|
|
if (displaySets.length > 1) {
|
|
console.warn(
|
|
'More than one display set with the same seriesInstanceUid. This is not supported yet...'
|
|
);
|
|
}
|
|
|
|
const referenceDisplaySet = displaySets[0];
|
|
const imageIds = referenceDisplaySet.images.map(image => image.getImageId());
|
|
const results = parseSeg(arrayBuffer, imageIds);
|
|
|
|
if (!results) {
|
|
throw new Error('Fractional segmentations are not supported');
|
|
}
|
|
|
|
const { labelmapBuffer, segMetadata, segmentsOnFrame } = results;
|
|
const { setters } = cornerstoneTools.getModule('segmentation');
|
|
|
|
setters.labelmap3DByFirstImageId(
|
|
imageIds[0],
|
|
labelmapBuffer,
|
|
0, // TODO -> Can define a color LUT based on colors in the SEG later.
|
|
segMetadata,
|
|
imageIds.length,
|
|
segmentsOnFrame
|
|
);
|
|
|
|
const cachedStack = StackManager.findOrCreateStack(
|
|
study,
|
|
referenceDisplaySet
|
|
);
|
|
const stack = Object.assign({}, cachedStack);
|
|
|
|
stack.currentImageIdIndex = 0;
|
|
|
|
return {
|
|
studyInstanceUid,
|
|
displaySetInstanceUid,
|
|
stack,
|
|
};
|
|
}
|
|
|
|
export default handleSegmentationStorage;
|