Add Next/Previous Hanging Protcol stage buttons (only works with MG for now)
This commit is contained in:
parent
bfe6b80e27
commit
487ebf9541
@ -48,6 +48,12 @@ Template.viewer.onCreated(function() {
|
|||||||
}
|
}
|
||||||
OHIF.viewer.isPlaying[viewportIndex] = !OHIF.viewer.isPlaying[viewportIndex];
|
OHIF.viewer.isPlaying[viewportIndex] = !OHIF.viewer.isPlaying[viewportIndex];
|
||||||
Session.set('UpdateCINE', Random.id());
|
Session.set('UpdateCINE', Random.id());
|
||||||
|
},
|
||||||
|
previousPresentationGroup: function() {
|
||||||
|
WindowManager.previousPresentationGroup();
|
||||||
|
},
|
||||||
|
nextPresentationGroup: function() {
|
||||||
|
WindowManager.nextPresentationGroup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -52,6 +52,12 @@ Template.viewer.onCreated(function() {
|
|||||||
}
|
}
|
||||||
OHIF.viewer.isPlaying[viewportIndex] = !OHIF.viewer.isPlaying[viewportIndex];
|
OHIF.viewer.isPlaying[viewportIndex] = !OHIF.viewer.isPlaying[viewportIndex];
|
||||||
Session.set('UpdateCINE', Random.id());
|
Session.set('UpdateCINE', Random.id());
|
||||||
|
},
|
||||||
|
previousPresentationGroup: function() {
|
||||||
|
WindowManager.previousPresentationGroup();
|
||||||
|
},
|
||||||
|
nextPresentationGroup: function() {
|
||||||
|
WindowManager.nextPresentationGroup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -186,6 +186,7 @@ function thumbnailDragEndHandler(e, target) {
|
|||||||
|
|
||||||
// Rerender the viewport using the drag and drop data
|
// Rerender the viewport using the drag and drop data
|
||||||
rerenderViewportWithNewSeries(element, OHIF.viewer.dragAndDropData);
|
rerenderViewportWithNewSeries(element, OHIF.viewer.dragAndDropData);
|
||||||
|
Session.get('UseHangingProtocol', false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,20 @@
|
|||||||
|
<template name="hangingProtocolButtons">
|
||||||
|
<button id="previousPresentationGroup" type="button"
|
||||||
|
class="imageViewerCommand btn btn-sm btn-default"
|
||||||
|
data-container="body"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
data-placement="bottom"
|
||||||
|
title="Previous presentation group"
|
||||||
|
disabled="{{ #unless isPreviousAvailable }} true {{ /unless }}">
|
||||||
|
<span class="fa fa-step-backward"></span>
|
||||||
|
</button>
|
||||||
|
<button id="nextPresentationGroup" type="button"
|
||||||
|
class="imageViewerCommand btn btn-sm btn-default"
|
||||||
|
data-container="body"
|
||||||
|
data-toggle="tooltip"
|
||||||
|
data-placement="bottom"
|
||||||
|
title="Next presentation group"
|
||||||
|
disabled="{{ #unless isNextAvailable }} true {{ /unless }}">
|
||||||
|
<span class="fa fa-step-forward"></span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
Template.hangingProtocolButtons.helpers({
|
||||||
|
'isNextAvailable': function() {
|
||||||
|
var presentationGroup = Session.get('WindowManagerPresentationGroup');
|
||||||
|
var numPresentationGroups = WindowManager.getNumPresentationGroups();
|
||||||
|
return presentationGroup < numPresentationGroups;
|
||||||
|
},
|
||||||
|
'isPreviousAvailable': function() {
|
||||||
|
var presentationGroup = Session.get('WindowManagerPresentationGroup');
|
||||||
|
return presentationGroup > 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -41,7 +41,11 @@ Template.imageViewerViewports.helpers({
|
|||||||
viewportRows: viewportRows
|
viewportRows: viewportRows
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inputData.DisplaySetPresentationGroup = Session.get('WindowManagerPresentationGroup');
|
||||||
var hangingProtocolViewportData = WindowManager.getHangingProtocol(inputData);
|
var hangingProtocolViewportData = WindowManager.getHangingProtocol(inputData);
|
||||||
|
if (Session.get('UseHangingProtocol')) {
|
||||||
|
viewportData = hangingProtocolViewportData;
|
||||||
|
}
|
||||||
|
|
||||||
var numViewports = viewportRows * viewportColumns;
|
var numViewports = viewportRows * viewportColumns;
|
||||||
for (var i=0; i < numViewports; ++i) {
|
for (var i=0; i < numViewports; ++i) {
|
||||||
|
|||||||
@ -12,6 +12,10 @@
|
|||||||
{{ #if includeLayoutButton }}
|
{{ #if includeLayoutButton }}
|
||||||
{{ >layoutButton }}
|
{{ >layoutButton }}
|
||||||
{{ /if }}
|
{{ /if }}
|
||||||
|
|
||||||
|
{{ #if includeHangingProtocolButtons }}
|
||||||
|
{{ >hangingProtocolButtons }}
|
||||||
|
{{ /if }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -152,5 +152,11 @@ Template.toolbar.helpers({
|
|||||||
return this.toolbarOptions.includeLayoutButton;
|
return this.toolbarOptions.includeLayoutButton;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
},
|
||||||
|
'includeHangingProtocolButtons': function() {
|
||||||
|
if (this.toolbarOptions && this.toolbarOptions.includeHangingProtocolButtons !== undefined) {
|
||||||
|
return this.toolbarOptions.includeHangingProtocolButtons;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -44,6 +44,8 @@ addMetaData = function(imageId, data) {
|
|||||||
sopInstanceUid: instanceMetaData.sopInstanceUid,
|
sopInstanceUid: instanceMetaData.sopInstanceUid,
|
||||||
sopClassUid: instanceMetaData.sopClassUid,
|
sopClassUid: instanceMetaData.sopClassUid,
|
||||||
instanceNumber: instanceMetaData.instanceNumber,
|
instanceNumber: instanceMetaData.instanceNumber,
|
||||||
|
laterality: instanceMetaData.laterality,
|
||||||
|
viewPosition: instanceMetaData.viewPosition,
|
||||||
index: imageIndex
|
index: imageIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,8 @@ function getMammoHangingProtocol() {
|
|||||||
// Skip Nominal Screen Definition Sequence for now,
|
// Skip Nominal Screen Definition Sequence for now,
|
||||||
|
|
||||||
// http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.23.3.html
|
// http://dicom.nema.org/medical/dicom/current/output/chtml/part03/sect_C.23.3.html
|
||||||
DisplaySetsSequence: [{
|
DisplaySetsSequence: [
|
||||||
|
{
|
||||||
// Left side image (R MLO Current)
|
// Left side image (R MLO Current)
|
||||||
ImageSetNumber: 1,
|
ImageSetNumber: 1,
|
||||||
DisplaySetNumber: 1,
|
DisplaySetNumber: 1,
|
||||||
@ -80,6 +81,38 @@ function getMammoHangingProtocol() {
|
|||||||
ImageBoxNumber: 1,
|
ImageBoxNumber: 1,
|
||||||
ImageBoxLayoutType: 'STACK'
|
ImageBoxLayoutType: 'STACK'
|
||||||
}],
|
}],
|
||||||
|
FilterOperationsSequence: [{
|
||||||
|
SelectorAttributeVR: 'CS',
|
||||||
|
SelectorCSValue: 'R CC',
|
||||||
|
FilterByCategory: 'SERIES_DESCRIPTION',
|
||||||
|
FilterByOperator: 'MEMBER_OF'
|
||||||
|
}],
|
||||||
|
}, {
|
||||||
|
// Right side image (L MLO Current)
|
||||||
|
ImageSetNumber: 1,
|
||||||
|
DisplaySetNumber: 1,
|
||||||
|
DisplaySetPresentationGroup: 1,
|
||||||
|
ImageBoxesSequence: [{
|
||||||
|
ImageBoxNumber: 1,
|
||||||
|
ImageBoxLayoutType: 'STACK'
|
||||||
|
}],
|
||||||
|
FilterOperationsSequence: [{
|
||||||
|
SelectorAttributeVR: 'CS',
|
||||||
|
SelectorCSValue: 'L CC',
|
||||||
|
FilterByCategory: 'SERIES_DESCRIPTION',
|
||||||
|
FilterByOperator: 'MEMBER_OF'
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
// Left side image (R MLO Current)
|
||||||
|
ImageSetNumber: 1,
|
||||||
|
DisplaySetNumber: 1,
|
||||||
|
DisplaySetPresentationGroup: 2,
|
||||||
|
DisplaySetPresentationGroupDescription: 'Current Mediolateral only',
|
||||||
|
ImageBoxesSequence: [{
|
||||||
|
DisplayEnvironmentSpatialPosition: '0\0.2\0.16667\0',
|
||||||
|
ImageBoxNumber: 1,
|
||||||
|
ImageBoxLayoutType: 'STACK'
|
||||||
|
}],
|
||||||
FilterOperationsSequence: [{
|
FilterOperationsSequence: [{
|
||||||
SelectorAttributeVR: 'CS',
|
SelectorAttributeVR: 'CS',
|
||||||
SelectorCSValue: 'R MLO',
|
SelectorCSValue: 'R MLO',
|
||||||
@ -97,7 +130,7 @@ function getMammoHangingProtocol() {
|
|||||||
// Right side image (L MLO Current)
|
// Right side image (L MLO Current)
|
||||||
ImageSetNumber: 1,
|
ImageSetNumber: 1,
|
||||||
DisplaySetNumber: 1,
|
DisplaySetNumber: 1,
|
||||||
DisplaySetPresentationGroup: 1,
|
DisplaySetPresentationGroup: 2,
|
||||||
ImageBoxesSequence: [{
|
ImageBoxesSequence: [{
|
||||||
ImageBoxNumber: 1,
|
ImageBoxNumber: 1,
|
||||||
ImageBoxLayoutType: 'STACK'
|
ImageBoxLayoutType: 'STACK'
|
||||||
@ -254,8 +287,8 @@ function defaultHangingProtocol(inputData) {
|
|||||||
return viewportData;
|
return viewportData;
|
||||||
}
|
}
|
||||||
|
|
||||||
var currentStage = 0;
|
|
||||||
var hangingProtocol;
|
var hangingProtocol;
|
||||||
|
var presentationGroup = 1;
|
||||||
|
|
||||||
function getHangingProtocol(inputData) {
|
function getHangingProtocol(inputData) {
|
||||||
// TODO = Update this to use Collection logic
|
// TODO = Update this to use Collection logic
|
||||||
@ -278,9 +311,11 @@ function getHangingProtocol(inputData) {
|
|||||||
|
|
||||||
if (modalities.indexOf('MG') > -1) {
|
if (modalities.indexOf('MG') > -1) {
|
||||||
var hangingProtocol = getMammoHangingProtocol();
|
var hangingProtocol = getMammoHangingProtocol();
|
||||||
|
Session.set('WindowManagerPresentationGroup', presentationGroup);
|
||||||
return applyDICOMHangingProtocol(hangingProtocol, inputData);
|
return applyDICOMHangingProtocol(hangingProtocol, inputData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Session.set('WindowManagerPresentationGroup', undefined);
|
||||||
return defaultHangingProtocol(inputData);
|
return defaultHangingProtocol(inputData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,9 +323,50 @@ function setHangingProtocol(protocol) {
|
|||||||
hangingProtocol = protocol;
|
hangingProtocol = protocol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function previousPresentationGroup() {
|
||||||
|
presentationGroup--;
|
||||||
|
presentationGroup = Math.max(1, presentationGroup);
|
||||||
|
|
||||||
|
log.info('previousPresentationGroup: ' + presentationGroup);
|
||||||
|
Session.set('WindowManagerPresentationGroup', presentationGroup);
|
||||||
|
Session.set('UseHangingProtocol', Random.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextPresentationGroup() {
|
||||||
|
var numPresentationGroups = getNumPresentationGroups();
|
||||||
|
|
||||||
|
presentationGroup++;
|
||||||
|
presentationGroup = Math.min(numPresentationGroups, presentationGroup);
|
||||||
|
|
||||||
|
log.info('nextPresentationGroup: ' + presentationGroup);
|
||||||
|
Session.set('WindowManagerPresentationGroup', presentationGroup);
|
||||||
|
Session.set('UseHangingProtocol', Random.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNumPresentationGroups() {
|
||||||
|
// TODO=Pull this information from the largest
|
||||||
|
// value of DisplaySetPresentationGroup in the DisplaySetsSequence
|
||||||
|
// after the DICOM-HP is parsed
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrentPresentationGroup() {
|
||||||
|
return presentationGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCurrentPresentationGroup(groupNumber) {
|
||||||
|
// Unused for now
|
||||||
|
presentationGroup = groupNumber;
|
||||||
|
}
|
||||||
|
|
||||||
WindowManager = {
|
WindowManager = {
|
||||||
setHangingProtocol: setHangingProtocol,
|
setHangingProtocol: setHangingProtocol,
|
||||||
getHangingProtocol: getHangingProtocol
|
getHangingProtocol: getHangingProtocol,
|
||||||
|
getNumPresentationGroups: getNumPresentationGroups,
|
||||||
|
setCurrentPresentationGroup: setCurrentPresentationGroup,
|
||||||
|
getCurrentPresentationGroup: getCurrentPresentationGroup,
|
||||||
|
nextPresentationGroup: nextPresentationGroup,
|
||||||
|
previousPresentationGroup: previousPresentationGroup
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowManager.setHangingProtocol(defaultHangingProtocol);
|
WindowManager.setHangingProtocol(defaultHangingProtocol);
|
||||||
|
|||||||
@ -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('viewerbase', defaultLevel = 'warn');
|
log = loglevel.createPackageLogger('viewerbase', defaultLevel = 'info');
|
||||||
@ -86,6 +86,9 @@ Package.onUse(function (api) {
|
|||||||
api.addFiles('components/viewer/playClipButton/playClipButton.html', 'client');
|
api.addFiles('components/viewer/playClipButton/playClipButton.html', 'client');
|
||||||
api.addFiles('components/viewer/playClipButton/playClipButton.js', 'client');
|
api.addFiles('components/viewer/playClipButton/playClipButton.js', 'client');
|
||||||
|
|
||||||
|
api.addFiles('components/viewer/hangingProtocolButtons/hangingProtocolButtons.html', 'client');
|
||||||
|
api.addFiles('components/viewer/hangingProtocolButtons/hangingProtocolButtons.js', 'client');
|
||||||
|
|
||||||
api.addFiles('components/viewer/layoutButton/layoutButton.html', 'client');
|
api.addFiles('components/viewer/layoutButton/layoutButton.html', 'client');
|
||||||
|
|
||||||
api.addFiles('components/viewer/toolbar/toolbar.html', 'client');
|
api.addFiles('components/viewer/toolbar/toolbar.html', 'client');
|
||||||
|
|||||||
@ -101,7 +101,9 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
|||||||
windowWidth: DICOMWeb.getString(instance['00281051']),
|
windowWidth: DICOMWeb.getString(instance['00281051']),
|
||||||
rescaleIntercept: DICOMWeb.getNumber(instance['00281052']),
|
rescaleIntercept: DICOMWeb.getNumber(instance['00281052']),
|
||||||
rescaleSlope: DICOMWeb.getNumber(instance['00281053']),
|
rescaleSlope: DICOMWeb.getNumber(instance['00281053']),
|
||||||
sourceImageInstanceUid: getSourceImageInstanceUid(instance)
|
sourceImageInstanceUid: getSourceImageInstanceUid(instance),
|
||||||
|
laterality: DICOMWeb.getString(instance['00200062']),
|
||||||
|
viewPosition: DICOMWeb.getString(instance['00185101']),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (server.imageRendering === 'wadouri') {
|
if (server.imageRendering === 'wadouri') {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user