chore(dcmjs): Move DICOM-SR creation / parsing logic from OHIF to dcmjs (#293)
This commit is contained in:
parent
fa73fedb73
commit
2c6bd1ef6f
@ -42,9 +42,10 @@ export class MetadataProvider {
|
||||
const seriesMetadata = data.series;
|
||||
const studyMetadata = data.study;
|
||||
const numImages = data.numImages;
|
||||
|
||||
const metadata = {};
|
||||
|
||||
metadata.frameNumber = data.frameNumber;
|
||||
|
||||
metadata.study = {
|
||||
accessionNumber: studyMetadata.accessionNumber,
|
||||
patientId: studyMetadata.patientId,
|
||||
|
||||
@ -11,7 +11,7 @@ Npm.depends({
|
||||
'cornerstone-math': '0.1.6',
|
||||
'dicom-parser': '1.8.0',
|
||||
'cornerstone-wado-image-loader': '2.1.4',
|
||||
'dcmjs': '0.1.5'
|
||||
'dcmjs': '0.2.1'
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
|
||||
@ -9,11 +9,7 @@ export const retrieveMeasurements = (patientId, timepointIds) => {
|
||||
|
||||
if(!latestSeries) return Promise.resolve({});
|
||||
|
||||
return retrieveMeasurementFromSR(latestSeries).then((value) => {
|
||||
return {
|
||||
length: value
|
||||
}
|
||||
});
|
||||
return retrieveMeasurementFromSR(latestSeries);
|
||||
};
|
||||
|
||||
export const storeMeasurements = (measurementData, timepointIds) => {
|
||||
|
||||
@ -1,77 +0,0 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import { cornerstone } from 'meteor/ohif:cornerstone';
|
||||
import { getInstanceMetadata } from './srUtils';
|
||||
|
||||
export default getLengthMeasurementData = (lengthMeasurementContent, displaySets) => {
|
||||
let lengthStates = [];
|
||||
|
||||
lengthMeasurementContent.forEach(groupItemContent => {
|
||||
const lengthContent = groupItemContent.ContentSequence;
|
||||
const reference = lengthContent.ContentSequence.ReferencedSOPSequence;
|
||||
const lengthState = {};
|
||||
|
||||
lengthState.measuredValue = groupItemContent.MeasuredValueSequence.NumericValue;
|
||||
lengthState.handles = {start: {}, end: {}};
|
||||
[lengthState.handles.start.x,
|
||||
lengthState.handles.start.y,
|
||||
lengthState.handles.end.x,
|
||||
lengthState.handles.end.y] = lengthContent.GraphicData;
|
||||
|
||||
// TODO: Save textbox position in GraphicData?
|
||||
lengthState.handles.textBox = {
|
||||
hasMoved: false,
|
||||
movesIndependently: false,
|
||||
drawnIndependently: true,
|
||||
allowedOutsideImage: true,
|
||||
hasBoundingBox: true
|
||||
}
|
||||
|
||||
lengthState.ReferencedInstanceUID = reference.ReferencedSOPInstanceUID;
|
||||
if (reference.ReferencedFrameNumber && reference.ReferencedFrameNumber !== 'NaN') {
|
||||
lengthState.ReferencedFrameNumber = reference.ReferencedFrameNumber;
|
||||
} else {
|
||||
lengthState.ReferencedFrameNumber = 0;
|
||||
}
|
||||
|
||||
lengthStates.push(lengthState);
|
||||
});
|
||||
|
||||
const lengthMeasurementData = [];
|
||||
|
||||
let measurementNumber = 0;
|
||||
lengthStates.forEach(lengthState => {
|
||||
const sopInstanceUid = lengthState.ReferencedInstanceUID;
|
||||
const instanceMetadata = getInstanceMetadata(displaySets, sopInstanceUid);
|
||||
const imageId = OHIF.viewerbase.getImageId(instanceMetadata);
|
||||
if (!imageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const studyInstanceUid = cornerstone.metaData.get('study', imageId).studyInstanceUid;
|
||||
const seriesInstanceUid = cornerstone.metaData.get('series', imageId).seriesInstanceUid;
|
||||
const patientId = instanceMetadata._study.patientId;
|
||||
const frameIndex = lengthState.ReferencedFrameNumber;
|
||||
const imagePath = [studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex].join('_');
|
||||
const measurement = {
|
||||
handles: lengthState.handles,
|
||||
length: lengthState.measuredValue,
|
||||
imageId,
|
||||
imagePath,
|
||||
sopInstanceUid,
|
||||
seriesInstanceUid,
|
||||
studyInstanceUid,
|
||||
patientId,
|
||||
frameIndex,
|
||||
measurementNumber: ++measurementNumber,
|
||||
userId: 'UserID',
|
||||
timepointId: OHIF.viewer.data.currentTimepointId,
|
||||
toolType: 'length',
|
||||
_id: imageId + measurementNumber,
|
||||
};
|
||||
|
||||
lengthMeasurementData.push(measurement);
|
||||
});
|
||||
|
||||
|
||||
return lengthMeasurementData;
|
||||
};
|
||||
@ -1,79 +0,0 @@
|
||||
export default measurementGroupContentItem = (measurement, sopClassUid) => {
|
||||
const {
|
||||
handles,
|
||||
length,
|
||||
frameIndex,
|
||||
sopInstanceUid
|
||||
} = measurement;
|
||||
const measurementContentItem = [
|
||||
{
|
||||
RelationshipType: 'HAS OBS CONTEXT',
|
||||
ValueType: 'TEXT',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '112039',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Tracking Identifier',
|
||||
},
|
||||
TextValue: 'web annotation',
|
||||
},
|
||||
{
|
||||
RelationshipType: 'HAS OBS CONTEXT',
|
||||
ValueType: 'UIDREF',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '112040',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Tracking Unique Identifier',
|
||||
},
|
||||
UID: dcmjs.data.DicomMetaDictionary.uid(),
|
||||
},
|
||||
{
|
||||
RelationshipType: 'CONTAINS',
|
||||
ValueType: 'CODE',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '121071',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Finding',
|
||||
},
|
||||
ConceptCodeSequence: {
|
||||
CodeValue: 'SAMPLEFINDING',
|
||||
CodingSchemeDesignator: '99dcmjs',
|
||||
CodeMeaning: 'Sample Finding',
|
||||
},
|
||||
},
|
||||
{
|
||||
RelationshipType: 'CONTAINS',
|
||||
ValueType: 'NUM',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: 'G-D7FE',
|
||||
CodingSchemeDesignator: 'SRT',
|
||||
CodeMeaning: 'Length',
|
||||
},
|
||||
MeasuredValueSequence: {
|
||||
MeasurementUnitsCodeSequence: {
|
||||
CodeValue: 'mm',
|
||||
CodingSchemeDesignator: 'UCUM',
|
||||
CodingSchemeVersion: '1.4',
|
||||
CodeMeaning: 'millimeter',
|
||||
},
|
||||
NumericValue: length,
|
||||
},
|
||||
ContentSequence: {
|
||||
RelationshipType: 'INFERRED FROM',
|
||||
ValueType: 'SCOORD',
|
||||
GraphicType: 'POLYLINE',
|
||||
GraphicData: [ handles.start.x, handles.start.y, handles.end.x, handles.end.y ],
|
||||
ContentSequence: {
|
||||
RelationshipType: 'SELECTED FROM',
|
||||
ValueType: 'IMAGE',
|
||||
ReferencedSOPSequence: {
|
||||
ReferencedSOPClassUID: sopClassUid,
|
||||
ReferencedSOPInstanceUID: sopInstanceUid,
|
||||
ReferencedFrameNumber: frameIndex,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return measurementContentItem;
|
||||
};
|
||||
@ -28,13 +28,25 @@ const retrieveMeasurementFromSR = async (series) => {
|
||||
const stowSRFromMeasurements = async (measurements) => {
|
||||
const server = OHIF.servers.getCurrentServer();
|
||||
const url = WADOProxy.convertURL(server.wadoRoot, server);
|
||||
const reportDataset = retrieveDataFromMeasurements(measurements);
|
||||
const denaturalizedMetaheader = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset._meta);
|
||||
const dicomDict = new dcmjs.data.DicomDict(denaturalizedMetaheader);
|
||||
const dataset = retrieveDataFromMeasurements(measurements);
|
||||
const { DicomMetaDictionary, DicomDict } = dcmjs.data;
|
||||
|
||||
dicomDict.dict = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset);
|
||||
const meta = {
|
||||
FileMetaInformationVersion: dataset._meta.FileMetaInformationVersion.Value,
|
||||
MediaStorageSOPClassUID: dataset.SOPClassUID,
|
||||
MediaStorageSOPInstanceUID: dataset.SOPInstanceUID,
|
||||
TransferSyntaxUID: "1.2.840.10008.1.2.1",
|
||||
ImplementationClassUID: DicomMetaDictionary.uid(),
|
||||
ImplementationVersionName: "dcmjs-0.0",
|
||||
};
|
||||
|
||||
const denaturalized = DicomMetaDictionary.denaturalizeDataset(meta);
|
||||
const dicomDict = new DicomDict(denaturalized);
|
||||
|
||||
dicomDict.dict = DicomMetaDictionary.denaturalizeDataset(dataset);
|
||||
|
||||
const part10Buffer = dicomDict.write();
|
||||
|
||||
const config = {
|
||||
url,
|
||||
headers: OHIF.DICOMWeb.getAuthorizationHeader()
|
||||
|
||||
@ -1,199 +1,27 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import { dcmjs } from 'meteor/ohif:cornerstone';
|
||||
import { getInstanceMetadata, getAllDisplaySets } from './srUtils';
|
||||
import getLengthMeasurementGroupContentItem from './getLengthMeasurementGroupContentItem';
|
||||
|
||||
|
||||
export default retrieveDataFromMeasurements = (measurements) => {
|
||||
|
||||
const { studyInstanceUid, seriesInstanceUid, sopInstanceUid } = measurements.allTools[0];
|
||||
|
||||
const displaySets = getAllDisplaySets();
|
||||
const instanceMetadata = getInstanceMetadata(displaySets, sopInstanceUid);
|
||||
const sopClassUid = instanceMetadata._data.sopClassUid;
|
||||
|
||||
// TODO: figure out what is needed to make a dcmjs dataset from
|
||||
// information available in the viewer. Apparently the raw dicom is not available
|
||||
// directly.
|
||||
const derivationSourceDataset = {
|
||||
StudyInstanceUID: studyInstanceUid,
|
||||
SeriesInstanceUID: seriesInstanceUid,
|
||||
SOPInstanceUID: sopInstanceUid,
|
||||
SOPClassUID: sopClassUid
|
||||
};
|
||||
report = new dcmjs.derivations.StructuredReport([derivationSourceDataset]);
|
||||
dataset = report.dataset;
|
||||
|
||||
// TODO: what is the correct metaheader
|
||||
// http://dicom.nema.org/medical/Dicom/current/output/chtml/part10/chapter_7.html
|
||||
// TODO: move meta creation to dcmjs
|
||||
const fileMetaInformationVersionArray = new Uint16Array(1);
|
||||
fileMetaInformationVersionArray[0] = 1;
|
||||
dataset._meta = {
|
||||
FileMetaInformationVersion: fileMetaInformationVersionArray.buffer,
|
||||
MediaStorageSOPClassUID: dataset.SOPClassUID,
|
||||
MediaStorageSOPInstanceUID: dataset.SOPInstanceUID,
|
||||
TransferSyntaxUID: "1.2.840.10008.1.2.1", // Explicit little endian (always for dcmjs?)
|
||||
ImplementationClassUID: dcmjs.data.DicomMetaDictionary.uid(), // TODO: could be git hash or other valid id
|
||||
ImplementationVersionName: "OHIFViewer"
|
||||
};
|
||||
|
||||
// TODO: factor out a lot of this back into dcmjs for use in both
|
||||
// the example and in the Viewer
|
||||
const measurementGroupContentSequence = [];
|
||||
for (measurement of measurements.allTools) {
|
||||
if (measurement.toolType === 'length') {
|
||||
measurementGroupContentSequence.push.apply(measurementGroupContentSequence, getLengthMeasurementGroupContentItem(measurement, sopClassUid));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: make a TID1550 derivation as an SR subclass
|
||||
dataset = Object.assign(dataset, {
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '126000',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Imaging Measurement Report'
|
||||
},
|
||||
ContinuityOfContent: 'SEPARATE',
|
||||
PerformedProcedureCodeSequence: [],
|
||||
CompletionFlag: 'COMPLETE',
|
||||
VerificationFlag: 'UNVERIFIED',
|
||||
ReferencedPerformedProcedureStepSequence: [],
|
||||
InstanceNumber: 1,
|
||||
CurrentRequestedProcedureEvidenceSequence: {
|
||||
StudyInstanceUID: dataset.StudyInstanceUID,
|
||||
ReferencedSeriesSequence: {
|
||||
SeriesInstanceUID: dataset.SeriesInstanceUID,
|
||||
ReferencedSOPSequence: {
|
||||
ReferencedSOPClassUID: derivationSourceDataset.SOPClassUID,
|
||||
ReferencedSOPInstanceUID: derivationSourceDataset.SOPInstanceUID
|
||||
},
|
||||
},
|
||||
},
|
||||
CodingSchemeIdentificationSequence: {
|
||||
CodingSchemeDesignator: "99dcmjs",
|
||||
CodingSchemeName: "Codes used for dcmjs",
|
||||
CodingSchemeVersion: "0",
|
||||
CodingSchemeResponsibleOrganization: "https://github.com/pieper/dcmjs"
|
||||
},
|
||||
ContentTemplateSequence: {
|
||||
MappingResource: 'DCMR',
|
||||
TemplateIdentifier: '1500'
|
||||
},
|
||||
ContentSequence: [
|
||||
{
|
||||
RelationshipType: 'HAS CONCEPT MOD',
|
||||
ValueType: 'CODE',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '121049',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Language of Content Item and Descendants',
|
||||
},
|
||||
ConceptCodeSequence: {
|
||||
CodeValue: 'eng',
|
||||
CodingSchemeDesignator: 'RFC3066',
|
||||
CodeMeaning: 'English',
|
||||
},
|
||||
ContentSequence: {
|
||||
RelationshipType: 'HAS CONCEPT MOD',
|
||||
ValueType: 'CODE',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '121046',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Country of Language',
|
||||
},
|
||||
ConceptCodeSequence: {
|
||||
CodeValue: 'US',
|
||||
CodingSchemeDesignator: 'ISO3166_1',
|
||||
CodeMeaning: 'United States',
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
RelationshipType: 'HAS OBS CONTEXT',
|
||||
ValueType: 'PNAME',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '121008',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Person Observer Name',
|
||||
},
|
||||
PersonName: 'user^web' // TODO: these can be options argument for constructor
|
||||
},
|
||||
{
|
||||
RelationshipType: 'HAS OBS CONTEXT',
|
||||
ValueType: 'TEXT',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: 'RP-100006',
|
||||
CodingSchemeDesignator: '99dcmjs',
|
||||
CodeMeaning: "Person Observer's Login Name"
|
||||
},
|
||||
TextValue: 'user'
|
||||
},
|
||||
{
|
||||
RelationshipType: 'HAS CONCEPT MOD',
|
||||
ValueType: 'CODE',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '121058',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Procedure reported'
|
||||
},
|
||||
ConceptCodeSequence: {
|
||||
CodeValue: '1',
|
||||
CodingSchemeDesignator: '99dcmjs',
|
||||
CodeMeaning: 'Unknown procedure'
|
||||
},
|
||||
},
|
||||
{
|
||||
RelationshipType: 'CONTAINS',
|
||||
ValueType: 'CONTAINER',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '111028',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Image Library',
|
||||
},
|
||||
ContinuityOfContent: 'SEPARATE',
|
||||
ContentSequence: {
|
||||
RelationshipType: 'CONTAINS',
|
||||
ValueType: 'CONTAINER',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '126200',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Image Library Group',
|
||||
},
|
||||
ContinuityOfContent: 'SEPARATE',
|
||||
ContentSequence: {
|
||||
RelationshipType: 'CONTAINS',
|
||||
ValueType: 'IMAGE',
|
||||
ReferencedSOPSequence: {
|
||||
// TODO: this should refer to the UIDs extracted from the toolState / instance info
|
||||
ReferencedSOPClassUID: dataset.SOPClassUID,
|
||||
ReferencedSOPInstanceUID: dataset.SOPInstanceUID,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
RelationshipType: 'CONTAINS',
|
||||
ValueType: 'CONTAINER',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '126010',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Imaging Measurements', // TODO: would be nice to abstract the code sequences (in a dictionary? a service?)
|
||||
},
|
||||
ContinuityOfContent: 'SEPARATE',
|
||||
ContentSequence: {
|
||||
RelationshipType: 'CONTAINS',
|
||||
ValueType: 'CONTAINER',
|
||||
ConceptNameCodeSequence: {
|
||||
CodeValue: '125007',
|
||||
CodingSchemeDesignator: 'DCM',
|
||||
CodeMeaning: 'Measurement Group',
|
||||
},
|
||||
ContinuityOfContent: 'SEPARATE',
|
||||
ContentSequence: measurementGroupContentSequence,
|
||||
},
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
return dataset;
|
||||
const { MeasurementReport } = dcmjs.adapters.Cornerstone;
|
||||
const { getImageIdForImagePath } = OHIF.viewerbase;
|
||||
|
||||
const toolState = {};
|
||||
|
||||
Object.keys(measurements).forEach(measurementType => {
|
||||
const annotations = measurements[measurementType];
|
||||
|
||||
annotations.forEach(annotation => {
|
||||
const imageId = getImageIdForImagePath(annotation.imagePath);
|
||||
toolState[imageId] = toolState[imageId] || {};
|
||||
toolState[imageId][annotation.toolType] = toolState[imageId][annotation.toolType] || {
|
||||
data: []
|
||||
};
|
||||
|
||||
toolState[imageId][annotation.toolType].data.push(annotation);
|
||||
});
|
||||
})
|
||||
|
||||
const report = MeasurementReport.generateReport(toolState, cornerstone.metaData);
|
||||
|
||||
return report.dataset;
|
||||
}
|
||||
|
||||
@ -1,36 +1,58 @@
|
||||
import { dcmjs } from 'meteor/ohif:cornerstone';
|
||||
import getLengthMeasurementData from './getLengthMeasurementData';
|
||||
import { toArray, codeMeaningEquals, getAllDisplaySets } from './srUtils'
|
||||
import {getAllDisplaySets, getInstanceMetadata} from './srUtils'
|
||||
|
||||
const imagingMeasurementsToMeasurementData = (dataset, displaySets) => {
|
||||
// Identify the Imaging Measurements
|
||||
const imagingMeasurementContent = toArray(dataset.ContentSequence).find(codeMeaningEquals("Imaging Measurements"));
|
||||
const { MeasurementReport } = dcmjs.adapters.Cornerstone;
|
||||
const storedMeasurementByToolType = MeasurementReport.generateToolState(dataset);
|
||||
const measurementData = {};
|
||||
let measurementNumber = 0;
|
||||
|
||||
// Retrieve the Measurements themselves
|
||||
const measurementGroupContent = toArray(imagingMeasurementContent.ContentSequence).find(codeMeaningEquals("Measurement Group"));
|
||||
Object.keys(storedMeasurementByToolType).forEach(toolType => {
|
||||
const measurements = storedMeasurementByToolType[toolType];
|
||||
measurementData[toolType] = [];
|
||||
|
||||
// For now, bail out if the dataset is not a TID1500 SR with length measurements
|
||||
// TODO: generalize to the various kinds of report
|
||||
// TODO: generalize to the kinds of measurements the Viewer supports
|
||||
if (dataset.ContentTemplateSequence.TemplateIdentifier !== "1500") {
|
||||
OHIF.log.warn("This package can currently only interpret DICOM SR TID 1500");
|
||||
measurements.forEach(measurement => {
|
||||
const instanceMetadata = getInstanceMetadata(displaySets, measurement.sopInstanceUid);
|
||||
const imageId = OHIF.viewerbase.getImageId(instanceMetadata);
|
||||
if (!imageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
// TODO: Update the OHIF metadata provider, then switch these to use 'generalSeriesModule'
|
||||
const study = cornerstone.metaData.get('study', imageId);
|
||||
const series = cornerstone.metaData.get('series', imageId);
|
||||
const imagePath = [
|
||||
study.studyInstanceUid,
|
||||
series.seriesInstanceUid,
|
||||
measurement.sopInstanceUid,
|
||||
measurement.frameIndex
|
||||
].join('_');
|
||||
|
||||
// Filter to find Length measurements in the Structured Report
|
||||
const lengthMeasurementContent = toArray(measurementGroupContent.ContentSequence).filter(codeMeaningEquals("Length"));
|
||||
const toolData = Object.assign({}, measurement, {
|
||||
imageId,
|
||||
imagePath,
|
||||
seriesInstanceUid: series.seriesInstanceUid,
|
||||
studyInstanceUid: study.studyInstanceUid,
|
||||
patientId: study.patientId,
|
||||
measurementNumber: ++measurementNumber,
|
||||
timepointId: OHIF.viewer.data.currentTimepointId,
|
||||
toolType,
|
||||
_id: imageId + measurementNumber,
|
||||
});
|
||||
|
||||
// Retrieve Length Measurement Data
|
||||
return getLengthMeasurementData(lengthMeasurementContent, displaySets);
|
||||
measurementData[toolType].push(toolData);
|
||||
});
|
||||
})
|
||||
|
||||
return measurementData;
|
||||
};
|
||||
|
||||
export default retrieveDataFromSR = (Part10SRArrayBuffer) => {
|
||||
const allDisplaySets = getAllDisplaySets();
|
||||
|
||||
// get the dicom data as an Object
|
||||
let dicomData = dcmjs.data.DicomMessage.readFile(Part10SRArrayBuffer);
|
||||
let dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
||||
// Get the dicom data as an Object
|
||||
const dicomData = dcmjs.data.DicomMessage.readFile(Part10SRArrayBuffer);
|
||||
const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
||||
|
||||
// Convert the SR into the kind of object the Measurements package is expecting
|
||||
return imagingMeasurementsToMeasurementData(dataset, allDisplaySets);
|
||||
|
||||
@ -2,16 +2,6 @@ import { dcmjs } from 'meteor/ohif:cornerstone';
|
||||
|
||||
const supportedSopClassUIDs = ['1.2.840.10008.5.1.4.1.1.88.22'];
|
||||
|
||||
const toArray = function(x) {
|
||||
return (x.constructor.name === "Array" ? x : [x]);
|
||||
};
|
||||
|
||||
const codeMeaningEquals = (codeMeaningName) => {
|
||||
return (contentItem) => {
|
||||
return contentItem.ConceptNameCodeSequence.CodeMeaning === codeMeaningName;
|
||||
};
|
||||
};
|
||||
|
||||
const getAllDisplaySets = () => {
|
||||
const allStudies = OHIF.viewer.Studies.all();
|
||||
let allDisplaySets = [];
|
||||
@ -66,14 +56,8 @@ const getLatestSRSeries = () => {
|
||||
return latestSeries;
|
||||
};
|
||||
|
||||
const stringToArray = (string) => {
|
||||
return Uint8Array.from(Array.from(string).map(letter => letter.charCodeAt(0)))
|
||||
};
|
||||
|
||||
export {
|
||||
codeMeaningEquals,
|
||||
getAllDisplaySets,
|
||||
getInstanceMetadata,
|
||||
getLatestSRSeries,
|
||||
toArray
|
||||
}
|
||||
|
||||
@ -25,7 +25,5 @@ if (Meteor.settings &&
|
||||
CurrentServer.insert({
|
||||
serverId: newServer._id
|
||||
});
|
||||
|
||||
console.log('test');
|
||||
}
|
||||
|
||||
|
||||
@ -35,12 +35,13 @@ function createAndAddStack(stackMap, study, displaySet) {
|
||||
if (numberOfFrames > 1) {
|
||||
OHIF.log.info('Multiframe image detected');
|
||||
for (let i = 0; i < numberOfFrames; i++) {
|
||||
metaData.frame = i;
|
||||
metaData.frameNumber = i;
|
||||
imageId = getImageId(image, i);
|
||||
imageIds.push(imageId);
|
||||
metadataProvider.addMetadata(imageId, metaData);
|
||||
}
|
||||
} else {
|
||||
metaData.frameNumber = 1;
|
||||
imageId = getImageId(image);
|
||||
imageIds.push(imageId);
|
||||
metadataProvider.addMetadata(imageId, metaData);
|
||||
|
||||
@ -15,8 +15,5 @@ export function getWADORSImageId(instance, frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
const imageId = `wadors:${uri}`;
|
||||
OHIF.log.info('WADO-RS ImageID: ' + imageId);
|
||||
|
||||
return imageId;
|
||||
return `wadors:${uri}`;
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user