Fixed bug LT-85 (Location Response Selections). Work on LT-9 and LT-12

This commit is contained in:
Erik Ziegler committed 2015-12-20 18:24:51 -05:00
1 parent 28cee350ff
commit 220ff065dc
44 files changed
+1515 -824

No files matched your search

@@ -0,0 +1,174 @@
var LesionManager = (function() {
PatientLocations = new Meteor.Collection(null);
/**
* Retrieve a location name (e.g. Liver Right) from the
* PatientLocations Collection by id, if it exists. Otherwise,
* return an empty string.
*
* @param id
* @returns {*|string}
*/
function getLocationName(id) {
var locationObject = PatientLocations.findOne(id);
if (!locationObject || !locationObject.location) {
return '';
}
return locationObject.location;
}
/**
* Update the Timepoint object for a specific Measurement.
* If no measurement exists yet, one will be created.
*
* Input is toolData from the lesion or nonTarget tool
*
* @param lesionData
*/
function updateLesionData(lesionData) {
// Find the related Timepoint from the Timepoints Collection
var timepointID = lesionData.timepointID;
var timepoint = Timepoints.findOne({timepointID: timepointID});
if (!timepoint) {
log.warn('Timepoint in an image is not present in the Timepoints Collection?');
return;
}
// Find the specific lesion to be updated
var existingMeasurement;
if (lesionData.id) {
existingMeasurement = Measurements.findOne(lesionData.id);
} else {
existingMeasurement = Measurements.findOne({
lesionNumber: lesionData.lesionNumber,
isTarget: lesionData.isTarget
});
}
// Create a structure for the timepointData based
// on this Lesion's toolData
var timepointData = {
seriesInstanceUid: lesionData.seriesInstanceUid,
studyInstanceUid: lesionData.studyInstanceUid,
handles: lesionData.handles,
imageId: lesionData.imageId
};
if (lesionData.isTarget === true) {
// TODO = Add short axis
timepointData.longestDiameter = lesionData.measurementText;
} else {
timepointData.response = lesionData.response;
}
// If no such lesion exists, we need to add one
if (!existingMeasurement) {
// Create a data structure for the Measurement
// based on the current tool data
var measurement = {
lesionNumber: lesionData.lesionNumber,
isTarget: lesionData.isTarget,
patientId: lesionData.patientId,
id: lesionData.id
};
// Retrieve the location name given the locationUID
if (lesionData.locationUID !== undefined) {
measurement.location = getLocationName(lesionData.locationUID);
}
// Add toolData parameters to the Measurement at this Timepoint
measurement.timepoints = {};
measurement.timepoints[timepointID] = timepointData;
// Set a flag to prevent duplication of toolData
measurement.toolDataInsertedManually = true;
// Increment and store the Lesion Number for this Measurement
measurement.lesionNumber = Measurements.find().count() + 1;
// Insert this into the Measurements Collection
// Save the ID into the toolData (not sure if this works?)
measurement.id = Measurements.insert(measurement);
} else {
lesionData.id = existingMeasurement._id;
// Update timepoints from lesion data
existingMeasurement.timepoints[timepointID] = timepointData;
Measurements.update(existingMeasurement._id, {
$set: {
timepoints: existingMeasurement.timepoints
}
});
}
}
/**
* Returns new lesion number according to timepointID
* @param timepointID
* @param isTarget
* @returns {*}
*/
function getNewLesionNumber(timepointID, isTarget) {
// Get all current lesion measurements
var measurements = Measurements.find({
isTarget: isTarget
}, {
sort: {lesionNumber: 1}
}).fetch();
// If no measurements exist yet, start at 1
if (!measurements.length) {
return 1;
}
// If measurements exist, find the last lesion number
// from the given timepoint
var lesionNumberCounter = 1;
var numMeasurements = measurements.length;
// Search through Measurements to see which ones
// already have data for this Timepoint
for (var i = 0; i < numMeasurements; i++) {
var measurement = measurements[i];
// If this measurement has no data for this Timepoint,
// use this as the current Measurement
if (!measurement.timepoints[timepointID]) {
return measurement.lesionNumber;
}
lesionNumberCounter++;
}
return lesionNumberCounter;
}
/**
* If the current Lesion Number already exists
* for any other timepoint, returns lesion locationUID
* @param lesionData
* @returns {*}
*/
function lesionNumberExists(lesionData) {
var measurement = Measurements.findOne({
lesionNumber: lesionData.lesionNumber,
isTarget: lesionData.isTarget
});
if (!measurement) {
return;
}
return measurement.locationUID;
}
return {
updateLesionData: updateLesionData,
getNewLesionNumber: getNewLesionNumber,
lesionNumberExists: lesionNumberExists,
getLocationName: getLocationName
};
})();
@@ -856,7 +856,7 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
if (lesionData.timepointID && lesionData.timepointID !== "") {
// Update Measurements Collection
measurementManagerDAL.updateTimepointData(lesionData);
LesionManager.updateLesionData(lesionData);
}
}
@@ -0,0 +1,91 @@
(function(cornerstoneTools) {
'use strict';
// Delete a lesion if Ctrl+D or DELETE is pressed while a lesion is selected
var keys = {
D: 68,
DELETE: 46
};
function removeMeasurementTimepoint(data, index, toolType) {
var imageId = data.imageId;
var enabledElements = cornerstone.getEnabledElementsByImageId(imageId);
enabledElements.forEach(function(enabledElement) {
var element = enabledElement.element;
// The HandleMeasurementRemoved handler should do the rest
cornerstoneTools.removeToolState(element, toolType, data);
//Update element
cornerstone.updateImage(element);
});
}
function getNearbyToolData(element, coords, toolTypes) {
var allTools = toolManager.getTools();
var pointNearTool = false;
var touchDevice = isTouchDevice();
var nearbyTool,
nearbyToolIndex,
nearbyToolType;
toolTypes.forEach(function(toolType){
var toolData = cornerstoneTools.getToolState(element, toolType);
if (!toolData) {
return;
}
for (var i = 0; i < toolData.data.length; i++) {
var data = toolData.data[i];
var toolInterface;
if (touchDevice) {
toolInterface = allTools[toolType].touch;
} else {
toolInterface = allTools[toolType].mouse;
}
if (toolInterface.pointNearTool(element, data, coords)) {
pointNearTool = true;
nearbyTool = data;
nearbyToolIndex = i;
nearbyToolType = toolType;
break;
}
}
if (pointNearTool === true) {
return false;
}
});
if (pointNearTool === true) {
return {
nearbyTool: nearbyTool,
nearbyToolIndex: nearbyToolIndex,
nearbyToolType: nearbyToolType
};
}
}
function keyDownCallback(e, eventData) {
var keyCode = eventData.keyCode;
if (keyCode === keys.DELETE ||
(keyCode === keys.D && eventData.event.ctrlKey === true)) {
var toolTypes = ["lesion", "nonTarget"];
var nearbyToolData = getNearbyToolData(eventData.element, eventData.currentPoints.canvas, toolTypes);
if (nearbyToolData) {
removeMeasurementTimepoint(nearbyToolData.nearbyTool,
nearbyToolData.nearbyToolIndex,
nearbyToolData.nearbyToolType);
}
}
}
// module/private exports
cornerstoneTools.deleteLesionKeyboardTool = cornerstoneTools.keyboardTool(keyDownCallback);
})(cornerstoneTools);
@@ -78,8 +78,6 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
$(element).on('CornerstoneToolsMouseDown', eventData, cornerstoneTools.lesion.mouseDownCallback);
$(element).on('CornerstoneToolsMouseDownActivate', eventData, cornerstoneTools.lesion.mouseDownActivateCallback);
cornerstone.updateImage(element);
updateLesionCollection(measurementData);
});
}
@@ -287,18 +285,6 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
}
}
function updateLesionCollection(lesionData) {
// TODO = Remove this in favour of measurement events
if (!lesionData.active) {
return;
}
if (lesionData.timepointID && lesionData.timepointID !== "") {
// Update Measurements Collection
measurementManagerDAL.updateTimepointData(lesionData);
}
}
function doubleClickCallback(e, eventData) {
// Prevent other double click handlers from firing after this one
//e.stopImmediatePropagation();
@@ -310,16 +296,7 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
if (deleteTool === true) {
cornerstoneTools.removeToolState(element, toolType, data);
cornerstone.updateImage(element);
//return;
}
/*// TODO= Find a better way to do this! This is very messy
config.setLesionNumberCallback(data, eventData, function(lesionNumber) {
data.lesionName = "Target " + lesionNumber;
data.lesionNumber = lesionNumber;
data.active = false;
cornerstone.updateImage(element);
});*/
}
if (e.data && e.data.mouseButtonMask && !cornerstoneTools.isMouseButtonEnabled(eventData.which, e.data.mouseButtonMask)) {
@@ -1,167 +0,0 @@
var measurementManagerDAL = (function() {
PatientLocations = new Meteor.Collection(null);
function getLocationName(id) {
var locationObject = PatientLocations.findOne(id);
return locationObject.location || "";
}
// Add timepoint data to Measurements collection
function addTimepointData(lesionData) {
var timepoints = Timepoints.find().fetch();
var timepointsObject = {};
for (var i = 0; i < timepoints.length; i++) {
var timepointId = timepoints[i].timepointID;
var lesionTimepointId = lesionData.timepointID;
var timepointObject;
if (timepointId === lesionTimepointId) {
// Add real measurement
timepointObject = {
longestDiameter: lesionData.measurementText,
imageId: lesionData.imageId,
seriesInstanceUid: lesionData.seriesInstanceUid,
studyInstanceUid: lesionData.studyInstanceUid,
handles: lesionData.handles
};
} else {
// Add null measurement
timepointObject = {
longestDiameter: "",
imageId: "",
seriesInstanceUid: "",
studyInstanceUid: "",
handles: undefined
};
}
timepointsObject[timepointId] = timepointObject;
}
var lesionDataObject = lesionData;
lesionDataObject.patientId = timepoints[0].patientId;
lesionDataObject.location = getLocationName(lesionData.locationUID);
lesionDataObject.timepoints = timepointsObject;
// Is there a use for this?
lesionDataObject.number = Measurements.find().count() + 1;
lesionDataObject.id = Measurements.insert(lesionDataObject);
}
// Update timepoint data in Measurements collection
function updateTimepointData(lesionData) {
// Find the specific lesion to be updated
var measurement = Measurements.findOne({
lesionNumber: lesionData.lesionNumber,
isTarget: lesionData.isTarget
});
// If no such lesion exists, stop here
if (!measurement) {
return;
}
// Update this specific lesion at the given timepoint
var timepointID = lesionData.timepointID;
// Update timepoints from lesion data
var timepoints = measurement.timepoints;
if (timepoints[timepointID] === undefined) {
timepoints[timepointID] = {};
}
timepoints[timepointID].longestDiameter = lesionData.measurementText;
timepoints[timepointID].imageId = lesionData.imageId;
timepoints[timepointID].seriesInstanceUid = lesionData.seriesInstanceUid;
timepoints[timepointID].studyInstanceUid = lesionData.studyInstanceUid;
timepoints[timepointID].handles = lesionData.handles;
lesionData.id = measurement._id;
Measurements.update(measurement._id, {
$set: {
timepoints: timepoints
}
});
}
// Check timepointData is found in Measurements collection
function hasTimepointData(lesionData) {
var timepointData = Measurements.findOne({
lesionNumber: lesionData.lesionNumber,
isTarget: lesionData.isTarget
});
if (timepointData) {
return true;
}
return false;
}
// Adds new timepoint item to timepoints array
function addLesionData(lesionData) {
if (hasTimepointData(lesionData)) {
// Update data
updateTimepointData(lesionData);
} else {
// Insert data
addTimepointData(lesionData);
}
}
// Returns new lesion number according to timepointID
function getNewLesionNumber(timepointID, isTarget) {
// Get all current lesion measurements
var measurements = Measurements.find({isTarget: isTarget},{sort: {lesionNumber: 1}}).fetch();
// If no measurements exist yet, start at 1
if (!measurements.length) {
return 1;
}
// If measurements exist, find the last lesion number
// from the given timepoint
var lesionNumberCounter = 0;
for (var i = 0; i < measurements.length; i++) {
var measurement = measurements[i];
var timepoints = measurement.timepoints;
if (!timepoints[timepointID]) {
// Find lesion number for this timepointID
return measurement.lesionNumber;
}
if (timepoints[timepointID].longestDiameter === '') {
return measurement.lesionNumber;
} else {
lesionNumberCounter = lesionNumberCounter + 1;
}
}
return lesionNumberCounter + 1;
}
// If lesion number is added for any timepoint, returns lesion locationUID
function lesionNumberExists(lesionData) {
if (!hasTimepointData(lesionData)) {
return;
}
var measurement = Measurements.findOne({
lesionNumber: lesionData.lesionNumber,
isTarget: lesionData.isTarget
});
return measurement.locationUID;
}
return {
addLesionData: addLesionData,
getNewLesionNumber: getNewLesionNumber,
lesionNumberExists: lesionNumberExists,
updateTimepointData: updateTimepointData,
getLocationName: getLocationName
};
})();
@@ -32,7 +32,6 @@
/// --- Mouse Tool --- ///
///////// BEGIN ACTIVE TOOL ///////
function addNewMeasurement(mouseEventData) {
var element = mouseEventData.element;
function doneCallback(lesionNumber) {
@@ -53,9 +52,9 @@
// since we are dragging to another place to drop the end point, we can just activate
// the end point and let the moveHandle move it for us.
$(mouseEventData.element).off('CornerstoneToolsMouseMove', cornerstoneTools.nonTarget.mouseMoveCallback);
$(mouseEventData.element).off('CornerstoneToolsMouseDown', cornerstoneTools.nonTarget.mouseDownCallback);
$(mouseEventData.element).off('CornerstoneToolsMouseDownActivate', cornerstoneTools.nonTarget.mouseDownActivateCallback);
$(element).off('CornerstoneToolsMouseMove', cornerstoneTools.nonTarget.mouseMoveCallback);
$(element).off('CornerstoneToolsMouseDown', cornerstoneTools.nonTarget.mouseDownCallback);
$(element).off('CornerstoneToolsMouseDownActivate', cornerstoneTools.nonTarget.mouseDownActivateCallback);
var config = cornerstoneTools.nonTarget.getConfiguration();
@@ -75,9 +74,9 @@
}
$(mouseEventData.element).on('CornerstoneToolsMouseMove', eventData, cornerstoneTools.nonTarget.mouseMoveCallback);
$(mouseEventData.element).on('CornerstoneToolsMouseDown', eventData, cornerstoneTools.nonTarget.mouseDownCallback);
$(mouseEventData.element).on('CornerstoneToolsMouseDownActivate', eventData, cornerstoneTools.nonTarget.mouseDownActivateCallback);
$(element).on('CornerstoneToolsMouseMove', eventData, cornerstoneTools.nonTarget.mouseMoveCallback);
$(element).on('CornerstoneToolsMouseDown', eventData, cornerstoneTools.nonTarget.mouseDownCallback);
$(element).on('CornerstoneToolsMouseDownActivate', eventData, cornerstoneTools.nonTarget.mouseDownActivateCallback);
cornerstone.updateImage(mouseEventData.element);
});
@@ -127,8 +126,7 @@
studyInstanceUid: studyInstanceUid,
patientId: patientId,
measurementText: '',
isTarget: false,
uid: uuid.v4()
isTarget: false
};
return measurementData;
@@ -184,8 +182,8 @@
// configurable shadow from CornerstoneTools
if (config && config.shadow) {
context.shadowColor = '#000000';
context.shadowOffsetX = +1;
context.shadowOffsetY = +1;
context.shadowOffsetX = 1;
context.shadowOffsetY = 1;
}
if (data.active) {
@@ -286,6 +284,7 @@
if (deleteTool === true) {
cornerstoneTools.removeToolState(element, toolType, data);
cornerstone.updateImage(element);
return;
}
data.active = false;