Add option to convert non-Targets to CR/NE/EX
This commit is contained in:
parent
dbeaba1684
commit
bee1e38044
@ -1,10 +1,10 @@
|
|||||||
(function($, cornerstone, cornerstoneMath, cornerstoneTools) {
|
(function($, cornerstone, cornerstoneMath, cornerstoneTools) {
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var crToolInterface = cornerstoneTools.crunexTool('crTool');
|
var crToolInterface = cornerstoneTools.crunexTool('crTool');
|
||||||
cornerstoneTools.crTool = crToolInterface.crunex;
|
cornerstoneTools.crTool = crToolInterface.crunex;
|
||||||
cornerstoneTools.crTool.setConfiguration(crToolInterface.defaultConfiguration);
|
cornerstoneTools.crTool.setConfiguration(crToolInterface.defaultConfiguration);
|
||||||
cornerstoneTools.crToolTouch = crToolInterface.crunexTouch;
|
cornerstoneTools.crToolTouch = crToolInterface.crunexTouch;
|
||||||
|
|
||||||
|
|
||||||
})($, cornerstone, cornerstoneMath, cornerstoneTools);
|
})($, cornerstone, cornerstoneMath, cornerstoneTools);
|
||||||
|
|||||||
@ -83,6 +83,11 @@ Template.lesionTableTimepointCell.events({
|
|||||||
var currentTimepointID = this.timepointId;
|
var currentTimepointID = this.timepointId;
|
||||||
|
|
||||||
var timepointData = currentMeasurement.timepoints[currentTimepointID];
|
var timepointData = currentMeasurement.timepoints[currentTimepointID];
|
||||||
|
|
||||||
|
if (!timepointData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var measurementData = {
|
var measurementData = {
|
||||||
id: currentMeasurement._id,
|
id: currentMeasurement._id,
|
||||||
timepointId: currentTimepointID,
|
timepointId: currentTimepointID,
|
||||||
|
|||||||
@ -61,6 +61,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="locationOK">
|
<div class="locationOK">
|
||||||
<button class="btn btn-link" id="removeLesion">Remove</button>
|
<button class="btn btn-link" id="removeLesion">Remove</button>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-link dropdown-toggle"
|
||||||
|
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||||
|
Convert
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
{{ #each conversionOptions }}
|
||||||
|
<a class="btn btn-link dropdown-item convertNonTarget" data-type="{{id}}">{{name}}</a>
|
||||||
|
{{ /each }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button class="btn btn-primary" id="nonTargetLesionOK">OK</button>
|
<button class="btn btn-primary" id="nonTargetLesionOK">OK</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -173,11 +173,6 @@ changeNonTargetLocationCallback = function(measurementData, eventData, doneCallb
|
|||||||
// Make sure the context menu is closed when the user clicks away
|
// Make sure the context menu is closed when the user clicks away
|
||||||
$('.removableBackdrop').one('mousedown touchstart', function() {
|
$('.removableBackdrop').one('mousedown touchstart', function() {
|
||||||
closeHandler(dialog);
|
closeHandler(dialog);
|
||||||
|
|
||||||
if (doneCallback && typeof doneCallback === 'function') {
|
|
||||||
var deleteTool = true;
|
|
||||||
doneCallback(measurementData, deleteTool);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Find the select option box
|
// Find the select option box
|
||||||
@ -320,6 +315,17 @@ Template.nonTargetLesionDialog.events({
|
|||||||
var dialog = Template.nonTargetLesionDialog.dialog;
|
var dialog = Template.nonTargetLesionDialog.dialog;
|
||||||
closeHandler(dialog);
|
closeHandler(dialog);
|
||||||
},
|
},
|
||||||
|
'click a.convertNonTarget': function(evt) {
|
||||||
|
var measurementData = Template.nonTargetLesionDialog.measurementData;
|
||||||
|
var dialog = Template.nonTargetLesionDialog.dialog;
|
||||||
|
|
||||||
|
var button = $(evt.currentTarget);
|
||||||
|
var toolType = button.data('type');
|
||||||
|
|
||||||
|
convertNonTarget(measurementData, toolType);
|
||||||
|
|
||||||
|
closeHandler(dialog);
|
||||||
|
},
|
||||||
'keydown #lesionLocationDialog, keydown #lesionLocationRelabelDialog': function(e) {
|
'keydown #lesionLocationDialog, keydown #lesionLocationRelabelDialog': function(e) {
|
||||||
var dialog = Template.nonTargetLesionDialog.dialog;
|
var dialog = Template.nonTargetLesionDialog.dialog;
|
||||||
|
|
||||||
@ -331,11 +337,28 @@ Template.nonTargetLesionDialog.events({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var conversionOptions = [{
|
||||||
|
id: 'bidirectional',
|
||||||
|
name: 'Measurable Target'
|
||||||
|
}, {
|
||||||
|
id: 'crTool',
|
||||||
|
name: 'Complete Response (CR)'
|
||||||
|
}, {
|
||||||
|
id: 'unTool',
|
||||||
|
name: 'Not Evaluable (NE)'
|
||||||
|
}, {
|
||||||
|
id: 'exTool',
|
||||||
|
name: 'Excluded (EX)'
|
||||||
|
}];
|
||||||
|
|
||||||
Template.nonTargetLesionDialog.helpers({
|
Template.nonTargetLesionDialog.helpers({
|
||||||
lesionLocations: function() {
|
lesionLocations: function() {
|
||||||
return LesionLocations.find();
|
return LesionLocations.find();
|
||||||
},
|
},
|
||||||
locationResponses: function() {
|
locationResponses: function() {
|
||||||
return LocationResponses.find();
|
return LocationResponses.find();
|
||||||
|
},
|
||||||
|
conversionOptions: function() {
|
||||||
|
return conversionOptions;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
70
Packages/lesiontracker/lib/convertNonTarget.js
Normal file
70
Packages/lesiontracker/lib/convertNonTarget.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
var responseTypes = {
|
||||||
|
crTool: 'CR',
|
||||||
|
exTool: 'EX',
|
||||||
|
unTool: 'UN'
|
||||||
|
};
|
||||||
|
|
||||||
|
convertNonTarget = function(measurementData, newTooltype) {
|
||||||
|
if (measurementData.toolType !== 'nonTarget') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var measurement = Measurements.findOne(measurementData.id);
|
||||||
|
|
||||||
|
var timepoint = Timepoints.findOne({
|
||||||
|
timepointId: measurementData.timepointId
|
||||||
|
});
|
||||||
|
|
||||||
|
if (timepoint && timepoint.timepointType !== 'followup') {
|
||||||
|
log.warn('Not a followup');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, update the measurementData and add it to the new tool type
|
||||||
|
var newMeasurement = {
|
||||||
|
id: 'notready',
|
||||||
|
lesionNumber: LesionManager.getNewLesionNumber(measurementData.timepointId, false),
|
||||||
|
visible: true,
|
||||||
|
active: true,
|
||||||
|
imageId: measurementData.imageId,
|
||||||
|
seriesInstanceUid: measurementData.seriesInstanceUid,
|
||||||
|
studyInstanceUid: measurementData.studyInstanceUid,
|
||||||
|
patientId: measurementData.patientId,
|
||||||
|
isTarget: false,
|
||||||
|
toolType: newTooltype
|
||||||
|
};
|
||||||
|
|
||||||
|
newMeasurement.handles = measurementData.handles;
|
||||||
|
|
||||||
|
if (responseTypes[newTooltype]) {
|
||||||
|
newMeasurement.response = responseTypes[newTooltype];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds lesion data to timepoints array
|
||||||
|
LesionManager.updateLesionData(newMeasurement);
|
||||||
|
|
||||||
|
// Set the new Measurement to have the same location as the old one
|
||||||
|
if (measurement.location && measurement.locationId) {
|
||||||
|
var existingMeasurement = Measurements.findOne({
|
||||||
|
lesionNumber: newMeasurement.lesionNumber,
|
||||||
|
isTarget: newMeasurement.isTarget
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!existingMeasurement) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Measurements.update(existingMeasurement._id, {
|
||||||
|
$set: {
|
||||||
|
location: measurement.location,
|
||||||
|
locationId: measurement.locationId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (measurement) {
|
||||||
|
// Remove the timepointData from this Measurement and update it
|
||||||
|
// in the database, if it is already in the database
|
||||||
|
clearMeasurementTimepointData(measurement._id, measurementData.timepointId);
|
||||||
|
}
|
||||||
|
};
|
||||||
@ -1,11 +1,14 @@
|
|||||||
// If timepoint is baseline, sets lesion tool as active tool
|
// If timepoint is baseline, sets lesion tool as active tool
|
||||||
setTimepointTools = function(timepoint) {
|
setTimepointTools = function(timepoint) {
|
||||||
|
if (!timepoint) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var disabledBaselineTools = ["crunexTools"];
|
var disabledBaselineTools = ["crunexTools"];
|
||||||
var states = toolManager.getToolDefaultStates();
|
var states = toolManager.getToolDefaultStates();
|
||||||
var disabledToolButtons = states.disabledToolButtons;
|
var disabledToolButtons = states.disabledToolButtons;
|
||||||
|
|
||||||
if ((timepoint.timepointType).toLowerCase() === "baseline") {
|
if (timepoint.timepointType === "baseline") {
|
||||||
// Set active tool as lesion tool
|
// Set active tool as lesion tool
|
||||||
toolManager.setActiveTool('bidirectional');
|
toolManager.setActiveTool('bidirectional');
|
||||||
disabledBaselineTools.forEach(function(tool) {
|
disabledBaselineTools.forEach(function(tool) {
|
||||||
@ -14,7 +17,6 @@ setTimepointTools = function(timepoint) {
|
|||||||
disabledToolButtons.push(tool);
|
disabledToolButtons.push(tool);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
toolManager.setActiveTool(toolManager.getDefaultTool());
|
toolManager.setActiveTool(toolManager.getDefaultTool());
|
||||||
// Remove disabled baseline tools
|
// Remove disabled baseline tools
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
// Create package logger using loglevel
|
// Create package logger using loglevel
|
||||||
// https://atmospherejs.com/spacejamio/loglevel
|
// https://atmospherejs.com/spacejamio/loglevel
|
||||||
log = loglevel.createPackageLogger('lesiontracker', defaultLevel = 'info');
|
log = loglevel.createPackageLogger('lesiontracker', defaultLevel = 'warn');
|
||||||
|
|||||||
@ -56,7 +56,6 @@ Package.onUse(function(api) {
|
|||||||
bare: true
|
bare: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// Trial Criteria data validation (the Meteor package is currently out-of-date)
|
// Trial Criteria data validation (the Meteor package is currently out-of-date)
|
||||||
api.addFiles('client/compatibility/validate.js', 'client', {
|
api.addFiles('client/compatibility/validate.js', 'client', {
|
||||||
bare: true
|
bare: true
|
||||||
@ -71,7 +70,6 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('client/components/associationModal/associationModal.styl', 'client');
|
api.addFiles('client/components/associationModal/associationModal.styl', 'client');
|
||||||
api.addFiles('client/components/associationModal/associationModal.js', 'client');
|
api.addFiles('client/components/associationModal/associationModal.js', 'client');
|
||||||
|
|
||||||
|
|
||||||
api.addFiles('client/components/activeEntry/activeEntry.styl', 'client');
|
api.addFiles('client/components/activeEntry/activeEntry.styl', 'client');
|
||||||
api.addFiles('client/components/activeEntry/activeEntry.js', 'client');
|
api.addFiles('client/components/activeEntry/activeEntry.js', 'client');
|
||||||
|
|
||||||
@ -180,6 +178,7 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('lib/clearTools.js', 'client');
|
api.addFiles('lib/clearTools.js', 'client');
|
||||||
api.addFiles('lib/calculateTotalLesionBurden.js', 'client');
|
api.addFiles('lib/calculateTotalLesionBurden.js', 'client');
|
||||||
api.addFiles('lib/convertToNonTarget.js', 'client');
|
api.addFiles('lib/convertToNonTarget.js', 'client');
|
||||||
|
api.addFiles('lib/convertNonTarget.js', 'client');
|
||||||
api.addFiles('lib/timepointAutoCheck.js', 'client');
|
api.addFiles('lib/timepointAutoCheck.js', 'client');
|
||||||
|
|
||||||
api.addFiles('lib/syncMeasurementAndToolData.js', 'client');
|
api.addFiles('lib/syncMeasurementAndToolData.js', 'client');
|
||||||
@ -190,7 +189,6 @@ Package.onUse(function(api) {
|
|||||||
api.addFiles('lib/handleMeasurementModified.js', 'client');
|
api.addFiles('lib/handleMeasurementModified.js', 'client');
|
||||||
api.addFiles('lib/handleMeasurementRemoved.js', 'client');
|
api.addFiles('lib/handleMeasurementRemoved.js', 'client');
|
||||||
|
|
||||||
|
|
||||||
// Export global functions
|
// Export global functions
|
||||||
api.export('pixelSpacingAutorunCheck', 'client');
|
api.export('pixelSpacingAutorunCheck', 'client');
|
||||||
api.export('handleMeasurementAdded', 'client');
|
api.export('handleMeasurementAdded', 'client');
|
||||||
@ -212,9 +210,9 @@ Package.onUse(function(api) {
|
|||||||
api.export('getTrialCriteriaConstraints', 'client');
|
api.export('getTrialCriteriaConstraints', 'client');
|
||||||
api.export('calculateTotalLesionBurden', 'client');
|
api.export('calculateTotalLesionBurden', 'client');
|
||||||
api.export('convertToNonTarget', 'client');
|
api.export('convertToNonTarget', 'client');
|
||||||
|
api.export('convertNonTarget', 'client');
|
||||||
api.export('timepointAutoCheck', 'client');
|
api.export('timepointAutoCheck', 'client');
|
||||||
|
|
||||||
|
|
||||||
// Export global objects
|
// Export global objects
|
||||||
api.export('TrialResponseCriteria', 'client');
|
api.export('TrialResponseCriteria', 'client');
|
||||||
api.export('TrialCriteriaConstraints', 'client');
|
api.export('TrialCriteriaConstraints', 'client');
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user