////////////////////////////////////////////////////////////////////////// // // // This is a generated file. You can view the original // // source in your browser if your browser supports source maps. // // Source maps are supported by all recent versions of Chrome, Safari, // // and Firefox, and by Internet Explorer 11. // // // ////////////////////////////////////////////////////////////////////////// (function () { /* Imports */ var Meteor = Package.meteor.Meteor; var global = Package.meteor.global; var meteorEnv = Package.meteor.meteorEnv; var cornerstone = Package['ohif:cornerstone'].cornerstone; var cornerstoneMath = Package['ohif:cornerstone'].cornerstoneMath; var cornerstoneTools = Package['ohif:cornerstone'].cornerstoneTools; var cornerstoneWADOImageLoader = Package['ohif:cornerstone'].cornerstoneWADOImageLoader; var dicomParser = Package['ohif:cornerstone'].dicomParser; var dcmjs = Package['ohif:cornerstone'].dcmjs; var dialogPolyfill = Package['ohif:viewerbase'].dialogPolyfill; var MeasurementSchemaTypes = Package['ohif:measurements'].MeasurementSchemaTypes; var WADOProxy = Package['ohif:wadoproxy'].WADOProxy; var meteorInstall = Package.modules.meteorInstall; var meteorBabelHelpers = Package['babel-runtime'].meteorBabelHelpers; var Promise = Package.promise.Promise; var Symbol = Package['ecmascript-runtime-client'].Symbol; var Map = Package['ecmascript-runtime-client'].Map; var Set = Package['ecmascript-runtime-client'].Set; /* Package-scope variables */ var getLengthMeasurementData, measurementGroupContentItem, retrieveDataFromMeasurements, report, dataset, measurement, retrieveDataFromSR, headerArray, contentArray, footerArray; var require = meteorInstall({"node_modules":{"meteor":{"ohif:measurement-table":{"client":{"index.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/index.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); module.export({ MeasurementTable: function () { return MeasurementTable; } }); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var Session; module.watch(require("meteor/session"), { Session: function (v) { Session = v; } }, 1); var configureApis; module.watch(require("./configuration/configuration"), { configureApis: function (v) { configureApis = v; } }, 2); var MeasurementTable = /*#__PURE__*/ function () { function MeasurementTable() { configureApis(); Session.set('TimepointsReady', false); Session.set('MeasurementsReady', false); } var _proto = MeasurementTable.prototype; _proto.onCreated = function () { function onCreated(instance) { var _this = this; var _OHIF$measurements, TimepointApi, MeasurementApi, timepointApi, measurementApi, apis, patientId; return _regenerator.default.async(function () { function onCreated$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _OHIF$measurements = OHIF.measurements, TimepointApi = _OHIF$measurements.TimepointApi, MeasurementApi = _OHIF$measurements.MeasurementApi; OHIF.viewer.data.currentTimepointId = 'TimepointId'; timepointApi = new TimepointApi(OHIF.viewer.data.currentTimepointId); measurementApi = new MeasurementApi(timepointApi); apis = { timepointApi: timepointApi, measurementApi: measurementApi }; Object.assign(OHIF.viewer, apis); Object.assign(instance.data, apis); patientId = instance.data.studies[0].patientId; _context.next = 10; return _regenerator.default.awrap(timepointApi.retrieveTimepoints({ patientId: patientId })); case 10: Session.set('TimepointsReady', true); _context.next = 13; return _regenerator.default.awrap(measurementApi.retrieveMeasurements(patientId, [OHIF.viewer.data.currentTimepointId])); case 13: Session.set('MeasurementsReady', true); measurementApi.syncMeasurementsAndToolData(); this.firstMeasurementActivated = false; instance.autorun(function () { if (!Session.get('TimepointsReady') || !Session.get('MeasurementsReady') || !Session.get('ViewerReady') || _this.firstMeasurementActivated) { return; } _this.jumpToFirstMeasurement(); }); instance.measurementModifiedHandler = _.throttle(function (event, instance) { OHIF.measurements.MeasurementHandlers.onModified(event, instance); }, 300); case 18: case "end": return _context.stop(); } } } return onCreated$; }(), null, this); } return onCreated; }(); _proto.onDestroyed = function () { function onDestroyed() { Session.set('TimepointsReady', false); Session.set('MeasurementsReady', false); } return onDestroyed; }(); _proto.jumpToFirstMeasurement = function () { function jumpToFirstMeasurement() { // Find and activate the first measurement by Lesion Number // NOTE: This is inefficient, we should be using a hanging protocol // to hang the first measurement's imageId immediately, rather // than changing images after initial loading... var config = OHIF.measurements.MeasurementApi.getConfiguration(); var tools = config.measurementTools[0].childTools; var firstTool = tools[Object.keys(tools)[0]]; var measurementTypeId = firstTool.id; var collection = OHIF.viewer.measurementApi.tools[measurementTypeId]; var sorting = { sort: { measurementNumber: -1 } }; var data = collection.find({}, sorting).fetch(); // TODO: Clean this up, it's probably an inefficient way to get what we need var groupObject = _.groupBy(data, function (m) { return m.measurementNumber; }); // Reformat the data var rows = Object.keys(groupObject).map(function (key) { return { measurementTypeId: measurementTypeId, measurementNumber: key, entries: groupObject[key] }; }); var rowItem = rows[0]; var timepoints = [OHIF.viewer.timepointApi.current()]; if (rowItem) { OHIF.measurements.jumpToRowItem(rowItem, timepoints); } this.firstMeasurementActivated = true; } return jumpToFirstMeasurement; }(); return MeasurementTable; }(); MeasurementTable.measurementEvents = { 'cornerstonetoolsmeasurementadded .imageViewerViewport': function (event, instance) { var originalEvent = event.originalEvent; OHIF.measurements.MeasurementHandlers.onAdded(originalEvent, instance); }, 'cornerstonetoolsmeasurementmodified .imageViewerViewport': function (event, instance) { var originalEvent = event.originalEvent; instance.measurementModifiedHandler(originalEvent, instance); }, 'cornerstonemeasurementremoved .imageViewerViewport': function (event, instance) { var originalEvent = event.originalEvent; OHIF.measurements.MeasurementHandlers.onRemoved(originalEvent, instance); } }; ; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"configuration":{"configuration.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/configuration/configuration.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ configureApis: function () { return configureApis; } }); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var measurementTools; module.watch(require("./measurementTools"), { measurementTools: function (v) { measurementTools = v; } }, 1); var retrieveMeasurements, storeMeasurements, retrieveTimepoints, storeTimepoints, removeTimepoint, updateTimepoint, disassociateStudy; module.watch(require("./dataExchange"), { retrieveMeasurements: function (v) { retrieveMeasurements = v; }, storeMeasurements: function (v) { storeMeasurements = v; }, retrieveTimepoints: function (v) { retrieveTimepoints = v; }, storeTimepoints: function (v) { storeTimepoints = v; }, removeTimepoint: function (v) { removeTimepoint = v; }, updateTimepoint: function (v) { updateTimepoint = v; }, disassociateStudy: function (v) { disassociateStudy = v; } }, 2); var configureApis = function () { OHIF.measurements.MeasurementApi.setConfiguration({ measurementTools: measurementTools, dataExchange: { retrieve: retrieveMeasurements, store: storeMeasurements }, dataValidation: { validation: function () {} } }); OHIF.measurements.TimepointApi.setConfiguration({ dataExchange: { retrieve: retrieveTimepoints, store: storeTimepoints, remove: removeTimepoint, update: updateTimepoint, disassociate: disassociateStudy } }); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"dataExchange.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/configuration/dataExchange.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ retrieveMeasurements: function () { return retrieveMeasurements; }, storeMeasurements: function () { return storeMeasurements; }, retrieveTimepoints: function () { return retrieveTimepoints; }, storeTimepoints: function () { return storeTimepoints; }, updateTimepoint: function () { return updateTimepoint; }, removeTimepoint: function () { return removeTimepoint; }, disassociateStudy: function () { return disassociateStudy; } }); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var retrieveMeasurementFromSR, stowSRFromMeasurements; module.watch(require("../utils/handleSR"), { retrieveMeasurementFromSR: function (v) { retrieveMeasurementFromSR = v; }, stowSRFromMeasurements: function (v) { stowSRFromMeasurements = v; } }, 1); var getLatestSRSeries; module.watch(require("../utils/srUtils"), { getLatestSRSeries: function (v) { getLatestSRSeries = v; } }, 2); var retrieveMeasurements = function (patientId, timepointIds) { OHIF.log.info('retrieveMeasurements'); var latestSeries = getLatestSRSeries(); if (!latestSeries) return Promise.resolve({}); return retrieveMeasurementFromSR(latestSeries).then(function (value) { return { length: value }; }); }; var storeMeasurements = function (measurementData, timepointIds) { OHIF.log.info('storeMeasurements'); var server = OHIF.servers.getCurrentServer(); if (!server || server.type !== 'dicomWeb') { return Promise.resolve({}); } var studyInstanceUid = measurementData[Object.keys(measurementData)[0]][0].studyInstanceUid; return stowSRFromMeasurements(measurementData).then(function () { OHIF.studies.deleteStudyMetadataPromise(studyInstanceUid); }); }; var retrieveTimepoints = function (filter) { var studyInstanceUids = OHIF.viewer.StudyMetadataList.all().map(function (study) { return study.getStudyInstanceUID(); }); OHIF.log.info('retrieveTimepoints'); return Promise.resolve([{ timepointType: 'baseline', timepointId: 'TimepointId', studyInstanceUids: studyInstanceUids, patientId: filter.patientId, earliestDate: new Date(), latestDate: new Date(), isLocked: false }]); }; var storeTimepoints = function (timepointData) { OHIF.log.info('storeTimepoints'); return Promise.resolve(); }; var updateTimepoint = function (timepointData, query) { OHIF.log.info('updateTimepoint'); return Promise.resolve(); }; var removeTimepoint = function (timepointId) { OHIF.log.info('removeTimepoint'); return Promise.resolve(); }; var disassociateStudy = function (timepointIds, studyInstanceUid) { return Promise.resolve(); }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"measurementTools.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/configuration/measurementTools.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ measurementTools: function () { return measurementTools; } }); var ToolGroupBaseSchema; module.watch(require("../schema/toolGroupSchema"), { ToolGroupBaseSchema: function (v) { ToolGroupBaseSchema = v; } }, 0); var length; module.watch(require("../schema/length"), { "default": function (v) { length = v; } }, 1); var ellipticalRoi; module.watch(require("../schema/ellipticalRoi"), { "default": function (v) { ellipticalRoi = v; } }, 2); var rectangleRoi; module.watch(require("../schema/rectangleRoi"), { "default": function (v) { rectangleRoi = v; } }, 3); var simpleAngle; module.watch(require("../schema/simpleAngle"), { "default": function (v) { simpleAngle = v; } }, 4); var arrowAnnotate; module.watch(require("../schema/arrowAnnotate"), { "default": function (v) { arrowAnnotate = v; } }, 5); var trackedTools = [length, ellipticalRoi, rectangleRoi, simpleAngle, arrowAnnotate]; var measurementTools = [{ id: 'allTools', name: 'Measurements', childTools: trackedTools, schema: ToolGroupBaseSchema }]; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"schema":{"arrowAnnotate.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/schema/arrowAnnotate.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var MeasurementSchemaTypes; module.watch(require("meteor/ohif:measurements/both/schema/measurements"), { MeasurementSchemaTypes: function (v) { MeasurementSchemaTypes = v; } }, 1); var CornerstoneHandleSchema = MeasurementSchemaTypes.CornerstoneHandleSchema; var handlesSchema = new SimpleSchema({ start: { type: CornerstoneHandleSchema, label: 'Start' }, end: { type: CornerstoneHandleSchema, label: 'End' }, textBox: { type: CornerstoneHandleSchema, label: 'Text Box' } }); var toolSchema = new SimpleSchema([MeasurementSchemaTypes.CornerstoneToolMeasurement, { handles: { type: handlesSchema, label: 'Handles' }, measurementNumber: { type: Number, label: 'Measurement Number' }, location: { type: String, label: 'Location', optional: true }, description: { type: String, label: 'Description', optional: true }, toolType: { type: String, label: 'Measurement Tool Type', defaultValue: 'arrowAnnotate' }, text: { type: String, label: 'text', optional: true } }]); var displayFunction = function (data) { return data.text || ''; }; module.exportDefault({ id: 'arrowAnnotate', name: 'ArrowAnnotate', toolGroup: 'allTools', cornerstoneToolType: 'arrowAnnotate', schema: toolSchema, options: { measurementTable: { displayFunction: displayFunction } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"ellipticalRoi.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/schema/ellipticalRoi.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var MeasurementSchemaTypes; module.watch(require("meteor/ohif:measurements/both/schema/measurements"), { MeasurementSchemaTypes: function (v) { MeasurementSchemaTypes = v; } }, 1); var CornerstoneHandleSchema = MeasurementSchemaTypes.CornerstoneHandleSchema; var handlesSchema = new SimpleSchema({ start: { type: CornerstoneHandleSchema, label: 'Start' }, end: { type: CornerstoneHandleSchema, label: 'End' }, textBox: { type: CornerstoneHandleSchema, label: 'Text Box' } }); var MeanStdDevSchema = new SimpleSchema({ count: { type: Number, label: 'count', decimal: true }, mean: { type: Number, label: 'mean', decimal: true }, stdDev: { type: Number, label: 'stdDev', decimal: true }, variance: { type: Number, label: 'variance', decimal: true } }); var toolSchema = new SimpleSchema([MeasurementSchemaTypes.CornerstoneToolMeasurement, { handles: { type: handlesSchema, label: 'Handles' }, measurementNumber: { type: Number, label: 'Measurement Number' }, toolType: { type: String, label: 'Measurement Tool Type', defaultValue: 'ellipticalRoi' }, location: { type: String, label: 'Location', optional: true }, description: { type: String, label: 'Description', optional: true }, area: { type: Number, label: 'Ellipse Area value', decimal: true, optional: true }, meanStdDev: { type: MeanStdDevSchema, label: 'MeanStd Values', optional: true } }]); var displayFunction = function (data) { var meanValue = ''; if (data.meanStdDev && data.meanStdDev.mean) { meanValue = data.meanStdDev.mean.toFixed(2) + ' HU'; } return meanValue; // let meanValue = data.meanStdDev && data.meanStdDev.mean || 0; // return numberWithCommas(meanValue).toFixed(2) + ' HU'; //return data.meanStdDev.mean.toFixed(2); }; module.exportDefault({ id: 'ellipticalRoi', name: 'Ellipse', toolGroup: 'allTools', cornerstoneToolType: 'ellipticalRoi', schema: toolSchema, options: { measurementTable: { displayFunction: displayFunction } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"length.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/schema/length.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var MeasurementSchemaTypes; module.watch(require("meteor/ohif:measurements/both/schema/measurements"), { MeasurementSchemaTypes: function (v) { MeasurementSchemaTypes = v; } }, 1); var CornerstoneHandleSchema = MeasurementSchemaTypes.CornerstoneHandleSchema; var handlesSchema = new SimpleSchema({ start: { type: CornerstoneHandleSchema, label: 'Start' }, end: { type: CornerstoneHandleSchema, label: 'End' }, textBox: { type: CornerstoneHandleSchema, label: 'Text Box' } }); var toolSchema = new SimpleSchema([MeasurementSchemaTypes.CornerstoneToolMeasurement, { handles: { type: handlesSchema, label: 'Handles' }, measurementNumber: { type: Number, label: 'Measurement Number' }, location: { type: String, label: 'Location', optional: true }, description: { type: String, label: 'Description', optional: true }, toolType: { type: String, label: 'Measurement Tool Type', defaultValue: 'length' }, length: { type: Number, label: 'Length', optional: true, decimal: true } }]); var displayFunction = function (data) { var lengthValue = ''; if (data.length) { lengthValue = data.length.toFixed(2) + ' mm'; } return lengthValue; }; module.exportDefault({ id: 'length', name: 'Length', toolGroup: 'allTools', cornerstoneToolType: 'length', schema: toolSchema, options: { measurementTable: { displayFunction: displayFunction } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"rectangleRoi.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/schema/rectangleRoi.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var MeasurementSchemaTypes; module.watch(require("meteor/ohif:measurements/both/schema/measurements"), { MeasurementSchemaTypes: function (v) { MeasurementSchemaTypes = v; } }, 1); var CornerstoneHandleSchema = MeasurementSchemaTypes.CornerstoneHandleSchema; var handlesSchema = new SimpleSchema({ start: { type: CornerstoneHandleSchema, label: 'Start' }, end: { type: CornerstoneHandleSchema, label: 'End' }, textBox: { type: CornerstoneHandleSchema, label: 'Text Box' } }); var MeanStdDevSchema = new SimpleSchema({ count: { type: Number, label: 'count', decimal: true }, mean: { type: Number, label: 'mean', decimal: true }, stdDev: { type: Number, label: 'stdDev', decimal: true }, variance: { type: Number, label: 'variance', decimal: true } }); var toolSchema = new SimpleSchema([MeasurementSchemaTypes.CornerstoneToolMeasurement, { handles: { type: handlesSchema, label: 'Handles' }, measurementNumber: { type: Number, label: 'Measurement Number' }, toolType: { type: String, label: 'Measurement Tool Type', defaultValue: 'rectangleRoi' }, location: { type: String, label: 'Location', optional: true }, description: { type: String, label: 'Description', optional: true }, area: { type: Number, label: 'Rectangle Area value', decimal: true, optional: true }, meanStdDev: { type: MeanStdDevSchema, label: 'MeanStd Values', optional: true } }]); var displayFunction = function (data) { var meanValue = ''; if (data.meanStdDev && data.meanStdDev.mean) { meanValue = data.meanStdDev.mean.toFixed(2) + ' HU'; } return meanValue; }; module.exportDefault({ id: 'rectangleRoi', name: 'Rectangle', toolGroup: 'allTools', cornerstoneToolType: 'rectangleRoi', schema: toolSchema, options: { measurementTable: { displayFunction: displayFunction } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"simpleAngle.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/schema/simpleAngle.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var MeasurementSchemaTypes; module.watch(require("meteor/ohif:measurements/both/schema/measurements"), { MeasurementSchemaTypes: function (v) { MeasurementSchemaTypes = v; } }, 1); var CornerstoneHandleSchema = MeasurementSchemaTypes.CornerstoneHandleSchema; var handlesSchema = new SimpleSchema({ start: { type: CornerstoneHandleSchema, label: 'Start' }, middle: { type: CornerstoneHandleSchema, label: 'Middle' }, end: { type: CornerstoneHandleSchema, label: 'End' }, textBox: { type: CornerstoneHandleSchema, label: 'Text Box' } }); var toolSchema = new SimpleSchema([MeasurementSchemaTypes.CornerstoneToolMeasurement, { handles: { type: handlesSchema, label: 'Handles' }, measurementNumber: { type: Number, label: 'Measurement Number' }, location: { type: String, label: 'Location', optional: true }, description: { type: String, label: 'Description', optional: true }, toolType: { type: String, label: 'Measurement Tool Type', defaultValue: 'simpleAngle' }, rAngle: { type: Number, label: 'Angle', optional: true, decimal: true } }]); var displayFunction = function (data) { var text = ''; if (data.rAngle) { text = data.rAngle.toFixed(2) + String.fromCharCode(parseInt('00B0', 16)); } return text; }; module.exportDefault({ id: 'simpleAngle', name: 'SimpleAngle', toolGroup: 'allTools', cornerstoneToolType: 'simpleAngle', schema: toolSchema, options: { measurementTable: { displayFunction: displayFunction } } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"toolGroupSchema.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/schema/toolGroupSchema.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ ToolGroupBaseSchema: function () { return ToolGroupBaseSchema; } }); var SimpleSchema; module.watch(require("meteor/aldeed:simple-schema"), { SimpleSchema: function (v) { SimpleSchema = v; } }, 0); var ToolGroupBaseSchema = new SimpleSchema({ toolId: { type: String, label: 'Tool ID', optional: true }, toolItemId: { type: String, label: 'Tool Item ID', optional: true }, createdAt: { type: Date }, studyInstanceUid: { type: String, label: 'Study Instance UID' }, timepointId: { type: String, label: 'Timepoint ID' }, measurementNumber: { type: Number, label: 'Measurement Number' } }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// }},"utils":{"getLengthMeasurementData.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/utils/getLengthMeasurementData.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var OHIF; module.watch(require("meteor/ohif:core"), { OHIF: function (v) { OHIF = v; } }, 0); var cornerstone; module.watch(require("meteor/ohif:cornerstone"), { cornerstone: function (v) { cornerstone = v; } }, 1); var getInstanceMetadata; module.watch(require("./srUtils"), { getInstanceMetadata: function (v) { getInstanceMetadata = v; } }, 2); module.exportDefault(getLengthMeasurementData = function (lengthMeasurementContent, displaySets) { var lengthStates = []; lengthMeasurementContent.forEach(function (groupItemContent) { var lengthContent = groupItemContent.ContentSequence; var reference = lengthContent.ContentSequence.ReferencedSOPSequence; var lengthState = {}; lengthState.measuredValue = groupItemContent.MeasuredValueSequence.NumericValue; lengthState.handles = { start: {}, end: {} }; var _lengthContent$Graphi = (0, _slicedToArray2.default)(lengthContent.GraphicData, 4); lengthState.handles.start.x = _lengthContent$Graphi[0]; lengthState.handles.start.y = _lengthContent$Graphi[1]; lengthState.handles.end.x = _lengthContent$Graphi[2]; lengthState.handles.end.y = _lengthContent$Graphi[3]; // 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); }); var lengthMeasurementData = []; var measurementNumber = 0; lengthStates.forEach(function (lengthState) { var sopInstanceUid = lengthState.ReferencedInstanceUID; var instanceMetadata = getInstanceMetadata(displaySets, sopInstanceUid); var imageId = OHIF.viewerbase.getImageId(instanceMetadata); if (!imageId) { return; } var studyInstanceUid = cornerstone.metaData.get('study', imageId).studyInstanceUid; var seriesInstanceUid = cornerstone.metaData.get('series', imageId).seriesInstanceUid; var patientId = instanceMetadata._study.patientId; var frameIndex = lengthState.ReferencedFrameNumber; var imagePath = [studyInstanceUid, seriesInstanceUid, sopInstanceUid, frameIndex].join('_'); var measurement = { handles: lengthState.handles, length: lengthState.measuredValue, imageId: imageId, imagePath: imagePath, sopInstanceUid: sopInstanceUid, seriesInstanceUid: seriesInstanceUid, studyInstanceUid: studyInstanceUid, patientId: patientId, frameIndex: frameIndex, measurementNumber: ++measurementNumber, userId: 'UserID', timepointId: OHIF.viewer.data.currentTimepointId, toolType: 'length', _id: imageId + measurementNumber }; lengthMeasurementData.push(measurement); }); return lengthMeasurementData; }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"getLengthMeasurementGroupContentItem.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/utils/getLengthMeasurementGroupContentItem.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.exportDefault(measurementGroupContentItem = function (measurement, sopClassUid) { var handles = measurement.handles, length = measurement.length, frameIndex = measurement.frameIndex, sopInstanceUid = measurement.sopInstanceUid; var 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; }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"handleSR.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/utils/handleSR.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); module.export({ retrieveMeasurementFromSR: function () { return retrieveMeasurementFromSR; }, stowSRFromMeasurements: function () { return stowSRFromMeasurements; } }); var dcmjs; module.watch(require("meteor/ohif:cornerstone"), { dcmjs: function (v) { dcmjs = v; } }, 0); var retrieveDataFromSR; module.watch(require("./retrieveDataFromSR"), { "default": function (v) { retrieveDataFromSR = v; } }, 1); var retrieveDataFromMeasurements; module.watch(require("./retrieveDataFromMeasurements"), { "default": function (v) { retrieveDataFromMeasurements = v; } }, 2); var multipartEncode; module.watch(require("./srUtils"), { multipartEncode: function (v) { multipartEncode = v; } }, 3); var retrieveMeasurementFromSR = function () { function _callee(series) { var instance, options, url, result, data, measurementData; return _regenerator.default.async(function () { function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: instance = series.getFirstInstance(); options = { method: 'GET', responseType: 'arraybuffer' }; url = instance.getDataProperty('wadouri'); _context.prev = 3; _context.next = 6; return _regenerator.default.awrap(DICOMWeb.makeRequest(url, options)); case 6: result = _context.sent; _context.next = 9; return _regenerator.default.awrap(result.arrayBuffer()); case 9: data = _context.sent; measurementData = retrieveDataFromSR(data); return _context.abrupt("return", Promise.resolve(measurementData)); case 14: _context.prev = 14; _context.t0 = _context["catch"](3); return _context.abrupt("return", Promise.reject(_context.t0)); case 17: case "end": return _context.stop(); } } } return _callee$; }(), null, this, [[3, 14]]); } return _callee; }(); /** * Retrieve the DICOMWeb STOW-RS URL for the current server. * * See ftp://medical.nema.org/medical/dicom/current/output/html/part18.html#sect_6.6.1.1 * * @return {string|null} The URL, rerouted to the proxy if the WADOProxy is enabled. */ function getStowRsUrl() { var server = OHIF.servers.getCurrentServer(); var url = server.wadoRoot + "/studies"; return WADOProxy.convertURL(url, server); } var stowSRFromMeasurements = function () { function _callee2(measurements) { var serverUrl, reportDataset, boundary, options; return _regenerator.default.async(function () { function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: serverUrl = getStowRsUrl(); reportDataset = retrieveDataFromMeasurements(measurements); boundary = dcmjs.data.DicomMetaDictionary.uid(); options = { method: 'POST', body: multipartEncode(reportDataset, boundary), headers: { 'Content-Type': "multipart/related; type=application/dicom; boundary=" + boundary } }; _context2.prev = 4; _context2.next = 7; return _regenerator.default.awrap(DICOMWeb.makeRequest(serverUrl, options)); case 7: return _context2.abrupt("return", Promise.resolve()); case 10: _context2.prev = 10; _context2.t0 = _context2["catch"](4); return _context2.abrupt("return", Promise.reject(_context2.t0)); case 13: case "end": return _context2.stop(); } } } return _callee2$; }(), null, this, [[4, 10]]); } return _callee2; }(); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"retrieveDataFromMeasurements.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/utils/retrieveDataFromMeasurements.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var dcmjs; module.watch(require("meteor/ohif:cornerstone"), { dcmjs: function (v) { dcmjs = v; } }, 0); var getInstanceMetadata, getAllDisplaySets; module.watch(require("./srUtils"), { getInstanceMetadata: function (v) { getInstanceMetadata = v; }, getAllDisplaySets: function (v) { getAllDisplaySets = v; } }, 1); var getLengthMeasurementGroupContentItem; module.watch(require("./getLengthMeasurementGroupContentItem"), { "default": function (v) { getLengthMeasurementGroupContentItem = v; } }, 2); module.exportDefault(retrieveDataFromMeasurements = function (measurements) { var _measurements$allTool = measurements.allTools[0], studyInstanceUid = _measurements$allTool.studyInstanceUid, seriesInstanceUid = _measurements$allTool.seriesInstanceUid, sopInstanceUid = _measurements$allTool.sopInstanceUid; var displaySets = getAllDisplaySets(); var instanceMetadata = getInstanceMetadata(displaySets, sopInstanceUid); var 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. var 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 var 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 var measurementGroupContentSequence = []; for (var _iterator = measurements.allTools, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { if (_isArray) { if (_i >= _iterator.length) break; measurement = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; measurement = _i.value; } 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; }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"retrieveDataFromSR.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/utils/retrieveDataFromSR.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // var dcmjs; module.watch(require("meteor/ohif:cornerstone"), { dcmjs: function (v) { dcmjs = v; } }, 0); var getLengthMeasurementData; module.watch(require("./getLengthMeasurementData"), { "default": function (v) { getLengthMeasurementData = v; } }, 1); var toArray, codeMeaningEquals, getAllDisplaySets; module.watch(require("./srUtils"), { toArray: function (v) { toArray = v; }, codeMeaningEquals: function (v) { codeMeaningEquals = v; }, getAllDisplaySets: function (v) { getAllDisplaySets = v; } }, 2); var imagingMeasurementsToMeasurementData = function (dataset, displaySets) { // Identify the Imaging Measurements var imagingMeasurementContent = toArray(dataset.ContentSequence).find(codeMeaningEquals("Imaging Measurements")); // Retrieve the Measurements themselves var measurementGroupContent = toArray(imagingMeasurementContent.ContentSequence).find(codeMeaningEquals("Measurement Group")); // 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"); return {}; } // Filter to find Length measurements in the Structured Report var lengthMeasurementContent = toArray(measurementGroupContent.ContentSequence).filter(codeMeaningEquals("Length")); // Retrieve Length Measurement Data return getLengthMeasurementData(lengthMeasurementContent, displaySets); }; module.exportDefault(retrieveDataFromSR = function (Part10SRArrayBuffer) { var allDisplaySets = getAllDisplaySets(); // get the dicom data as an Object var dicomData = dcmjs.data.DicomMessage.readFile(Part10SRArrayBuffer); var dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(dicomData.dict); // Convert the SR into the kind of object the Measurements package is expecting return imagingMeasurementsToMeasurementData(dataset, allDisplaySets); }); ///////////////////////////////////////////////////////////////////////////////////////////////////////////// },"srUtils.js":function(require,exports,module){ ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // packages/ohif_measurement-table/client/utils/srUtils.js // // // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // module.export({ codeMeaningEquals: function () { return codeMeaningEquals; }, getAllDisplaySets: function () { return getAllDisplaySets; }, getInstanceMetadata: function () { return getInstanceMetadata; }, getLatestSRSeries: function () { return getLatestSRSeries; }, multipartEncode: function () { return multipartEncode; }, toArray: function () { return toArray; } }); var dcmjs; module.watch(require("meteor/ohif:cornerstone"), { dcmjs: function (v) { dcmjs = v; } }, 0); var supportedSopClassUIDs = ['1.2.840.10008.5.1.4.1.1.88.22']; var toArray = function (x) { return x.constructor.name === "Array" ? x : [x]; }; var codeMeaningEquals = function (codeMeaningName) { return function (contentItem) { return contentItem.ConceptNameCodeSequence.CodeMeaning === codeMeaningName; }; }; var getAllDisplaySets = function () { var allStudies = OHIF.viewer.Studies.all(); var allDisplaySets = []; allStudies.forEach(function (study) { allDisplaySets = allDisplaySets.concat(study.displaySets); }); return allDisplaySets; }; var getInstanceMetadata = function (displaySets, sopInstanceUid) { var instance; // Use Array.some so that this loop stops when the internal loop // has found the correct instance displaySets.some(function (displaySet) { // Search the display set to find the instance metadata for return displaySet.images.find(function (instanceMetadata) { if (instanceMetadata._sopInstanceUID === sopInstanceUid) { instance = instanceMetadata; return true; } }); }); return instance; }; var getLatestSRSeries = function () { var allStudies = OHIF.viewer.StudyMetadataList.all(); var latestSeries; allStudies.forEach(function (study) { study.getSeries().forEach(function (series) { var firstInstance = series.getFirstInstance(); var sopClassUid = firstInstance._instance.sopClassUid; if (supportedSopClassUIDs.includes(sopClassUid)) { if (!latestSeries) { latestSeries = series; } else if (series._data.seriesDate > latestSeries._data.seriesDate || series._data.seriesDate === latestSeries._data.seriesDate && series._data.seriesTime > latestSeries._data.seriesTime) { latestSeries = series; } } }); }); return latestSeries; }; var stringToArray = function (string) { return Uint8Array.from(Array.from(string).map(function (letter) { return letter.charCodeAt(0); })); }; var multipartEncode = function (dataset, boundary) { var denaturalizedMetaheader = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset._meta); var dicomDict = new dcmjs.data.DicomDict(denaturalizedMetaheader); dicomDict.dict = dcmjs.data.DicomMetaDictionary.denaturalizeDataset(dataset); var part10Buffer = dicomDict.write(); var header = "\r\n--" + boundary + "\r\nContent-Type: application/dicom\r\n\r\n"; var footer = "\r\n--" + boundary + "--"; headerArray = stringToArray(header); contentArray = new Uint8Array(part10Buffer); footerArray = stringToArray(footer); var multipartArray = new Uint8Array(headerArray.length + contentArray.length + footerArray.length); multipartArray.set(headerArray, 0); multipartArray.set(contentArray, headerArray.length); multipartArray.set(footerArray, headerArray.length + contentArray.length); return multipartArray.buffer; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////// }}}}}}},{ "extensions": [ ".js", ".json" ] }); var exports = require("/node_modules/meteor/ohif:measurement-table/client/index.js"); /* Exports */ Package._define("ohif:measurement-table", exports); })();