feat: Add a new hanging protocol @ohif/mn (#3305)
* feat: Add a new hanging protocol @ohif/mn * Add @ohif/seg example * PR comments and a couple more fixes to make things cleaner * PR comment * Added an example to cause the PR checks to rerun
This commit is contained in:
parent
6cf271d006
commit
c508a2b6bc
@ -0,0 +1,78 @@
|
|||||||
|
import { Types } from '@ohif/core';
|
||||||
|
|
||||||
|
const segProtocol: Types.HangingProtocol.Protocol = {
|
||||||
|
id: '@ohif/seg',
|
||||||
|
// Don't store this hanging protocol as it applies to the currently active
|
||||||
|
// display set by default
|
||||||
|
// cacheId: null,
|
||||||
|
hasUpdatedPriorsInformation: false,
|
||||||
|
name: 'Segmentations',
|
||||||
|
// Just apply this one when specifically listed
|
||||||
|
protocolMatchingRules: [],
|
||||||
|
toolGroupIds: ['default'],
|
||||||
|
// -1 would be used to indicate active only, whereas other values are
|
||||||
|
// the number of required priors referenced - so 0 means active with
|
||||||
|
// 0 or more priors.
|
||||||
|
numberOfPriorsReferenced: 0,
|
||||||
|
// Default viewport is used to define the viewport when
|
||||||
|
// additional viewports are added using the layout tool
|
||||||
|
defaultViewport: {
|
||||||
|
viewportOptions: {
|
||||||
|
viewportType: 'stack',
|
||||||
|
toolGroupId: 'default',
|
||||||
|
allowUnmatchedView: true,
|
||||||
|
},
|
||||||
|
displaySets: [
|
||||||
|
{
|
||||||
|
id: 'segDisplaySetId',
|
||||||
|
matchedDisplaySetsIndex: -1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
displaySetSelectors: {
|
||||||
|
segDisplaySetId: {
|
||||||
|
seriesMatchingRules: [
|
||||||
|
{
|
||||||
|
attribute: 'Modality',
|
||||||
|
constraint: {
|
||||||
|
equals: 'SEG',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stages: [
|
||||||
|
{
|
||||||
|
name: 'Segmentations',
|
||||||
|
viewportStructure: {
|
||||||
|
layoutType: 'grid',
|
||||||
|
properties: {
|
||||||
|
rows: 1,
|
||||||
|
columns: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
viewports: [
|
||||||
|
{
|
||||||
|
viewportOptions: { allowUnmatchedView: true },
|
||||||
|
displaySets: [
|
||||||
|
{
|
||||||
|
id: 'segDisplaySetId',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
function getHangingProtocolModule() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: segProtocol.id,
|
||||||
|
protocol: segProtocol,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default getHangingProtocolModule;
|
||||||
|
export { segProtocol };
|
||||||
@ -5,6 +5,7 @@ import { Types } from '@ohif/core';
|
|||||||
|
|
||||||
import getSopClassHandlerModule from './getSopClassHandlerModule';
|
import getSopClassHandlerModule from './getSopClassHandlerModule';
|
||||||
import PanelSegmentation from './panels/PanelSegmentation';
|
import PanelSegmentation from './panels/PanelSegmentation';
|
||||||
|
import getHangingProtocolModule from './getHangingProtocolModule';
|
||||||
|
|
||||||
const Component = React.lazy(() => {
|
const Component = React.lazy(() => {
|
||||||
return import(
|
return import(
|
||||||
@ -79,6 +80,8 @@ const extension = {
|
|||||||
* Examples include the default sop class handler provided by the default extension
|
* Examples include the default sop class handler provided by the default extension
|
||||||
*/
|
*/
|
||||||
getSopClassHandlerModule,
|
getSopClassHandlerModule,
|
||||||
|
|
||||||
|
getHangingProtocolModule,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default extension;
|
export default extension;
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import { Types } from '@ohif/core';
|
import { Types } from '@ohif/core';
|
||||||
|
|
||||||
const mpr: Types.HangingProtocol.Protocol = {
|
const mpr: Types.HangingProtocol.Protocol = {
|
||||||
|
id: 'mpr',
|
||||||
|
name: 'Multi-Planar Reconstruction',
|
||||||
locked: true,
|
locked: true,
|
||||||
hasUpdatedPriorsInformation: false,
|
hasUpdatedPriorsInformation: false,
|
||||||
name: 'mpr',
|
createdDate: '2021-02-23',
|
||||||
createdDate: '2021-02-23T19:22:08.894Z',
|
modifiedDate: '2023-04-03',
|
||||||
modifiedDate: '2023-02-17',
|
|
||||||
availableTo: {},
|
availableTo: {},
|
||||||
editableBy: {},
|
editableBy: {},
|
||||||
// Unknown number of priors referenced - so just match any study
|
// Unknown number of priors referenced - so just match any study
|
||||||
@ -303,7 +304,7 @@ const mprAnd3DVolumeViewport = {
|
|||||||
function getHangingProtocolModule() {
|
function getHangingProtocolModule() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: 'mpr',
|
name: mpr.id,
|
||||||
protocol: mpr,
|
protocol: mpr,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -171,7 +171,7 @@ const commandsModule = ({
|
|||||||
reset = false,
|
reset = false,
|
||||||
}: HangingProtocolParams): boolean => {
|
}: HangingProtocolParams): boolean => {
|
||||||
try {
|
try {
|
||||||
// Stores in the state the reuseID to displaySetUID mapping
|
// Stores in the state the display set selector id to displaySetUID mapping
|
||||||
// Pass in viewportId for the active viewport. This item will get set as
|
// Pass in viewportId for the active viewport. This item will get set as
|
||||||
// the activeViewportId
|
// the activeViewportId
|
||||||
const state = viewportGridService.getState();
|
const state = viewportGridService.getState();
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import hpMNGrid from './hpMNGrid';
|
||||||
|
|
||||||
const defaultProtocol = {
|
const defaultProtocol = {
|
||||||
id: 'default',
|
id: 'default',
|
||||||
locked: true,
|
locked: true,
|
||||||
@ -92,211 +94,6 @@ const defaultProtocol = {
|
|||||||
],
|
],
|
||||||
createdDate: '2021-02-23T18:32:42.850Z',
|
createdDate: '2021-02-23T18:32:42.850Z',
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is an example of a 2x2 layout that requires at least 2 viewports
|
|
||||||
// filled to be navigatable to
|
|
||||||
{
|
|
||||||
name: '2x2',
|
|
||||||
// Indicate that the number of viewports needed is 2 filled viewports,
|
|
||||||
// but that 4 viewports are preferred.
|
|
||||||
stageActivation: {
|
|
||||||
enabled: {
|
|
||||||
minViewportsMatched: 4,
|
|
||||||
},
|
|
||||||
passive: {
|
|
||||||
minViewportsMatched: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
viewportStructure: {
|
|
||||||
layoutType: 'grid',
|
|
||||||
properties: {
|
|
||||||
rows: 2,
|
|
||||||
columns: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
viewports: [
|
|
||||||
{
|
|
||||||
viewportOptions: {
|
|
||||||
toolGroupId: 'default',
|
|
||||||
},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
matchedDisplaySetsIndex: 3,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
viewportOptions: {
|
|
||||||
toolGroupId: 'default',
|
|
||||||
},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
matchedDisplaySetsIndex: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
viewportOptions: {
|
|
||||||
toolGroupId: 'default',
|
|
||||||
},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
matchedDisplaySetsIndex: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
viewportOptions: {},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
matchedDisplaySetsIndex: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: '3x1',
|
|
||||||
// Indicate that the number of viewports needed is 2 filled viewports,
|
|
||||||
// but that 4 viewports are preferred.
|
|
||||||
stageActivation: {
|
|
||||||
enabled: {
|
|
||||||
minViewportsMatched: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
viewportStructure: {
|
|
||||||
layoutType: 'grid',
|
|
||||||
properties: {
|
|
||||||
rows: 1,
|
|
||||||
columns: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
viewports: [
|
|
||||||
{
|
|
||||||
viewportOptions: {
|
|
||||||
toolGroupId: 'default',
|
|
||||||
},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
matchedDisplaySetsIndex: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
viewportOptions: {
|
|
||||||
toolGroupId: 'default',
|
|
||||||
},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
matchedDisplaySetsIndex: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
viewportOptions: {},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
// This is an example of a layout with more than one element in it
|
|
||||||
// It can be navigated to using , and . (prev/next stage)
|
|
||||||
{
|
|
||||||
name: '2x1',
|
|
||||||
// Indicate that the number of viewports needed is 1 filled viewport,
|
|
||||||
// but that 2 viewports are preferred.
|
|
||||||
stageActivation: {
|
|
||||||
enabled: {
|
|
||||||
minViewportsMatched: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
viewportStructure: {
|
|
||||||
layoutType: 'grid',
|
|
||||||
properties: {
|
|
||||||
rows: 1,
|
|
||||||
columns: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
viewports: [
|
|
||||||
{
|
|
||||||
viewportOptions: {
|
|
||||||
toolGroupId: 'default',
|
|
||||||
// initialImageOptions: {
|
|
||||||
// index: 180,
|
|
||||||
// preset: 'middle', // 'first', 'last', 'middle'
|
|
||||||
// },
|
|
||||||
},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
// Shows the second index of this image set
|
|
||||||
matchedDisplaySetsIndex: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
viewportOptions: {},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: '2x1',
|
|
||||||
// Indicate that the number of viewports needed is 1 filled viewport,
|
|
||||||
// but that 2 viewports are preferred.
|
|
||||||
stageActivation: {
|
|
||||||
enabled: {
|
|
||||||
minViewportsMatched: 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
viewportStructure: {
|
|
||||||
layoutType: 'grid',
|
|
||||||
properties: {
|
|
||||||
rows: 2,
|
|
||||||
columns: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
viewports: [
|
|
||||||
{
|
|
||||||
viewportOptions: {},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
// Shows the second index of this image set
|
|
||||||
matchedDisplaySetsIndex: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
viewportOptions: {},
|
|
||||||
displaySets: [
|
|
||||||
{
|
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -306,6 +103,11 @@ function getHangingProtocolModule() {
|
|||||||
name: defaultProtocol.id,
|
name: defaultProtocol.id,
|
||||||
protocol: defaultProtocol,
|
protocol: defaultProtocol,
|
||||||
},
|
},
|
||||||
|
// Create a MxN hanging protocol available by default
|
||||||
|
{
|
||||||
|
name: hpMNGrid.id,
|
||||||
|
protocol: hpMNGrid,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,24 +1,23 @@
|
|||||||
import { Types } from '@ohif/core';
|
import { Types } from '@ohif/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This hanging protocol has multiple stages, which are enabled when
|
* This hanging protocol can be activated on the primary mode by directly
|
||||||
* there are enough display sets with images to fill the stage, and
|
* referencing it in a URL or by directly including it within a mode, e.g.:
|
||||||
* are passive when there is at least one display set.
|
* `&hangingProtocolId=@ohif/mnGrid` added to the viewer URL
|
||||||
* Enabled display sets are navigated to by default, while passive ones
|
* It is not included in the viewer mode by default.
|
||||||
* are navigated to manually using the ctrl+end keyboard shortcut.
|
|
||||||
*/
|
*/
|
||||||
const hpMN: Types.HangingProtocol.Protocol = {
|
const hpMN: Types.HangingProtocol.Protocol = {
|
||||||
hasUpdatedPriorsInformation: false,
|
hasUpdatedPriorsInformation: false,
|
||||||
id: '@ohif/hp-extension.mn',
|
id: '@ohif/mnGrid',
|
||||||
description: 'Has various hanging protocol layouts for use in testing',
|
description: 'Has various hanging protocol grid layouts',
|
||||||
name: '2x2',
|
name: '2x2',
|
||||||
protocolMatchingRules: [
|
protocolMatchingRules: [
|
||||||
{
|
{
|
||||||
id: 'OneOrMoreSeries',
|
id: 'OneOrMoreSeries',
|
||||||
weight: 1,
|
weight: 25,
|
||||||
attribute: 'numberOfDisplaySetsWithImages',
|
attribute: 'numberOfDisplaySetsWithImages',
|
||||||
constraint: {
|
constraint: {
|
||||||
greaterThan: 1,
|
greaterThan: 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -32,6 +31,15 @@ const hpMN: Types.HangingProtocol.Protocol = {
|
|||||||
greaterThan: { value: 0 },
|
greaterThan: { value: 0 },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
// This display set will select the specified items by preference
|
||||||
|
// It has no affect if nothing is specified in the URL.
|
||||||
|
{
|
||||||
|
attribute: 'isDisplaySetFromUrl',
|
||||||
|
weight: 10,
|
||||||
|
constraint: {
|
||||||
|
equals: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -142,7 +150,6 @@ const hpMN: Types.HangingProtocol.Protocol = {
|
|||||||
displaySets: [
|
displaySets: [
|
||||||
{
|
{
|
||||||
id: 'defaultDisplaySetId',
|
id: 'defaultDisplaySetId',
|
||||||
reuseId: '0-0',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -153,9 +160,8 @@ const hpMN: Types.HangingProtocol.Protocol = {
|
|||||||
},
|
},
|
||||||
displaySets: [
|
displaySets: [
|
||||||
{
|
{
|
||||||
|
id: 'defaultDisplaySetId',
|
||||||
matchedDisplaySetsIndex: 1,
|
matchedDisplaySetsIndex: 1,
|
||||||
id: 'defaultDisplaySetId',
|
|
||||||
reuseId: '1-0',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -166,9 +172,8 @@ const hpMN: Types.HangingProtocol.Protocol = {
|
|||||||
},
|
},
|
||||||
displaySets: [
|
displaySets: [
|
||||||
{
|
{
|
||||||
matchedDisplaySetsIndex: 2,
|
|
||||||
id: 'defaultDisplaySetId',
|
id: 'defaultDisplaySetId',
|
||||||
reuseId: '0-1',
|
matchedDisplaySetsIndex: 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -38,12 +38,12 @@ const findingsContextMenu = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// The example below shows how to include a delegating sub-menu,
|
// The example below shows how to include a delegating sub-menu,
|
||||||
// Only available on the @ohif/hp-extension.mn hanging protocol
|
// Only available on the @ohif/mnGrid hanging protocol
|
||||||
// To demonstrate, select the 3x1 layout from the protocol menu
|
// To demonstrate, select the 3x1 layout from the protocol menu
|
||||||
// and right click on a measurement.
|
// and right click on a measurement.
|
||||||
{
|
{
|
||||||
label: 'IncludeSubMenu',
|
label: 'IncludeSubMenu',
|
||||||
selector: ({ protocol }) => protocol?.id === '@ohif/hp-extension.mn',
|
selector: ({ protocol }) => protocol?.id === '@ohif/mnGrid',
|
||||||
delegating: true,
|
delegating: true,
|
||||||
subMenu: 'orientationSelectionSubMenu',
|
subMenu: 'orientationSelectionSubMenu',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
import hpMN from './hpMN';
|
|
||||||
|
|
||||||
const hangingProtocols = [
|
|
||||||
{
|
|
||||||
name: '@ohif/hp-extension.mn',
|
|
||||||
protocol: hpMN,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a single study hanging protocol which can be referenced as
|
|
||||||
* `@ohif/hp-exgtension.mn`, that has initial layouts which show images
|
|
||||||
* only display sets, up to a 2x2 view.
|
|
||||||
*/
|
|
||||||
export default function getHangingProtocolModule() {
|
|
||||||
return hangingProtocols;
|
|
||||||
}
|
|
||||||
@ -2,14 +2,11 @@ import { Types } from '@ohif/core';
|
|||||||
|
|
||||||
import { id } from './id';
|
import { id } from './id';
|
||||||
|
|
||||||
import getHangingProtocolModule from './hp';
|
|
||||||
import getCustomizationModule from './getCustomizationModule';
|
import getCustomizationModule from './getCustomizationModule';
|
||||||
// import {setViewportZoomPan, storeViewportZoomPan } from './custom-viewport/setViewportZoomPan';
|
// import {setViewportZoomPan, storeViewportZoomPan } from './custom-viewport/setViewportZoomPan';
|
||||||
import sameAs from './custom-attribute/sameAs';
|
import sameAs from './custom-attribute/sameAs';
|
||||||
import numberOfDisplaySets from './custom-attribute/numberOfDisplaySets';
|
import numberOfDisplaySets from './custom-attribute/numberOfDisplaySets';
|
||||||
import numberOfDisplaySetsWithImages from './custom-attribute/numberOfDisplaySetsWithImages';
|
|
||||||
import maxNumImageFrames from './custom-attribute/maxNumImageFrames';
|
import maxNumImageFrames from './custom-attribute/maxNumImageFrames';
|
||||||
import seriesDescriptionsFromDisplaySets from './custom-attribute/seriesDescriptionsFromDisplaySets';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The test extension provides additional behaviour for testing various
|
* The test extension provides additional behaviour for testing various
|
||||||
@ -31,21 +28,11 @@ const testExtension: Types.Extensions.Extension = {
|
|||||||
*/
|
*/
|
||||||
preRegistration: ({ servicesManager }: Types.Extensions.ExtensionParams) => {
|
preRegistration: ({ servicesManager }: Types.Extensions.ExtensionParams) => {
|
||||||
const { hangingProtocolService } = servicesManager.services;
|
const { hangingProtocolService } = servicesManager.services;
|
||||||
hangingProtocolService.addCustomAttribute(
|
|
||||||
'seriesDescriptions',
|
|
||||||
'Series Descriptions',
|
|
||||||
seriesDescriptionsFromDisplaySets
|
|
||||||
);
|
|
||||||
hangingProtocolService.addCustomAttribute(
|
hangingProtocolService.addCustomAttribute(
|
||||||
'numberOfDisplaySets',
|
'numberOfDisplaySets',
|
||||||
'Number of displays sets',
|
'Number of displays sets',
|
||||||
numberOfDisplaySets
|
numberOfDisplaySets
|
||||||
);
|
);
|
||||||
hangingProtocolService.addCustomAttribute(
|
|
||||||
'numberOfDisplaySetsWithImages',
|
|
||||||
'Number of displays sets with images',
|
|
||||||
numberOfDisplaySetsWithImages
|
|
||||||
);
|
|
||||||
hangingProtocolService.addCustomAttribute(
|
hangingProtocolService.addCustomAttribute(
|
||||||
'maxNumImageFrames',
|
'maxNumImageFrames',
|
||||||
'Maximum of number of image frames',
|
'Maximum of number of image frames',
|
||||||
@ -58,9 +45,6 @@ const testExtension: Types.Extensions.Extension = {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Registers some additional hanging protocols. See hp/index.tsx for more details */
|
|
||||||
getHangingProtocolModule,
|
|
||||||
|
|
||||||
/** Registers some customizations */
|
/** Registers some customizations */
|
||||||
getCustomizationModule,
|
getCustomizationModule,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -357,7 +357,7 @@ const toolbarButtons = [
|
|||||||
{
|
{
|
||||||
commandName: 'setHangingProtocol',
|
commandName: 'setHangingProtocol',
|
||||||
commandOptions: {
|
commandOptions: {
|
||||||
protocolId: '@ohif/hp-extension.mn',
|
protocolId: '@ohif/mnGrid',
|
||||||
stageId: '2x2',
|
stageId: '2x2',
|
||||||
},
|
},
|
||||||
context: 'DEFAULT',
|
context: 'DEFAULT',
|
||||||
@ -372,7 +372,7 @@ const toolbarButtons = [
|
|||||||
{
|
{
|
||||||
commandName: 'setHangingProtocol',
|
commandName: 'setHangingProtocol',
|
||||||
commandOptions: {
|
commandOptions: {
|
||||||
protocolId: '@ohif/hp-extension.mn',
|
protocolId: '@ohif/mnGrid',
|
||||||
stageId: '3x1',
|
stageId: '3x1',
|
||||||
},
|
},
|
||||||
context: 'DEFAULT',
|
context: 'DEFAULT',
|
||||||
@ -387,7 +387,7 @@ const toolbarButtons = [
|
|||||||
{
|
{
|
||||||
commandName: 'setHangingProtocol',
|
commandName: 'setHangingProtocol',
|
||||||
commandOptions: {
|
commandOptions: {
|
||||||
protocolId: '@ohif/hp-extension.mn',
|
protocolId: '@ohif/mnGrid',
|
||||||
stageId: '2x1',
|
stageId: '2x1',
|
||||||
},
|
},
|
||||||
context: 'DEFAULT',
|
context: 'DEFAULT',
|
||||||
@ -402,7 +402,7 @@ const toolbarButtons = [
|
|||||||
{
|
{
|
||||||
commandName: 'setHangingProtocol',
|
commandName: 'setHangingProtocol',
|
||||||
commandOptions: {
|
commandOptions: {
|
||||||
protocolId: '@ohif/hp-extension.mn',
|
protocolId: '@ohif/mnGrid',
|
||||||
stageId: '1x1',
|
stageId: '1x1',
|
||||||
},
|
},
|
||||||
context: 'DEFAULT',
|
context: 'DEFAULT',
|
||||||
|
|||||||
@ -9,7 +9,9 @@ import * as HangingProtocol from '../../types/HangingProtocol';
|
|||||||
import {
|
import {
|
||||||
isDisplaySetFromUrl,
|
isDisplaySetFromUrl,
|
||||||
sopInstanceLocation,
|
sopInstanceLocation,
|
||||||
} from './isDisplaySetFromUrl';
|
} from './custom-attribute/isDisplaySetFromUrl';
|
||||||
|
import numberOfDisplaySetsWithImages from './custom-attribute/numberOfDisplaySetsWithImages';
|
||||||
|
import seriesDescriptionsFromDisplaySets from './custom-attribute/seriesDescriptionsFromDisplaySets';
|
||||||
|
|
||||||
type Protocol = HangingProtocol.Protocol | HangingProtocol.ProtocolGenerator;
|
type Protocol = HangingProtocol.Protocol | HangingProtocol.ProtocolGenerator;
|
||||||
|
|
||||||
@ -93,6 +95,16 @@ export default class HangingProtocolService extends PubSubService {
|
|||||||
name: 'Gets the position of the specified sop instance',
|
name: 'Gets the position of the specified sop instance',
|
||||||
callback: sopInstanceLocation,
|
callback: sopInstanceLocation,
|
||||||
},
|
},
|
||||||
|
seriesDescriptions: {
|
||||||
|
name: 'seriesDescriptions',
|
||||||
|
description: 'List of Series Descriptions',
|
||||||
|
callback: seriesDescriptionsFromDisplaySets,
|
||||||
|
},
|
||||||
|
numberOfDisplaySetsWithImages: {
|
||||||
|
name: 'numberOfDisplaySetsWithImages',
|
||||||
|
desription: 'Number of displays sets with images',
|
||||||
|
numberOfDisplaySetsWithImages,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
listeners = {};
|
listeners = {};
|
||||||
registeredImageLoadStrategies = {};
|
registeredImageLoadStrategies = {};
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { getSplitParam } from '../../utils';
|
import { getSplitParam } from '../../../utils';
|
||||||
|
|
||||||
/** Indicates if the given display set is the one specified in the
|
/** Indicates if the given display set is the one specified in the
|
||||||
* displaySet parameter in the URL
|
* displaySet parameter in the URL
|
||||||
@ -31,7 +31,7 @@ const isDisplaySetFromUrl = (displaySet): boolean => {
|
|||||||
* Returns undefined to fallback to the defaultValue
|
* Returns undefined to fallback to the defaultValue
|
||||||
*/
|
*/
|
||||||
function sopInstanceLocation(displaySets) {
|
function sopInstanceLocation(displaySets) {
|
||||||
const displaySet = displaySets[0];
|
const displaySet = displaySets?.[0];
|
||||||
if (!displaySet) return;
|
if (!displaySet) return;
|
||||||
const initialSOPInstanceUID = getSplitParam('initialsopinstanceuid');
|
const initialSOPInstanceUID = getSplitParam('initialsopinstanceuid');
|
||||||
if (!initialSOPInstanceUID) return;
|
if (!initialSOPInstanceUID) return;
|
||||||
@ -2,7 +2,7 @@ describe('OHIF HP', () => {
|
|||||||
const beforeSetup = () => {
|
const beforeSetup = () => {
|
||||||
cy.checkStudyRouteInViewer(
|
cy.checkStudyRouteInViewer(
|
||||||
'1.3.6.1.4.1.25403.345050719074.3824.20170125113417.1',
|
'1.3.6.1.4.1.25403.345050719074.3824.20170125113417.1',
|
||||||
'&hangingProtocolId=@ohif/hp-extension.mn'
|
'&hangingProtocolId=@ohif/mnGrid'
|
||||||
);
|
);
|
||||||
cy.expectMinimumThumbnails(3);
|
cy.expectMinimumThumbnails(3);
|
||||||
cy.initCornerstoneToolsAliases();
|
cy.initCornerstoneToolsAliases();
|
||||||
|
|||||||
@ -2,7 +2,7 @@ describe('OHIF Double Click', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.checkStudyRouteInViewer(
|
cy.checkStudyRouteInViewer(
|
||||||
'1.3.6.1.4.1.25403.345050719074.3824.20170125113417.1',
|
'1.3.6.1.4.1.25403.345050719074.3824.20170125113417.1',
|
||||||
'&hangingProtocolId=@ohif/hp-extension.mn'
|
'&hangingProtocolId=@ohif/mnGrid'
|
||||||
);
|
);
|
||||||
cy.expectMinimumThumbnails(3);
|
cy.expectMinimumThumbnails(3);
|
||||||
cy.initCornerstoneToolsAliases();
|
cy.initCornerstoneToolsAliases();
|
||||||
|
|||||||
@ -14,7 +14,7 @@ window.config = {
|
|||||||
{
|
{
|
||||||
friendlyName: 'StaticWado test data',
|
friendlyName: 'StaticWado test data',
|
||||||
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
||||||
sourceName: 'dicomweb',
|
sourceName: 'e2e',
|
||||||
configuration: {
|
configuration: {
|
||||||
// The most important field to set for static WADO
|
// The most important field to set for static WADO
|
||||||
staticWado: true,
|
staticWado: true,
|
||||||
@ -32,6 +32,51 @@ window.config = {
|
|||||||
singlepart: 'video,thumbnail,pdf',
|
singlepart: 'video,thumbnail,pdf',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
friendlyName: 'Static WADO Local Data',
|
||||||
|
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
||||||
|
sourceName: 'local',
|
||||||
|
configuration: {
|
||||||
|
name: 'DCM4CHEE',
|
||||||
|
qidoRoot: '/dicomweb',
|
||||||
|
wadoRoot: '/dicomweb',
|
||||||
|
qidoSupportsIncludeField: false,
|
||||||
|
supportsReject: true,
|
||||||
|
supportsStow: true,
|
||||||
|
imageRendering: 'wadors',
|
||||||
|
thumbnailRendering: 'wadors',
|
||||||
|
enableStudyLazyLoad: true,
|
||||||
|
supportsFuzzyMatching: false,
|
||||||
|
supportsWildcard: true,
|
||||||
|
staticWado: true,
|
||||||
|
singlepart: 'bulkdata,video,pdf',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
friendlyName: 'dcmjs DICOMWeb Server',
|
||||||
|
namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
||||||
|
sourceName: 'ohif',
|
||||||
|
configuration: {
|
||||||
|
name: 'aws',
|
||||||
|
// old server
|
||||||
|
// wadoUriRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/wado',
|
||||||
|
// qidoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||||
|
// wadoRoot: 'https://server.dcmjs.org/dcm4chee-arc/aets/DCM4CHEE/rs',
|
||||||
|
// new server
|
||||||
|
wadoUriRoot: 'https://domvja9iplmyu.cloudfront.net/dicomweb',
|
||||||
|
qidoRoot: 'https://domvja9iplmyu.cloudfront.net/dicomweb',
|
||||||
|
wadoRoot: 'https://domvja9iplmyu.cloudfront.net/dicomweb',
|
||||||
|
qidoSupportsIncludeField: false,
|
||||||
|
supportsReject: false,
|
||||||
|
imageRendering: 'wadors',
|
||||||
|
thumbnailRendering: 'wadors',
|
||||||
|
enableStudyLazyLoad: true,
|
||||||
|
supportsFuzzyMatching: false,
|
||||||
|
supportsWildcard: true,
|
||||||
|
staticWado: true,
|
||||||
|
singlepart: 'bulkdata,video,pdf',
|
||||||
|
},
|
||||||
|
},
|
||||||
// {
|
// {
|
||||||
// friendlyName: 'StaticWado default data',
|
// friendlyName: 'StaticWado default data',
|
||||||
// namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
// namespace: '@ohif/extension-default.dataSourcesModule.dicomweb',
|
||||||
@ -92,93 +137,6 @@ window.config = {
|
|||||||
// ))
|
// ))
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
defaultDataSourceName: 'dicomweb',
|
defaultDataSourceName: 'e2e',
|
||||||
hotkeys: [
|
hotkeys: [],
|
||||||
{
|
|
||||||
commandName: 'incrementActiveViewport',
|
|
||||||
label: 'Next Viewport',
|
|
||||||
keys: ['right'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'decrementActiveViewport',
|
|
||||||
label: 'Previous Viewport',
|
|
||||||
keys: ['left'],
|
|
||||||
},
|
|
||||||
{ commandName: 'rotateViewportCW', label: 'Rotate Right', keys: ['r'] },
|
|
||||||
{ commandName: 'rotateViewportCCW', label: 'Rotate Left', keys: ['l'] },
|
|
||||||
{ commandName: 'invertViewport', label: 'Invert', keys: ['i'] },
|
|
||||||
{
|
|
||||||
commandName: 'flipViewportHorizontal',
|
|
||||||
label: 'Flip Horizontally',
|
|
||||||
keys: ['h'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'flipViewportVertical',
|
|
||||||
label: 'Flip Vertically',
|
|
||||||
keys: ['v'],
|
|
||||||
},
|
|
||||||
{ commandName: 'scaleUpViewport', label: 'Zoom In', keys: ['+'] },
|
|
||||||
{ commandName: 'scaleDownViewport', label: 'Zoom Out', keys: ['-'] },
|
|
||||||
{ commandName: 'fitViewportToWindow', label: 'Zoom to Fit', keys: ['='] },
|
|
||||||
{ commandName: 'resetViewport', label: 'Reset', keys: ['space'] },
|
|
||||||
{ commandName: 'nextImage', label: 'Next Image', keys: ['down'] },
|
|
||||||
{ commandName: 'previousImage', label: 'Previous Image', keys: ['up'] },
|
|
||||||
// {
|
|
||||||
// commandName: 'previousViewportDisplaySet',
|
|
||||||
// label: 'Previous Series',
|
|
||||||
// keys: ['pagedown'],
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// commandName: 'nextViewportDisplaySet',
|
|
||||||
// label: 'Next Series',
|
|
||||||
// keys: ['pageup'],
|
|
||||||
// },
|
|
||||||
{ commandName: 'setZoomTool', label: 'Zoom', keys: ['z'] },
|
|
||||||
// ~ Window level presets
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset1',
|
|
||||||
label: 'W/L Preset 1',
|
|
||||||
keys: ['1'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset2',
|
|
||||||
label: 'W/L Preset 2',
|
|
||||||
keys: ['2'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset3',
|
|
||||||
label: 'W/L Preset 3',
|
|
||||||
keys: ['3'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset4',
|
|
||||||
label: 'W/L Preset 4',
|
|
||||||
keys: ['4'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset5',
|
|
||||||
label: 'W/L Preset 5',
|
|
||||||
keys: ['5'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset6',
|
|
||||||
label: 'W/L Preset 6',
|
|
||||||
keys: ['6'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset7',
|
|
||||||
label: 'W/L Preset 7',
|
|
||||||
keys: ['7'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset8',
|
|
||||||
label: 'W/L Preset 8',
|
|
||||||
keys: ['8'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
commandName: 'windowLevelPreset9',
|
|
||||||
label: 'W/L Preset 9',
|
|
||||||
keys: ['9'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user