diff --git a/.jscsrc b/.jscsrc index b5c406d8e..6003e1d85 100644 --- a/.jscsrc +++ b/.jscsrc @@ -35,8 +35,10 @@ "disallowSpaceAfterObjectKeys": true, "disallowQuotedKeysInObjects": true, "disallowMultipleSpaces": true, + "disallowVar": true, "validateLineBreaks": "LF", "validateIndentation": 4, "validateQuoteMarks": { "mark": "'", "escape": true }, - "validateParameterSeparator": ", " -} \ No newline at end of file + "validateParameterSeparator": ", ", + "requireDollarBeforejQueryAssignment": true +} diff --git a/.jshintrc b/.jshintrc index de718b5a2..5365325f3 100644 --- a/.jshintrc +++ b/.jshintrc @@ -24,12 +24,12 @@ // true : ensure whatever is used is consistent // "single" : require single quotes // "double" : require double quotes - "undef" : false, // true: Require all non-global variables to be declared (prevents global leaks) - "unused" : true, // Unused variables: + "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) + "unused" : "vars", // Unused variables: // true : all variables, last function parameter // "vars" : all variables only // "strict" : all variables, all function parameters - "strict" : false, // true: Requires all functions run in ES5 Strict Mode + "strict" : false, // true: Requires all functions run in ES5 Strict Mode "maxparams" : false, // {int} Max number of formal params allowed per function "maxdepth" : false, // {int} Max depth of nested blocks (within functions) "maxstatements" : false, // {int} Max number statements per function @@ -43,7 +43,7 @@ "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. "eqnull" : false, // true: Tolerate use of `== null` "es5" : true, // true: Allow ES5 syntax (ex: getters and setters) - "esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`) + "esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`) "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) // (ex: `for each`, multiple try/catch, function expression…) "evil" : false, // true: Tolerate use of `eval` and `new Function()` @@ -69,11 +69,11 @@ "browser" : true, // Web Browser (window, document, etc) "browserify" : false, // Browserify (node.js code in the browser) "couch" : false, // CouchDB - "devel" : true, // Development/debugging (alert, confirm, etc) + "devel" : false, // Development/debugging (alert, confirm, etc) "dojo" : false, // Dojo Toolkit "jasmine" : false, // Jasmine "jquery" : true, // jQuery - "mocha" : true, // Mocha + "mocha" : false, // Mocha "mootools" : false, // MooTools "node" : false, // Node.js "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) @@ -85,5 +85,14 @@ "typed" : false, // Globals for typed array constructions "worker" : false, // Web Workers "wsh" : false, // Windows Scripting Host - "yui" : false // Yahoo User Interface -} \ No newline at end of file + "yui" : false, // Yahoo User Interface + "globals" : { + "Package" : true, // Meteor Package definition + + "cornerstone": true, // This group: cornerstone globals + "cornerstoneMath": true, + "cornerstoneTools": true, + "cornerstoneWADOImageLoader": true, + "dicomParser": true + } +} diff --git a/LesionTracker/client/components/viewer/viewer.js b/LesionTracker/client/components/viewer/viewer.js index eb1e5b246..f962a8cc5 100644 --- a/LesionTracker/client/components/viewer/viewer.js +++ b/LesionTracker/client/components/viewer/viewer.js @@ -1,5 +1,4 @@ import { OHIF } from 'meteor/ohif:core'; -import { MeasurementHandlers } from 'meteor/ohif:measurements/client/lib/MeasurementHandlers'; Session.set('TimepointsReady', false); Session.set('MeasurementsReady', false); @@ -96,12 +95,12 @@ Template.viewer.helpers({ Template.viewer.events({ 'CornerstoneToolsMeasurementAdded .imageViewerViewport'(event, instance, eventData) { - MeasurementHandlers.onAdded(event, instance, eventData); + OHIF.measurements.MeasurementHandlers.onAdded(event, instance, eventData); }, 'CornerstoneToolsMeasurementModified .imageViewerViewport'(event, instance, eventData) { - MeasurementHandlers.onModified(event, instance, eventData); + OHIF.measurements.MeasurementHandlers.onModified(event, instance, eventData); }, 'CornerstoneToolsMeasurementRemoved .imageViewerViewport'(event, instance, eventData) { - MeasurementHandlers.onRemoved(event, instance, eventData); + OHIF.measurements.MeasurementHandlers.onRemoved(event, instance, eventData); } }); diff --git a/PETSUVMeasurements/client/components/viewer/viewer.js b/PETSUVMeasurements/client/components/viewer/viewer.js index 242d96cb2..2e25e0634 100644 --- a/PETSUVMeasurements/client/components/viewer/viewer.js +++ b/PETSUVMeasurements/client/components/viewer/viewer.js @@ -1,6 +1,5 @@ import { OHIF } from 'meteor/ohif:core'; import { MeasurementsConfiguration } from 'meteor/ohif:measurements/both/configuration/measurements'; -import { MeasurementHandlers } from 'meteor/ohif:measurements/client/lib/MeasurementHandlers'; Session.set('MeasurementsReady', false); @@ -43,7 +42,7 @@ Template.viewer.onCreated(() => { Session.set('MeasurementsReady', true); instance.data.measurementApi.syncMeasurementsAndToolData(); - }) + }); }); Template.viewer.helpers({ @@ -51,16 +50,16 @@ Template.viewer.helpers({ // TODO: Find a better way to do this return Session.get('MeasurementsReady'); } -}) +}); Template.viewer.events({ 'CornerstoneToolsMeasurementAdded .imageViewerViewport'(event, instance, eventData) { - MeasurementHandlers.onAdded(event, instance, eventData); + OHIF.measurements.MeasurementHandlers.onAdded(event, instance, eventData); }, 'CornerstoneToolsMeasurementModified .imageViewerViewport'(event, instance, eventData) { - MeasurementHandlers.onModified(event, instance, eventData); + OHIF.measurements.MeasurementHandlers.onModified(event, instance, eventData); }, 'CornerstoneToolsMeasurementRemoved .imageViewerViewport'(event, instance, eventData) { - MeasurementHandlers.onRemoved(event, instance, eventData); + OHIF.measurements.MeasurementHandlers.onRemoved(event, instance, eventData); } }); diff --git a/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js b/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js index ad5b1a585..a98723ca9 100644 --- a/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js +++ b/Packages/ohif-lesiontracker/client/components/measurementLocationDialog/measurementLocationDialog.js @@ -1,4 +1,4 @@ -import { MeasurementManager } from 'meteor/ohif:measurements/client/lib/MeasurementManager'; +import { OHIF } from 'meteor/ohif:core'; function closeHandler(dialog) { // Hide the lesion dialog @@ -12,7 +12,6 @@ function closeHandler(dialog) { } // This event sets lesion number for new lesion - function getSetLesionNumberCallbackFunction(measurementTypeId, measurementApi, timepointApi) { return (measurementData, eventData, doneCallback) => { // Get the current element's timepointId from the study date metadata @@ -35,12 +34,12 @@ function getSetLesionNumberCallbackFunction(measurementTypeId, measurementApi, t // exists at a different timepoint const timepointId = timepoint.timepointId; const collection = measurementApi[measurementTypeId]; - const measurementNumber = MeasurementManager.getNewMeasurementNumber(timepointId, collection, timepointApi); + const measurementNumber = OHIF.measurements.MeasurementManager.getNewMeasurementNumber(timepointId, collection, timepointApi); measurementData.measurementNumber = measurementNumber; // Set lesion number doneCallback(measurementNumber); - } + }; } // This event determines whether or not to show the lesion dialog @@ -71,7 +70,7 @@ function getLesionLocationCallback(measurementData, eventData) { // Find out if this lesion number is already added in the lesion manager for another timepoint // If it is, stop here because we don't need the dialog. - var locationUID = MeasurementManager.getLocationIdIfMeasurementExists(measurementData); + var locationUID = OHIF.measurements.MeasurementManager.getLocationIdIfMeasurementExists(measurementData); if (locationUID) { // Add an ID value to the tool data to link it to the Measurements collection measurementData.id = 'notready'; @@ -123,9 +122,9 @@ changeLesionLocationCallback = function(measurementData, eventData, doneCallback // Show/Hide Convert To NonTarget option in measurementLocationRelabelDialog if (measurementData.toolType === 'bidirectional') { - dialog.find("#convertToNonTarget").css("visibility", "visible"); + dialog.find('#convertToNonTarget').css('visibility', 'visible'); } else { - dialog.find("#convertToNonTarget").css("visibility", "hidden"); + dialog.find('#convertToNonTarget').css('visibility', 'hidden'); } Template.measurementLocationDialog.dialog = dialog; @@ -189,7 +188,6 @@ changeLesionLocationCallback = function(measurementData, eventData, doneCallback }); }; - Template.measurementLocationDialog.onCreated(() => { const instance = Template.instance(); const measurementTypeId = 'targets'; @@ -268,7 +266,7 @@ Template.measurementLocationDialog.events({ var measurementData = Template.measurementLocationDialog.measurementData; var dialog = Template.measurementLocationDialog.dialog; - const instance = Template.instance() + const instance = Template.instance(); const measurementApi = instance.data.measurementApi; convertToNonTarget(measurementApi, measurementData); @@ -290,7 +288,7 @@ Template.measurementLocationDialog.events({ }); Template.measurementLocationDialog.helpers({ - measurementLocations: function() { + measurementLocations() { return LesionLocations.find(); } }); diff --git a/Packages/ohif-lesiontracker/client/components/nonTargetLesionDialog/nonTargetLesionDialog.js b/Packages/ohif-lesiontracker/client/components/nonTargetLesionDialog/nonTargetLesionDialog.js index 0a2b6b13f..834808ee2 100644 --- a/Packages/ohif-lesiontracker/client/components/nonTargetLesionDialog/nonTargetLesionDialog.js +++ b/Packages/ohif-lesiontracker/client/components/nonTargetLesionDialog/nonTargetLesionDialog.js @@ -1,4 +1,4 @@ -import { MeasurementManager } from 'meteor/ohif:measurements/client/lib/MeasurementManager'; +import { OHIF } from 'meteor/ohif:core'; function closeHandler(dialog) { // Hide the lesion dialog @@ -31,12 +31,12 @@ function getSetLesionNumberCallbackFunction(measurementTypeId, measurementApi, t // exists at a different timepoint const timepointId = timepoint.timepointId; const collection = measurementApi[measurementTypeId]; - const measurementNumber = MeasurementManager.getNewMeasurementNumber(timepointId, collection, timepointApi); + const measurementNumber = OHIF.measurements.MeasurementManager.getNewMeasurementNumber(timepointId, collection, timepointApi); measurementData.measurementNumber = measurementNumber; // Set lesion number doneCallback(measurementNumber); - } + }; } function selectNonTargetResponse(responseCode) { @@ -104,7 +104,7 @@ function getLesionLocationCallback(measurementData, eventData) { // Find out if this lesion number is already added in the lesion manager for another timepoint // If it is, disable selector location - var locationId = MeasurementManager.getLocationIdIfMeasurementExists(measurementData); + var locationId = OHIF.measurements.MeasurementManager.getLocationIdIfMeasurementExists(measurementData); if (locationId) { // Add an ID value to the tool data to link it to the Measurements collection measurementData.id = 'notready'; @@ -120,11 +120,11 @@ function getLesionLocationCallback(measurementData, eventData) { var locationObject = LesionLocations.findOne({ id: locationId }); - + if (!locationObject) { return; } - + selectorLocation.find('option[value="' + locationObject._id + '"]').prop('selected', true); selectorLocation.prop('disabled', true); } @@ -238,7 +238,6 @@ changeNonTargetLocationCallback = function(measurementData, eventData, doneCallb selectNonTargetResponse(response); }; - Template.nonTargetLesionDialog.onCreated(() => { const instance = Template.instance(); const measurementTypeId = 'nonTargets'; @@ -297,7 +296,9 @@ Template.nonTargetLesionDialog.events({ measurementData.isTarget = false; // Response is set from location response list - measurementData.response = LocationResponses.findOne({selected: true}).code; + measurementData.response = LocationResponses.findOne({ + selected: true + }).code; // Adds lesion data to timepoints array LesionManager.updateLesionData(measurementData); diff --git a/Packages/ohif-lesiontracker/lib/getTimepointObject.js b/Packages/ohif-lesiontracker/lib/getTimepointObject.js deleted file mode 100644 index 28cb663ed..000000000 --- a/Packages/ohif-lesiontracker/lib/getTimepointObject.js +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Returns timepoint object given a specified imageId - * - * @param imageId - * @returns {*|{}} Timepoint object - */ -getTimepointObject = function(imageId) { - var study = cornerstoneTools.metaData.get('study', imageId); - if (!study) { - return; - } - - return Timepoints.findOne({ - studyInstanceUids: { - $in: [study.studyInstanceUid] - } - }); -}; diff --git a/Packages/ohif-lesiontracker/lib/syncMeasurementAndToolData.js b/Packages/ohif-lesiontracker/lib/syncMeasurementAndToolData.js deleted file mode 100644 index 9c863c94c..000000000 --- a/Packages/ohif-lesiontracker/lib/syncMeasurementAndToolData.js +++ /dev/null @@ -1,62 +0,0 @@ -import { OHIF } from 'meteor/ohif:core'; - -function toolDataExists(toolState, imageId, toolType) { - const currentToolState = toolState[imageId][toolType]; - return (currentToolState && currentToolState.data && currentToolState.data.length); -} - -syncMeasurementAndToolData = function(measurement) { - OHIF.log.info('syncMeasurementAndToolData'); - - const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState; - const imageId = measurement.imageId; - const toolType = measurement.toolType; - - // If no tool state exists for this imageId, create an empty object to store it - if (!toolState[imageId]) { - toolState[imageId] = {}; - } - - // Check if we already have toolData for this imageId and toolType - if (toolDataExists(toolState, imageId, toolType)) { - // If we have toolData, we should search it for any toolData - // related to the current Measurement - const toolData = toolState[imageId][toolType].data; - - // Create a flag so we know if we have successfully updated - // this Measurement's in the toolData - let alreadyExists = false; - - // Loop through the toolData to search for this Measurement - toolData.forEach(function(tool) { - // Break the loop if this isn't the Measurement we are looking for - if (tool._id !== measurement._id) { - return; - } - - // If we have found the Measurement, set the flag to True - alreadyExists = true; - - // Update the toolData from the Measurement data - $.extend(tool, measurement); - return false; - }); - - // If we have found the Measurement we intended to update, we can stop - // this function here - if (alreadyExists === true) { - return; - } - } else { - // If no toolData exists for this toolType, create an empty array to hold some - toolState[imageId][toolType] = { - data: [] - }; - } - - // If we have reached this point, it means we haven't found the Measurement we are - // looking for in the current toolData. This means we need to add it. - - // Add the MeasurementData into the toolData for this imageId - toolState[imageId][toolType].data.push(measurement); -}; diff --git a/Packages/ohif-lesiontracker/package.js b/Packages/ohif-lesiontracker/package.js index cd4a464af..94c638b91 100644 --- a/Packages/ohif-lesiontracker/package.js +++ b/Packages/ohif-lesiontracker/package.js @@ -94,11 +94,8 @@ Package.onUse(function(api) { api.addFiles('lib/convertToNonTarget.js', 'client'); api.addFiles('lib/convertNonTarget.js', 'client'); - api.addFiles('lib/syncMeasurementAndToolData.js', 'client'); - // Export global functions api.export('pixelSpacingAutorunCheck', 'client'); - api.export('syncMeasurementAndToolData', 'client'); api.export('syncImageMeasurementAndToolData', 'client'); api.export('openNewTabWithTimepoint', 'client'); api.export('toggleLesionTrackerTools', 'client'); diff --git a/Packages/ohif-measurements/both/configuration/measurements.js b/Packages/ohif-measurements/both/configuration/measurements.js index cb87ec8d8..0c5e844cd 100644 --- a/Packages/ohif-measurements/both/configuration/measurements.js +++ b/Packages/ohif-measurements/both/configuration/measurements.js @@ -42,8 +42,8 @@ class MeasurementApi { return new Promise((resolve, reject) => { retrievalFn().then(measurementData => { - console.log('Measurement data retrieval'); - console.log(measurementData); + OHIF.log.info('Measurement data retrieval'); + OHIF.log.info(measurementData); Object.keys(measurementData).forEach(measurementTypeId => { const measurements = measurementData[measurementTypeId]; @@ -72,7 +72,7 @@ class MeasurementApi { }); storeFn(measurementData).then(() => { - console.log('Measurement storage completed'); + OHIF.log.info('Measurement storage completed'); }); } @@ -87,7 +87,7 @@ class MeasurementApi { this.config.measurementTools.forEach(tool => { const measurements = this[tool.id].find().fetch(); measurements.forEach(measurement => { - syncMeasurementAndToolData(measurement); + OHIF.measurements.syncMeasurementAndToolData(measurement); }); }); } diff --git a/Packages/ohif-measurements/both/configuration/timepoints.js b/Packages/ohif-measurements/both/configuration/timepoints.js index ba3d4b96c..210c9c3ae 100644 --- a/Packages/ohif-measurements/both/configuration/timepoints.js +++ b/Packages/ohif-measurements/both/configuration/timepoints.js @@ -36,8 +36,8 @@ class TimepointApi { return new Promise((resolve, reject) => { retrievalFn().then(timepointData => { - console.log('Timepoint data retrieval'); - console.log(timepointData); + OHIF.log.info('Timepoint data retrieval'); + OHIF.log.info(timepointData); _.each(timepointData, timepoint => { delete timepoint._id; this.timepoints.insert(timepoint); @@ -55,12 +55,10 @@ class TimepointApi { } const timepointData = this.timepoints.find().fetch(); - console.log('Preparing to store timepoints'); - console.log(JSON.stringify(timepointData, null, 2)); + OHIF.log.info('Preparing to store timepoints'); + OHIF.log.info(JSON.stringify(timepointData, null, 2)); - storeFn(timepointData).then(() => { - console.log('Timepoint storage completed'); - }); + storeFn(timepointData).then(() => OHIF.log.info('Timepoint storage completed')); } // Return all timepoints @@ -77,6 +75,11 @@ class TimepointApi { // Return the prior timepoint lock() { + const current = this.current(); + if (!current) { + return; + } + this.timepoints.update(current._id, { $set: { locked: true @@ -169,7 +172,7 @@ class TimepointApi { } // Retrieve all of the relevant follow-up timepoints for this patient - var followupTimepoints = this.timepoints.find({ + const followupTimepoints = this.timepoints.find({ patientId: timepoint.patientId, timepointType: timepoint.timepointType }, { @@ -180,13 +183,11 @@ class TimepointApi { // Create an array of just timepointIds, so we can use indexOf // on it to find the current timepoint's relative position - var followupTimepointIds = followupTimepoints.map(function(timepoint) { - return timepoint.timepointId; - }); + const followupTimepointIds = followupTimepoints.map(timepoint => timepoint.timepointId); // Calculate the index of the current timepoint in the array of all // relevant follow-up timepoints - var index = followupTimepointIds.indexOf(timepoint.timepointId) + 1; + const index = followupTimepointIds.indexOf(timepoint.timepointId) + 1; // If index is 0, it means that the current timepoint was not in the list // Log a warning and return here diff --git a/Packages/ohif-measurements/client/helpers/measurements.js b/Packages/ohif-measurements/client/helpers/measurements.js index cb20ef76b..c10714d95 100644 --- a/Packages/ohif-measurements/client/helpers/measurements.js +++ b/Packages/ohif-measurements/client/helpers/measurements.js @@ -1,3 +1,5 @@ +import { Template } from 'meteor/templating'; + import { OHIF } from 'meteor/ohif:core'; // Get the current measurement API configuration with information about tools, data exchange diff --git a/Packages/ohif-measurements/client/index.js b/Packages/ohif-measurements/client/index.js index c2767fd23..26e81ba9a 100644 --- a/Packages/ohif-measurements/client/index.js +++ b/Packages/ohif-measurements/client/index.js @@ -1,4 +1,2 @@ import './lib'; import './helpers'; -// import './components'; -// import './ui'; diff --git a/Packages/ohif-measurements/client/lib/MeasurementHandlers.js b/Packages/ohif-measurements/client/lib/MeasurementHandlers.js index 5e12a4b03..1afc76bf9 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementHandlers.js +++ b/Packages/ohif-measurements/client/lib/MeasurementHandlers.js @@ -1,153 +1,133 @@ +import { Meteor } from 'meteor/meteor'; +import { $ } from 'meteor/jquery'; + import { OHIF } from 'meteor/ohif:core'; -import { MeasurementManager } from 'meteor/ohif:measurements/client/lib/MeasurementManager'; -let MeasurementHandlers = {}; +class MeasurementHandlers { -MeasurementHandlers.onAdded = (e, instance, eventData) => { - const measurementData = eventData.measurementData; + static onAdded(e, instance, eventData) { + const measurementData = eventData.measurementData; - const config = OHIF.measurements.MeasurementApi.getConfiguration(); - const toolTypes = config.measurementTools.map(tool => { - return tool.cornerstoneToolType; - }); + const config = OHIF.measurements.MeasurementApi.getConfiguration(); + const toolTypes = config.measurementTools.map(tool => tool.cornerstoneToolType); - const index = toolTypes.indexOf(eventData.toolType); - if (index === -1) { - return; + const index = toolTypes.indexOf(eventData.toolType); + if (index === -1) { + return; + } + + const measurementToolConfiguration = config.measurementTools[index]; + const measurementApi = instance.data.measurementApi; + const Collection = measurementApi[measurementToolConfiguration.id]; + + // Get the Cornerstone imageId + const enabledElement = cornerstone.getEnabledElement(eventData.element); + const imageId = enabledElement.image.imageId; + + // Get studyInstanceUid & patientId + const study = cornerstoneTools.metaData.get('study', imageId); + const studyInstanceUid = study.studyInstanceUid; + const patientId = study.patientId; + + // Get seriesInstanceUid + const series = cornerstoneTools.metaData.get('series', imageId); + const seriesInstanceUid = series.seriesInstanceUid; + + // Get sopInstanceUid + const sopInstance = cornerstoneTools.metaData.get('instance', imageId); + const sopInstanceUid = sopInstance.sopInstanceUid; + const frameIndex = sopInstance.frame || 0; + + OHIF.log.info('CornerstoneToolsMeasurementAdded'); + + let measurement = $.extend({ + userId: Meteor.userId(), + patientId: patientId, + studyInstanceUid: studyInstanceUid, + seriesInstanceUid: seriesInstanceUid, + sopInstanceUid: sopInstanceUid, + frameIndex: frameIndex, + imageId: imageId // TODO: In the future we should consider removing this + }, measurementData); + + const timepointApi = instance.data.timepointApi; + if (timepointApi) { + const timepoint = timepointApi.study(studyInstanceUid)[0]; + const timepointId = timepoint.timepointId; + measurement.timepointId = timepointId; + measurement.measurementNumber = OHIF.measurements.MeasurementManager.getNewMeasurementNumber(timepointId, Collection, timepointApi); + + // TODO: Fix this + measurement.measurementNumberAbsolute = measurement.measurementNumber; + } else { + const numCurrentMeasurementsInStudy = Collection.find({ + studyInstanceUid: study.studyInstanceUid + }).count(); + measurement.measurementNumber = numCurrentMeasurementsInStudy + 1; + } + + // Clean the measurement according to the Schema + measurementToolConfiguration.schema.clean(measurement); + + // Insert the new measurement into the collection + measurementData.id = Collection.insert(measurement); } - const measurementToolConfiguration = config.measurementTools[index]; - const measurementApi = instance.data.measurementApi; - const Collection = measurementApi[measurementToolConfiguration.id]; + static onModified(e, instance, eventData) { + const measurementData = eventData.measurementData; - // Get the Cornerstone imageId - const enabledElement = cornerstone.getEnabledElement(eventData.element); - const imageId = enabledElement.image.imageId; + const config = OHIF.measurements.MeasurementApi.getConfiguration(); + const toolTypes = config.measurementTools.map(tool => tool.cornerstoneToolType); - // Get studyInstanceUid & patientId - const study = cornerstoneTools.metaData.get('study', imageId); - const studyInstanceUid = study.studyInstanceUid; - const patientId = study.patientId; + const index = toolTypes.indexOf(eventData.toolType); + if (index === -1) { + return; + } - // Get seriesInstanceUid - const series = cornerstoneTools.metaData.get('series', imageId); - const seriesInstanceUid = series.seriesInstanceUid; + const measurementToolConfiguration = config.measurementTools[index]; + const measurementApi = instance.data.measurementApi; + const Collection = measurementApi[measurementToolConfiguration.id]; - // Get sopInstanceUid - const sopInstance = cornerstoneTools.metaData.get('instance', imageId); - const sopInstanceUid = sopInstance.sopInstanceUid; - const frameIndex = sopInstance.frame || 0; + OHIF.log.info('CornerstoneToolsMeasurementModified'); - OHIF.log.info('CornerstoneToolsMeasurementAdded'); + let measurement = Collection.findOne(measurementData.id); - let measurement = $.extend({ - userId: Meteor.userId(), - patientId: patientId, - studyInstanceUid: studyInstanceUid, - seriesInstanceUid: seriesInstanceUid, - sopInstanceUid: sopInstanceUid, - frameIndex: frameIndex, - imageId: imageId // TODO: In the future we should consider removing this - }, measurementData); + Object.keys(measurementData).forEach(key => { + measurement[key] = measurementData[key]; + }); - const timepointApi = instance.data.timepointApi; - if (timepointApi) { - const timepoint = timepointApi.study(studyInstanceUid)[0]; - const timepointId = timepoint.timepointId; - measurement.timepointId = timepointId; - measurement.measurementNumber = MeasurementManager.getNewMeasurementNumber(timepointId, Collection, timepointApi); + const measurementId = measurement._id; + delete measurement._id; - // TODO: Fix this - measurement.measurementNumberAbsolute = measurement.measurementNumber; - } else { - const numCurrentMeasurementsInStudy = Collection.find({ - studyInstanceUid: study.studyInstanceUid - }).count(); - measurement.measurementNumber = numCurrentMeasurementsInStudy + 1; + // Clean the measurement according to the Schema + measurementToolConfiguration.schema.clean(measurement); + + // Insert the new measurement into the collection + Collection.update(measurementId, { + $set: measurement + }); } - // Clean the measurement according to the Schema - measurementToolConfiguration.schema.clean(measurement); + static onRemoved(e, instance, eventData) { + const measurementData = eventData.measurementData; - // Insert the new measurement into the collection - measurementData.id = Collection.insert(measurement); -}; + const config = OHIF.measurements.MeasurementApi.getConfiguration(); + const toolTypes = config.measurementTools.map(tool => tool.cornerstoneToolType); -MeasurementHandlers.onModified = (e, instance, eventData) => { - const measurementData = eventData.measurementData; + const index = toolTypes.indexOf(measurementData.toolType); + if (index === -1) { + return; + } - const config = MeasurementApi.getConfiguration(); - const toolTypes = config.measurementTools.map(tool => { - return tool.cornerstoneToolType; - }); + OHIF.log.info('CornerstoneToolsMeasurementRemoved'); - const index = toolTypes.indexOf(eventData.toolType); - if (index === -1) { - return; + const measurementToolConfiguration = config.measurementTools[index]; + const measurementApi = instance.data.measurementApi; + const Collection = measurementApi[measurementToolConfiguration.id]; + + Collection.remove(measurementData.id); } - const measurementToolConfiguration = config.measurementTools[index]; - const measurementApi = instance.data.measurementApi; - const Collection = measurementApi[measurementToolConfiguration.id]; +} - // Get the Cornerstone imageId - const enabledElement = cornerstone.getEnabledElement(eventData.element); - const imageId = enabledElement.image.imageId; - - // Get studyInstanceUid & patientId - const study = cornerstoneTools.metaData.get('study', imageId); - const studyInstanceUid = study.studyInstanceUid; - const patientId = study.patientId; - - // Get seriesInstanceUid - const series = cornerstoneTools.metaData.get('series', imageId); - const seriesInstanceUid = series.seriesInstanceUid; - - // Get sopInstanceUid - const sopInstance = cornerstoneTools.metaData.get('instance', imageId); - const sopInstanceUid = sopInstance.sopInstanceUid; - const frameIndex = sopInstance.frame || 0; - - OHIF.log.info('CornerstoneToolsMeasurementModified'); - - let measurement = Collection.findOne(measurementData.id); - - Object.keys(measurementData).forEach(key => { - measurement[key] = measurementData[key]; - }) - - const measurementId = measurement._id; - delete measurement._id; - - // Clean the measurement according to the Schema - measurementToolConfiguration.schema.clean(measurement); - - // Insert the new measurement into the collection - Collection.update(measurementId, { - $set: measurement - }); -}; - -MeasurementHandlers.onRemoved = (e, instance, eventData) => { - const measurementData = eventData.measurementData; - - const config = OHIF.measurements.MeasurementApi.getConfiguration(); - const toolTypes = config.measurementTools.map(tool => { - return tool.cornerstoneToolType; - }); - - const index = toolTypes.indexOf(measurementData.toolType); - if (index === -1) { - return; - } - - OHIF.log.info('CornerstoneToolsMeasurementRemoved'); - - const measurementToolConfiguration = config.measurementTools[index]; - const measurementApi = instance.data.measurementApi; - const Collection = measurementApi[measurementToolConfiguration.id]; - - Collection.remove(measurementData.id); -}; - -export { MeasurementHandlers }; +OHIF.measurements.MeasurementHandlers = MeasurementHandlers; diff --git a/Packages/ohif-measurements/client/lib/MeasurementManager.js b/Packages/ohif-measurements/client/lib/MeasurementManager.js index f5e84a5b2..a43718b31 100644 --- a/Packages/ohif-measurements/client/lib/MeasurementManager.js +++ b/Packages/ohif-measurements/client/lib/MeasurementManager.js @@ -1,47 +1,53 @@ -/** - * Returns new measurement number given a timepointId - * @param timepointId - * @param isTarget - * @returns {*} - */ -function getNewMeasurementNumber(timepointId, Collection, timepointApi) { - // Get all current lesion measurements - const numMeasurements = Collection.find().count(); +import { OHIF } from 'meteor/ohif:core'; - // If no measurements exist yet, start at 1 - if (!numMeasurements) { - return 1; - } +class MeasurementManager { - const timepoint = timepointApi.timepoints.findOne({timepointId: timepointId}); - const numMeasurementsAtTimepoint = Collection.find({ - studyInstanceUid: { - $in: timepoint.studyInstanceUids + /** + * Returns new measurement number given a timepointId + * @param timepointId + * @param isTarget + * @returns {number} - Number of measurements in timepoint + */ + static getNewMeasurementNumber(timepointId, Collection, timepointApi) { + // Get all current lesion measurements + const numMeasurements = Collection.find().count(); + + // If no measurements exist yet, start at 1 + if (!numMeasurements) { + return 1; } - }).count(); - return numMeasurementsAtTimepoint + 1; -} + const timepoint = timepointApi.timepoints.findOne({ + timepointId: timepointId + }); -/** - * If the current Measurements Number already exists - * for any other timepoint, returns lesion locationUID - * @param measurementData - * @returns {*} - */ -function getLocationIdIfMeasurementExists(measurementData, Collection) { - const measurement = Collection.findOne({ - measurementNumber: measurementData.measurementNumber - }); + const numMeasurementsAtTimepoint = Collection.find({ + studyInstanceUid: { + $in: timepoint.studyInstanceUids + } + }).count(); - if (!measurement) { - return; + return numMeasurementsAtTimepoint + 1; + } + + /** + * If the current Measurements Number already exists + * for any other timepoint, returns lesion locationUID + * @param measurementData + * @returns {number} - Measurement location ID + */ + static getLocationIdIfMeasurementExists(measurementData, Collection) { + const measurement = Collection.findOne({ + measurementNumber: measurementData.measurementNumber + }); + + if (!measurement) { + return; + } + + return measurement.locationId; } - return measurement.locationId; } -export const MeasurementManager = { - getNewMeasurementNumber: getNewMeasurementNumber, - getLocationIdIfMeasurementExists: getLocationIdIfMeasurementExists -}; +OHIF.measurements.MeasurementManager = MeasurementManager; diff --git a/Packages/ohif-measurements/client/lib/activateLesion.js b/Packages/ohif-measurements/client/lib/activateLesion.js index b1e218bb6..1caa47966 100644 --- a/Packages/ohif-measurements/client/lib/activateLesion.js +++ b/Packages/ohif-measurements/client/lib/activateLesion.js @@ -76,7 +76,7 @@ OHIF.measurements.activateLesion = (measurementId, templateData) => { const measurementAtTimepoint = orderedTimepointEntries[viewportIndex]; // Find the image that is currently in this viewport - var enabledElement = cornerstone.getEnabledElement(element); + const enabledElement = cornerstone.getEnabledElement(element); if (!enabledElement || !enabledElement.image) { return; } @@ -111,7 +111,7 @@ OHIF.measurements.activateLesion = (measurementId, templateData) => { // Otherwise, re-render the viewport with the required study/series, then // add an onRendered callback to activate the measurements - layoutManager.rerenderViewportWithNewDisplaySet(element, requiredSeriesData, element => { + window.layoutManager.rerenderViewportWithNewDisplaySet(element, requiredSeriesData, element => { activateMeasurements(element, measurementId, templateData, viewportIndex); }); }); diff --git a/Packages/ohif-measurements/client/lib/activateMeasurements.js b/Packages/ohif-measurements/client/lib/activateMeasurements.js index 93f25b027..8977f9252 100644 --- a/Packages/ohif-measurements/client/lib/activateMeasurements.js +++ b/Packages/ohif-measurements/client/lib/activateMeasurements.js @@ -11,7 +11,7 @@ OHIF.measurements.activateMeasurements = (element, measurementId, templateData, const enabledElement = cornerstone.getEnabledElement(element); const imageId = enabledElement.image.imageId; - const timepointData = getTimepointObject(imageId); + const timepointData = OHIF.measurements.getTimepointObject(imageId); const measurementData = Measurements.findOne(measurementId); if (!timepointData) { @@ -27,7 +27,7 @@ OHIF.measurements.activateMeasurements = (element, measurementId, templateData, // If type is inactive, update lesions of enabledElement as inactive //TODO: !stackData.currentImageIdIndex returns incorrect value // Get loadedSeriesData currentImageIdIndex from ViewerData - const viewerData = ViewerData[templateData.contentId]; + const viewerData = window.ViewerData[templateData.contentId]; const loadedSeriesData = viewerData.loadedSeriesData[viewportIndex]; const elementCurrentImageIdIndex = loadedSeriesData.currentImageIdIndex; diff --git a/Packages/ohif-measurements/client/lib/activateTool.js b/Packages/ohif-measurements/client/lib/activateTool.js index 33e415a6c..99336711f 100644 --- a/Packages/ohif-measurements/client/lib/activateTool.js +++ b/Packages/ohif-measurements/client/lib/activateTool.js @@ -17,23 +17,23 @@ OHIF.measurements.activateTool = (element, measurementData, timepointId) => { OHIF.measurements.deactivateAllToolData(element, 'unTool'); OHIF.measurements.deactivateAllToolData(element, 'exTool'); - var toolType = measurementData.toolType; - var toolData = cornerstoneTools.getToolState(element, toolType); + const toolType = measurementData.toolType; + const toolData = cornerstoneTools.getToolState(element, toolType); if (!toolData) { return; } - var measurementAtTimepoint = measurementData.timepoints[timepointId]; + const measurementAtTimepoint = measurementData.timepoints[timepointId]; - for (var i = 0; i < toolData.data.length; i++) { - data = toolData.data[i]; + for (let i = 0; i < toolData.data.length; i++) { + const data = toolData.data[i]; // When click a row of table measurements, measurement will be active and color will be green // TODO= Remove this with the measurementId once it is in the tool data if (data.seriesInstanceUid === measurementAtTimepoint.seriesInstanceUid && data.studyInstanceUid === measurementAtTimepoint.studyInstanceUid && data.lesionNumber === measurementData.lesionNumber && - data.isTarget == measurementData.isTarget) { + data.isTarget === measurementData.isTarget) { data.active = true; break; diff --git a/Packages/ohif-measurements/client/lib/deactivateAllToolData.js b/Packages/ohif-measurements/client/lib/deactivateAllToolData.js index 286844f63..b20824ac3 100644 --- a/Packages/ohif-measurements/client/lib/deactivateAllToolData.js +++ b/Packages/ohif-measurements/client/lib/deactivateAllToolData.js @@ -8,13 +8,12 @@ import { OHIF } from 'meteor/ohif:core'; * @param toolType The tooltype of the tools that will be deactivated */ OHIF.measurements.deactivateAllToolData = (element, toolType) => { - var toolData = cornerstoneTools.getToolState(element, toolType); + const toolData = cornerstoneTools.getToolState(element, toolType); if (!toolData) { return; } - for (var i = 0; i < toolData.data.length; i++) { - var data = toolData.data[i]; - data.active = false; + for (let i = 0; i < toolData.data.length; i++) { + toolData.data[i].active = false; } }; diff --git a/Packages/ohif-measurements/client/lib/getTimepointName.js b/Packages/ohif-measurements/client/lib/getTimepointName.js index 06e0a58b5..9911a0d4e 100644 --- a/Packages/ohif-measurements/client/lib/getTimepointName.js +++ b/Packages/ohif-measurements/client/lib/getTimepointName.js @@ -8,14 +8,14 @@ import { OHIF } from 'meteor/ohif:core'; * @param timepoint * @returns {*} The timepoint name */ -OHIF.measurements.getTimepointName = (timepoint) => { +OHIF.measurements.getTimepointName = timepoint => { // Check if this is a Baseline timepoint, if it is, return 'Baseline' if (timepoint.timepointType === 'baseline') { return 'Baseline'; } // Retrieve all of the relevant follow-up timepoints for this patient - var followupTimepoints = Timepoints.find({ + const followupTimepoints = Timepoints.find({ patientId: timepoint.patientId, timepointType: timepoint.timepointType }, { @@ -26,13 +26,11 @@ OHIF.measurements.getTimepointName = (timepoint) => { // Create an array of just timepointIds, so we can use indexOf // on it to find the current timepoint's relative position - var followupTimepointIds = followupTimepoints.map(function(timepoint) { - return timepoint.timepointId; - }); + const followupTimepointIds = followupTimepoints.map(timepoint => timepoint.timepointId); // Calculate the index of the current timepoint in the array of all // relevant follow-up timepoints - var index = followupTimepointIds.indexOf(timepoint.timepointId) + 1; + const index = followupTimepointIds.indexOf(timepoint.timepointId) + 1; // If index is 0, it means that the current timepoint was not in the list // Log a warning and return here diff --git a/Packages/ohif-measurements/client/lib/getTimepointObject.js b/Packages/ohif-measurements/client/lib/getTimepointObject.js index 28cb663ed..47b25187f 100644 --- a/Packages/ohif-measurements/client/lib/getTimepointObject.js +++ b/Packages/ohif-measurements/client/lib/getTimepointObject.js @@ -1,11 +1,13 @@ +import { OHIF } from 'meteor/ohif:core'; + /** * Returns timepoint object given a specified imageId * * @param imageId * @returns {*|{}} Timepoint object */ -getTimepointObject = function(imageId) { - var study = cornerstoneTools.metaData.get('study', imageId); +OHIF.measurements.getTimepointObject = imageId => { + const study = cornerstoneTools.metaData.get('study', imageId); if (!study) { return; } diff --git a/Packages/ohif-measurements/client/lib/hangingProtocolCustomizations.js b/Packages/ohif-measurements/client/lib/hangingProtocolCustomizations.js index 16401025d..2a2afcfee 100644 --- a/Packages/ohif-measurements/client/lib/hangingProtocolCustomizations.js +++ b/Packages/ohif-measurements/client/lib/hangingProtocolCustomizations.js @@ -1,6 +1,8 @@ +import { Template } from 'meteor/templating'; + // TODO: [LT-refactor] move this to ohif:hanging-protocols package -getTimepointType = function(study) { +const getTimepointType = study => { const timepointApi = Template.instance().timepointApi; if (!timepointApi) { return; diff --git a/Packages/ohif-measurements/client/lib/syncMeasurementAndToolData.js b/Packages/ohif-measurements/client/lib/syncMeasurementAndToolData.js index 9c863c94c..dbcec0384 100644 --- a/Packages/ohif-measurements/client/lib/syncMeasurementAndToolData.js +++ b/Packages/ohif-measurements/client/lib/syncMeasurementAndToolData.js @@ -1,11 +1,8 @@ +import { $ } from 'meteor/jquery'; + import { OHIF } from 'meteor/ohif:core'; -function toolDataExists(toolState, imageId, toolType) { - const currentToolState = toolState[imageId][toolType]; - return (currentToolState && currentToolState.data && currentToolState.data.length); -} - -syncMeasurementAndToolData = function(measurement) { +OHIF.measurements.syncMeasurementAndToolData = measurement => { OHIF.log.info('syncMeasurementAndToolData'); const toolState = cornerstoneTools.globalImageIdSpecificToolStateManager.toolState; @@ -17,18 +14,19 @@ syncMeasurementAndToolData = function(measurement) { toolState[imageId] = {}; } + const currentToolState = toolState[imageId][toolType]; + const toolData = currentToolState && currentToolState.data; + // Check if we already have toolData for this imageId and toolType - if (toolDataExists(toolState, imageId, toolType)) { - // If we have toolData, we should search it for any toolData - // related to the current Measurement + if (toolData && toolData.length) { + // If we have toolData, we should search it for any data related to the current Measurement const toolData = toolState[imageId][toolType].data; - // Create a flag so we know if we have successfully updated - // this Measurement's in the toolData + // Create a flag so we know if we've successfully updated the Measurement in the toolData let alreadyExists = false; // Loop through the toolData to search for this Measurement - toolData.forEach(function(tool) { + toolData.forEach(tool => { // Break the loop if this isn't the Measurement we are looking for if (tool._id !== measurement._id) { return; @@ -42,8 +40,7 @@ syncMeasurementAndToolData = function(measurement) { return false; }); - // If we have found the Measurement we intended to update, we can stop - // this function here + // If we have found the Measurement we intended to update, we can stop this function here if (alreadyExists === true) { return; } @@ -54,8 +51,8 @@ syncMeasurementAndToolData = function(measurement) { }; } - // If we have reached this point, it means we haven't found the Measurement we are - // looking for in the current toolData. This means we need to add it. + // If we have reached this point, it means we haven't found the Measurement we are looking for + // in the current toolData. This means we need to add it. // Add the MeasurementData into the toolData for this imageId toolState[imageId][toolType].data.push(measurement);