Begin adding DICOM Segmentation handling to Cornerstone plugin via dcmjs
This commit is contained in:
parent
b93a677ef3
commit
bf8f737fec
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -6,10 +6,4 @@
|
|||||||
url = git@github.com:OHIF/react-viewerbase.git
|
url = git@github.com:OHIF/react-viewerbase.git
|
||||||
[submodule "Packages-react/react-cornerstone-viewport"]
|
[submodule "Packages-react/react-cornerstone-viewport"]
|
||||||
path = Packages-react/react-cornerstone-viewport
|
path = Packages-react/react-cornerstone-viewport
|
||||||
url = git@github.com:cornerstonejs/react-cornerstone-viewport.git
|
url = git@github.com:cornerstonejs/react-cornerstone-viewport.git
|
||||||
[submodule "Packages-react/plugins/VTKPlugin"]
|
|
||||||
path = Packages-react/plugins/VTKPlugin
|
|
||||||
url = git@github.com:OHIF/VTKPlugin.git
|
|
||||||
[submodule "Packages-react/plugins/OpenLayersPlugin"]
|
|
||||||
path = Packages-react/plugins/OpenLayersPlugin
|
|
||||||
url = git@github.com:OHIF/OpenLayersPlugin.git
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import dicomParser from 'dicom-parser';
|
import dicomParser from 'dicom-parser';
|
||||||
import TypedArrayProp from './TypedArrayProp';
|
import TypedArrayProp from './TypedArrayProp';
|
||||||
|
|
||||||
@ -14,11 +14,10 @@ class DicomPDFViewport extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
byteArray: TypedArrayProp.uint8,
|
byteArray: TypedArrayProp.uint8
|
||||||
};
|
};
|
||||||
|
|
||||||
renderPDF = (dataSet) => {
|
renderPDF = dataSet => {
|
||||||
debugger;
|
|
||||||
const sopClassUid = dataSet.string('x00080016');
|
const sopClassUid = dataSet.string('x00080016');
|
||||||
|
|
||||||
if (sopClassUid !== SOP_CLASS_UIDS.ENCAPSULATED_PDF) {
|
if (sopClassUid !== SOP_CLASS_UIDS.ENCAPSULATED_PDF) {
|
||||||
@ -29,15 +28,15 @@ class DicomPDFViewport extends Component {
|
|||||||
const offset = fileTag.dataOffset;
|
const offset = fileTag.dataOffset;
|
||||||
const remainder = offset + fileTag.length;
|
const remainder = offset + fileTag.length;
|
||||||
const pdfByteArray = dataSet.byteArray.slice(offset, remainder);
|
const pdfByteArray = dataSet.byteArray.slice(offset, remainder);
|
||||||
const PDF = new Blob([pdfByteArray], {type: 'application/pdf'});
|
const PDF = new Blob([pdfByteArray], { type: 'application/pdf' });
|
||||||
const fileURL = URL.createObjectURL(PDF);
|
const fileURL = URL.createObjectURL(PDF);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
fileURL
|
fileURL
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
parseByteArray = (byteArray) => {
|
parseByteArray = byteArray => {
|
||||||
const options = {
|
const options = {
|
||||||
untilTag: ''
|
untilTag: ''
|
||||||
};
|
};
|
||||||
@ -46,14 +45,14 @@ class DicomPDFViewport extends Component {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
dataSet = dicomParser.parseDicom(byteArray, options);
|
dataSet = dicomParser.parseDicom(byteArray, options);
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
this.setState({
|
this.setState({
|
||||||
error
|
error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataSet
|
return dataSet;
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const dataSet = this.parseByteArray(this.props.byteArray);
|
const dataSet = this.parseByteArray(this.props.byteArray);
|
||||||
@ -63,18 +62,22 @@ class DicomPDFViewport extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className={'DicomPDFViewport'} style={{width: '100%', height: '100%'}}>
|
<div
|
||||||
{this.state.fileURL &&
|
className={'DicomPDFViewport'}
|
||||||
<object data={this.state.fileURL} type="application/pdf" width="100%" height="100%">
|
style={{ width: '100%', height: '100%' }}
|
||||||
</object>
|
>
|
||||||
}
|
{this.state.fileURL && (
|
||||||
{this.state.error &&
|
<object
|
||||||
<h2>{JSON.stringify(this.state.error)}</h2>
|
data={this.state.fileURL}
|
||||||
}
|
type="application/pdf"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{this.state.error && <h2>{JSON.stringify(this.state.error)}</h2>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default DicomPDFViewport;
|
export default DicomPDFViewport;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from 'ohif-core';
|
||||||
import OHIFComponentPlugin from './OHIFComponentPlugin.js';
|
import OHIFComponentPlugin from './OHIFComponentPlugin.js';
|
||||||
import DicomPDFViewport from './DicomPDFViewport';
|
import DicomPDFViewport from './DicomPDFViewport';
|
||||||
@ -10,13 +10,13 @@ class OHIFDicomPDFViewport extends Component {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
studies: PropTypes.object,
|
studies: PropTypes.object,
|
||||||
displaySet: PropTypes.object,
|
displaySet: PropTypes.object,
|
||||||
viewportIndex: PropTypes.number,
|
viewportIndex: PropTypes.number
|
||||||
};
|
};
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
byteArray: null,
|
byteArray: null,
|
||||||
error: null
|
error: null
|
||||||
}
|
};
|
||||||
|
|
||||||
static id = 'DicomPDFViewportPDF';
|
static id = 'DicomPDFViewportPDF';
|
||||||
|
|
||||||
@ -41,8 +41,9 @@ class OHIFDicomPDFViewport extends Component {
|
|||||||
error
|
error
|
||||||
});
|
});
|
||||||
|
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieveDicomData(studyInstanceUid, seriesInstanceUid, sopInstanceUid, wadoRoot, wadoUri, authorizationHeaders) {
|
retrieveDicomData(studyInstanceUid, seriesInstanceUid, sopInstanceUid, wadoRoot, wadoUri, authorizationHeaders) {
|
||||||
@ -63,10 +64,10 @@ class OHIFDicomPDFViewport extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<OHIFComponentPlugin {...pluginProps}>
|
<OHIFComponentPlugin {...pluginProps}>
|
||||||
{this.state.byteArray && <DicomPDFViewport byteArray={this.state.byteArray}/>}
|
{this.state.byteArray && (
|
||||||
{this.state.error &&
|
<DicomPDFViewport byteArray={this.state.byteArray} />
|
||||||
<h2>{JSON.stringify(this.state.error)}</h2>
|
)}
|
||||||
}
|
{this.state.error && <h2>{JSON.stringify(this.state.error)}</h2>}
|
||||||
</OHIFComponentPlugin>
|
</OHIFComponentPlugin>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit ede7e30e012174a0307f10e00b70e22bdfbe1b46
|
Subproject commit 8850a092a0b860bc9d423fcc49512567251fc47b
|
||||||
2
Packages-react/ohif-viewer/.gitignore
vendored
2
Packages-react/ohif-viewer/.gitignore
vendored
@ -3,3 +3,5 @@ dist
|
|||||||
node_modules
|
node_modules
|
||||||
yarn.lock
|
yarn.lock
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
|
src/sha.js
|
||||||
|
src/version.js
|
||||||
@ -97,9 +97,9 @@
|
|||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"cornerstone-core": "^2.2.8",
|
"cornerstone-core": "^2.2.8",
|
||||||
"cornerstone-math": "^0.1.8",
|
"cornerstone-math": "^0.1.8",
|
||||||
"cornerstone-tools": "3.0.0-b.1512",
|
"cornerstone-tools": "3.0.0-b.1679",
|
||||||
"cornerstone-wado-image-loader": "^2.2.3",
|
"cornerstone-wado-image-loader": "^2.2.3",
|
||||||
"dcmjs": "^0.3.0",
|
"dcmjs": "^0.3.2",
|
||||||
"dicom-parser": "^1.8.3",
|
"dicom-parser": "^1.8.3",
|
||||||
"dicomweb-client": "^0.4.1",
|
"dicomweb-client": "^0.4.1",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
@ -110,13 +110,13 @@
|
|||||||
"oidc-client": "^1.6.1",
|
"oidc-client": "^1.6.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react-bootstrap-modal": "^4.2.0",
|
"react-bootstrap-modal": "^4.2.0",
|
||||||
"react-cornerstone-viewport": "^0.1.8",
|
"react-cornerstone-viewport": "^0.1.9",
|
||||||
"react-dnd": "^7.0.2",
|
"react-dnd": "^7.0.2",
|
||||||
"react-dnd-html5-backend": "^7.0.2",
|
"react-dnd-html5-backend": "^7.0.2",
|
||||||
"react-redux": "^6.0.0",
|
"react-redux": "^6.0.0",
|
||||||
"react-router": "^4.3.1",
|
"react-router": "^4.3.1",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
"react-viewerbase": "^0.2.1",
|
"react-viewerbase": "^0.2.4",
|
||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
"redux-oidc": "^3.1.0"
|
"redux-oidc": "^3.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,6 +95,13 @@ const defaultButtons = [
|
|||||||
svgUrl: `${Icons}#icon-tools-measure-target`,
|
svgUrl: `${Icons}#icon-tools-measure-target`,
|
||||||
active: false
|
active: false
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
command: 'Brush',
|
||||||
|
type: 'tool',
|
||||||
|
text: 'Brush',
|
||||||
|
iconClasses: 'fa fa-circle',
|
||||||
|
active: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
command: 'reset',
|
command: 'reset',
|
||||||
type: 'command',
|
type: 'command',
|
||||||
|
|||||||
@ -1,29 +1,48 @@
|
|||||||
import React, { Component } from "react";
|
import React, { Component } from 'react';
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from 'prop-types';
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from 'ohif-core';
|
||||||
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
|
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
|
||||||
import OHIFComponentPlugin from '../OHIFComponentPlugin.js';
|
import OHIFComponentPlugin from '../OHIFComponentPlugin.js';
|
||||||
import cornerstoneTools from "cornerstone-tools";
|
import cornerstoneTools from 'cornerstone-tools';
|
||||||
import cornerstone from "cornerstone-core";
|
import cornerstone from 'cornerstone-core';
|
||||||
import './config';
|
import './config';
|
||||||
|
import handleSegmentationStorage from './handleSegmentationStorage.js';
|
||||||
|
|
||||||
const { StackManager } = OHIF.utils;
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
// Create the synchronizer used to update reference lines
|
// Create the synchronizer used to update reference lines
|
||||||
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
|
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer(
|
||||||
|
'cornerstonenewimage',
|
||||||
|
cornerstoneTools.updateImageSynchronizer
|
||||||
|
);
|
||||||
|
|
||||||
// Metadata configuration
|
// Metadata configuration
|
||||||
const metadataProvider = new OHIF.cornerstone.MetadataProvider();
|
const metadataProvider = new OHIF.cornerstone.MetadataProvider();
|
||||||
|
|
||||||
cornerstone.metaData.addProvider(metadataProvider.provider.bind(metadataProvider));
|
cornerstone.metaData.addProvider(
|
||||||
|
metadataProvider.provider.bind(metadataProvider)
|
||||||
|
);
|
||||||
|
|
||||||
StackManager.setMetadataProvider(metadataProvider);
|
StackManager.setMetadataProvider(metadataProvider);
|
||||||
|
|
||||||
|
const SOP_CLASSES = {
|
||||||
|
SEGMENTATION_STORAGE: '1.2.840.10008.5.1.4.1.1.66.4'
|
||||||
|
};
|
||||||
|
|
||||||
|
const specialCaseHandlers = {};
|
||||||
|
specialCaseHandlers[
|
||||||
|
SOP_CLASSES.SEGMENTATION_STORAGE
|
||||||
|
] = handleSegmentationStorage;
|
||||||
|
|
||||||
class OHIFCornerstoneViewportPlugin extends Component {
|
class OHIFCornerstoneViewportPlugin extends Component {
|
||||||
|
state = {
|
||||||
|
viewportData: null
|
||||||
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
studies: PropTypes.object,
|
studies: PropTypes.object,
|
||||||
displaySet: PropTypes.object,
|
displaySet: PropTypes.object,
|
||||||
viewportIndex: PropTypes.number,
|
viewportIndex: PropTypes.number
|
||||||
};
|
};
|
||||||
|
|
||||||
static id = 'CornerstoneViewportPlugin';
|
static id = 'CornerstoneViewportPlugin';
|
||||||
@ -39,9 +58,11 @@ class OHIFCornerstoneViewportPlugin extends Component {
|
|||||||
|
|
||||||
static getCornerstoneStack(studies, studyInstanceUid, displaySetInstanceUid) {
|
static getCornerstoneStack(studies, studyInstanceUid, displaySetInstanceUid) {
|
||||||
// Create shortcut to displaySet
|
// Create shortcut to displaySet
|
||||||
const study = studies.find(study => study.studyInstanceUid === studyInstanceUid);
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
const displaySet = study.displaySets.find((set) => {
|
const displaySet = study.displaySets.find(set => {
|
||||||
return set.displaySetInstanceUid === displaySetInstanceUid;
|
return set.displaySetInstanceUid === displaySetInstanceUid;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -49,37 +70,104 @@ class OHIFCornerstoneViewportPlugin extends Component {
|
|||||||
return StackManager.findOrCreateStack(study, displaySet);
|
return StackManager.findOrCreateStack(study, displaySet);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getPluginViewportData = (studies, studyInstanceUid, displaySetInstanceUid) => {
|
static getPluginViewportData = (
|
||||||
const currentStack = OHIFCornerstoneViewportPlugin.getCornerstoneStack(studies, studyInstanceUid, displaySetInstanceUid);
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
) => {
|
||||||
|
const currentStack = OHIFCornerstoneViewportPlugin.getCornerstoneStack(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
// Clone the stack here so we don't mutate it later
|
// Clone the stack here so we don't mutate it later
|
||||||
const stack = Object.assign({}, currentStack);
|
const stack = Object.assign({}, currentStack);
|
||||||
stack.currentImageIdIndex = 0;
|
stack.currentImageIdIndex = 0;
|
||||||
|
|
||||||
return stack;
|
return stack;
|
||||||
|
};
|
||||||
|
|
||||||
|
getViewportData = async (
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopClassUid
|
||||||
|
) => {
|
||||||
|
let viewportData;
|
||||||
|
|
||||||
|
switch (sopClassUid) {
|
||||||
|
case SOP_CLASSES.SEGMENTATION_STORAGE:
|
||||||
|
const specialCaseHandler =
|
||||||
|
specialCaseHandlers[SOP_CLASSES.SEGMENTATION_STORAGE];
|
||||||
|
|
||||||
|
viewportData = await specialCaseHandler(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
const stack = OHIFCornerstoneViewportPlugin.getPluginViewportData(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
viewportData = {
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
stack
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewportData;
|
||||||
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { studies, displaySet } = this.props.viewportData;
|
||||||
|
const {
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopClassUids
|
||||||
|
} = displaySet;
|
||||||
|
|
||||||
|
if (sopClassUids.length > 1) {
|
||||||
|
console.warn(
|
||||||
|
'More than one SOPClassUid in the same series is not yet supported.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sopClassUid = sopClassUids[0];
|
||||||
|
|
||||||
|
this.getViewportData(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
sopClassUid
|
||||||
|
).then(viewportData => {
|
||||||
|
this.setState({
|
||||||
|
viewportData
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { viewportIndex } = this.props;
|
|
||||||
const { studies, displaySet } = this.props.viewportData;
|
|
||||||
const { studyInstanceUid, displaySetInstanceUid } = displaySet;
|
|
||||||
const stack = OHIFCornerstoneViewportPlugin.getPluginViewportData(studies, studyInstanceUid, displaySetInstanceUid);
|
|
||||||
const viewportData = {
|
|
||||||
studyInstanceUid,
|
|
||||||
displaySetInstanceUid,
|
|
||||||
stack
|
|
||||||
};
|
|
||||||
|
|
||||||
const { id, init, destroy } = OHIFCornerstoneViewportPlugin;
|
const { id, init, destroy } = OHIFCornerstoneViewportPlugin;
|
||||||
const pluginProps = { id, init, destroy };
|
const pluginProps = { id, init, destroy };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<OHIFComponentPlugin {...pluginProps}>
|
<OHIFComponentPlugin {...pluginProps}>
|
||||||
<ConnectedCornerstoneViewport viewportData={viewportData} viewportIndex={viewportIndex}/>
|
{this.state.viewportData && (
|
||||||
|
<ConnectedCornerstoneViewport
|
||||||
|
viewportData={this.state.viewportData}
|
||||||
|
viewportIndex={this.props.viewportIndex}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</OHIFComponentPlugin>
|
</OHIFComponentPlugin>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default OHIFCornerstoneViewportPlugin;
|
export default OHIFCornerstoneViewportPlugin;
|
||||||
|
|||||||
@ -0,0 +1,151 @@
|
|||||||
|
import OHIF from 'ohif-core';
|
||||||
|
import cornerstoneTools from 'cornerstone-tools';
|
||||||
|
import * as dcmjs from 'dcmjs';
|
||||||
|
|
||||||
|
const { StackManager } = 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 getCornerstoneStack(studies, studyInstanceUid, displaySetInstanceUid) {
|
||||||
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create shortcut to displaySet
|
||||||
|
const displaySet = getDisplaySet(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
// Get stack from Stack Manager
|
||||||
|
const stack = StackManager.findOrCreateStack(study, displaySet);
|
||||||
|
|
||||||
|
// Clone the stack here so we don't mutate it later
|
||||||
|
const stackClone = Object.assign({}, stack);
|
||||||
|
stackClone.currentImageIdIndex = 0;
|
||||||
|
|
||||||
|
return stackClone;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseSeg(arrayBuffer, imageIds) {
|
||||||
|
return dcmjs.adapters.Cornerstone.Segmentation.readToolState(
|
||||||
|
imageIds,
|
||||||
|
arrayBuffer
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function retrieveDicomData(wadoUri) {
|
||||||
|
// TODO: Authorization header depends on the server. If we ever have multiple servers
|
||||||
|
// we will need to figure out how / when to pass this information in.
|
||||||
|
return fetch(wadoUri, {
|
||||||
|
headers: OHIF.DICOMWeb.getAuthorizationHeader()
|
||||||
|
}).then(response => response.arrayBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleSegmentationStorage(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
) {
|
||||||
|
const study = studies.find(
|
||||||
|
study => study.studyInstanceUid === studyInstanceUid
|
||||||
|
);
|
||||||
|
const displaySet = getDisplaySet(
|
||||||
|
studies,
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
const segWadoUri = displaySet.images[0].getData().wadouri;
|
||||||
|
const arrayBuffer = await retrieveDicomData(segWadoUri);
|
||||||
|
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
|
||||||
|
.reverse()
|
||||||
|
.map(image => image.getImageId());
|
||||||
|
const results = parseSeg(arrayBuffer, imageIds);
|
||||||
|
|
||||||
|
if (!results) {
|
||||||
|
throw new Error('Fractional segmentations are not supported');
|
||||||
|
}
|
||||||
|
|
||||||
|
const { segMetadata, toolState } = results;
|
||||||
|
|
||||||
|
segMetadata.seriesInstanceUid = seriesInstanceUid;
|
||||||
|
|
||||||
|
addSegMetadataToCornerstoneToolState(
|
||||||
|
segMetadata,
|
||||||
|
toolState,
|
||||||
|
displaySetInstanceUid
|
||||||
|
);
|
||||||
|
|
||||||
|
const cachedStack = StackManager.findOrCreateStack(
|
||||||
|
study,
|
||||||
|
referenceDisplaySet
|
||||||
|
);
|
||||||
|
const stack = Object.assign({}, cachedStack);
|
||||||
|
stack.currentImageIdIndex = 0;
|
||||||
|
|
||||||
|
return {
|
||||||
|
studyInstanceUid,
|
||||||
|
displaySetInstanceUid,
|
||||||
|
stack
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default handleSegmentationStorage;
|
||||||
@ -108,6 +108,24 @@ props.oidc = [
|
|||||||
]
|
]
|
||||||
}; */
|
}; */
|
||||||
|
|
||||||
|
/*props.servers = {
|
||||||
|
"dicomWeb": [
|
||||||
|
{
|
||||||
|
"name": "DCM4CHEE",
|
||||||
|
"wadoUriRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado",
|
||||||
|
"qidoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
|
"wadoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
|
"qidoSupportsIncludeField": true,
|
||||||
|
"imageRendering": "wadors",
|
||||||
|
"thumbnailRendering": "wadors",
|
||||||
|
"requestOptions": {
|
||||||
|
"requestFromBrowser": true,
|
||||||
|
"auth": "admin:admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
UI settings
|
UI settings
|
||||||
Plugins
|
Plugins
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
export default '298749821742198987421'
|
export default 'f06e629c2f2256576e7de5bda48124b3a808ab9b';
|
||||||
|
|||||||
@ -892,7 +892,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
regenerator-runtime "^0.12.0"
|
regenerator-runtime "^0.12.0"
|
||||||
|
|
||||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0":
|
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1":
|
||||||
version "7.3.1"
|
version "7.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.1.tgz#574b03e8e8a9898eaf4a872a92ea20b7846f6f2a"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.1.tgz#574b03e8e8a9898eaf4a872a92ea20b7846f6f2a"
|
||||||
integrity sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==
|
integrity sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==
|
||||||
@ -1856,7 +1856,7 @@ babel-plugin-transform-react-remove-prop-types@0.4.20:
|
|||||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.20.tgz#688bdea1e27ea0023775dea817fa2d3f8df8802b"
|
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.20.tgz#688bdea1e27ea0023775dea817fa2d3f8df8802b"
|
||||||
integrity sha512-bWQ8e7LsgdFpyHU/RabjDAjVhL7KLAJXEt0nb0LANFje8YAGA8RlZv88a72aCswOxELWULkYuJqfFoKgs58Tng==
|
integrity sha512-bWQ8e7LsgdFpyHU/RabjDAjVhL7KLAJXEt0nb0LANFje8YAGA8RlZv88a72aCswOxELWULkYuJqfFoKgs58Tng==
|
||||||
|
|
||||||
babel-polyfill@>=6.9.1, babel-polyfill@^6.26.0:
|
babel-polyfill@>=6.9.1:
|
||||||
version "6.26.0"
|
version "6.26.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
|
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153"
|
||||||
integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=
|
integrity sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=
|
||||||
@ -2969,10 +2969,10 @@ cornerstone-math@^0.1.6, cornerstone-math@^0.1.7, cornerstone-math@^0.1.8:
|
|||||||
resolved "https://registry.yarnpkg.com/cornerstone-math/-/cornerstone-math-0.1.8.tgz#68ab1f9e4fdcd7c5cb23a0d2eb4263f9f894f1c5"
|
resolved "https://registry.yarnpkg.com/cornerstone-math/-/cornerstone-math-0.1.8.tgz#68ab1f9e4fdcd7c5cb23a0d2eb4263f9f894f1c5"
|
||||||
integrity sha512-x7NEQHBtVG7j1yeyj/aRoKTpXv1Vh2/H9zNLMyqYJDtJkNng8C4Q8M3CgZ1qer0Yr7eVq2x+Ynmj6kfOm5jXKw==
|
integrity sha512-x7NEQHBtVG7j1yeyj/aRoKTpXv1Vh2/H9zNLMyqYJDtJkNng8C4Q8M3CgZ1qer0Yr7eVq2x+Ynmj6kfOm5jXKw==
|
||||||
|
|
||||||
cornerstone-tools@3.0.0-b.1512:
|
cornerstone-tools@3.0.0-b.1679:
|
||||||
version "3.0.0-b.1512"
|
version "3.0.0-b.1679"
|
||||||
resolved "https://registry.yarnpkg.com/cornerstone-tools/-/cornerstone-tools-3.0.0-b.1512.tgz#64e60709b7b638c08d201313a5748aa6f5145337"
|
resolved "https://registry.yarnpkg.com/cornerstone-tools/-/cornerstone-tools-3.0.0-b.1679.tgz#e97c4ddc5b229faeb625682412a7cfd77b9fc70c"
|
||||||
integrity sha512-+lpoPJnTTkGq61XZzrNfAVhYJprBYqFZc++D0TgVUUOfAlXn5I016+cabfRQ/K65ecTfd8RitFK/LrIBUE7D2Q==
|
integrity sha512-t69w5lgS/eZQXdyEfLixWuGZbpspNmyhvu8af9cYQDQ445tchvBtSSD6h1u+5m1gXZvV4LxwBqD8rwZTpMzH9Q==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "7.1.2"
|
"@babel/runtime" "7.1.2"
|
||||||
cornerstone-math "^0.1.7"
|
cornerstone-math "^0.1.7"
|
||||||
@ -3404,13 +3404,14 @@ date-now@^0.1.4:
|
|||||||
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
|
resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b"
|
||||||
integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
|
integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=
|
||||||
|
|
||||||
dcmjs@^0.3.0:
|
dcmjs@^0.3.2:
|
||||||
version "0.3.0"
|
version "0.3.2"
|
||||||
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.3.0.tgz#d065a65b3df14d6028542760de6143f0acdc2ed0"
|
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.3.2.tgz#18bdcccd0083e01269c588fbbb019e44897b952e"
|
||||||
integrity sha512-k6La/q+ROPjoAPQCWIWd49XUGUzolLG6qJhEMdSAhYEa4WP6CLyjIgL1Ul2NqM7Vxyd74ydHi537AWxOtdSxmA==
|
integrity sha512-6tA4A+22c6AK+5wqtU3cS1lNtEPEvndgeRdZfbuMJNC+OiPQFhPmK8+TrNF13ca9QWHUCyRT9mAfAMuio6GnEg==
|
||||||
dependencies:
|
dependencies:
|
||||||
babel-polyfill "^6.26.0"
|
"@babel/polyfill" "^7.2.5"
|
||||||
babel-runtime "^6.26.0"
|
"@babel/runtime" "^7.3.1"
|
||||||
|
loglevel "^1.6.1"
|
||||||
|
|
||||||
debug@*, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0:
|
debug@*, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
@ -7362,7 +7363,7 @@ log-update@^2.3.0:
|
|||||||
cli-cursor "^2.0.0"
|
cli-cursor "^2.0.0"
|
||||||
wrap-ansi "^3.0.1"
|
wrap-ansi "^3.0.1"
|
||||||
|
|
||||||
loglevel@^1.4.1:
|
loglevel@^1.4.1, loglevel@^1.6.1:
|
||||||
version "1.6.1"
|
version "1.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
|
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
|
||||||
integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
|
integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=
|
||||||
@ -10066,7 +10067,7 @@ react-bootstrap-modal@^4.2.0:
|
|||||||
react-overlays "^0.8.0"
|
react-overlays "^0.8.0"
|
||||||
react-transition-group "^2.0.0"
|
react-transition-group "^2.0.0"
|
||||||
|
|
||||||
react-cornerstone-viewport@^0.1.8:
|
react-cornerstone-viewport@^0.1.9:
|
||||||
version "0.1.9"
|
version "0.1.9"
|
||||||
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.9.tgz#28cbf2ec3b13976f271e7cc30e6386c5d97e854c"
|
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.9.tgz#28cbf2ec3b13976f271e7cc30e6386c5d97e854c"
|
||||||
integrity sha512-demadfvFX9uOp+lV0wV6Pom6g3Dagdt/97m3mTAN7o236mCDVBn1SBHBkVIjOeKkkPmXIV2q0dlHuINsnlK4TA==
|
integrity sha512-demadfvFX9uOp+lV0wV6Pom6g3Dagdt/97m3mTAN7o236mCDVBn1SBHBkVIjOeKkkPmXIV2q0dlHuINsnlK4TA==
|
||||||
@ -10264,7 +10265,7 @@ react-transition-group@^2.0.0, react-transition-group@^2.2.0:
|
|||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
react-lifecycles-compat "^3.0.4"
|
react-lifecycles-compat "^3.0.4"
|
||||||
|
|
||||||
react-viewerbase@^0.2.1:
|
react-viewerbase@^0.2.4:
|
||||||
version "0.2.4"
|
version "0.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-viewerbase/-/react-viewerbase-0.2.4.tgz#c247cb39cfbf0db803475a8f35f7463a5a61e397"
|
resolved "https://registry.yarnpkg.com/react-viewerbase/-/react-viewerbase-0.2.4.tgz#c247cb39cfbf0db803475a8f35f7463a5a61e397"
|
||||||
integrity sha512-U50z7lCbgL4tAt/ZbkzAGAi5Q/RcPoT12XuRWy+jlq6oH+GtoQtLU7pA4DQkFAk73ebBYH6yL+2r296i8zDGTg==
|
integrity sha512-U50z7lCbgL4tAt/ZbkzAGAi5Q/RcPoT12XuRWy+jlq6oH+GtoQtLU7pA4DQkFAk73ebBYH6yL+2r296i8zDGTg==
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit 2405290b1e5e80d13bae5358625463605eb83930
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit dd8b3a7edddc5bc97af49bd4ceeb89c5f7d56dfb
|
|
||||||
@ -1 +1 @@
|
|||||||
Subproject commit 1a66caa34d5a841ef414437a53093f7d22be840c
|
Subproject commit 59d177cb0e705441f58ce57d37a8122011522868
|
||||||
Loading…
Reference in New Issue
Block a user