diff --git a/extensions/cornerstone/src/getHangingProtocolModule.ts b/extensions/cornerstone/src/getHangingProtocolModule.ts index 6a1fc8a1c0a..d04024f2eb1 100644 --- a/extensions/cornerstone/src/getHangingProtocolModule.ts +++ b/extensions/cornerstone/src/getHangingProtocolModule.ts @@ -6,6 +6,7 @@ import { only3D } from './hps/only3D'; import { primary3D } from './hps/primary3D'; import { primaryAxial } from './hps/primaryAxial'; import { frameView } from './hps/frameView'; +import { mgCC, mgMLO } from './hps/mammo'; function getHangingProtocolModule() { return [ @@ -41,6 +42,14 @@ function getHangingProtocolModule() { name: frameView.id, protocol: frameView, }, + { + name: mgCC.id, + protocol: mgCC, + }, + { + name: mgMLO.id, + protocol: mgMLO, + }, ]; } diff --git a/extensions/cornerstone/src/hps/mammo.ts b/extensions/cornerstone/src/hps/mammo.ts new file mode 100644 index 00000000000..b2b140a80fe --- /dev/null +++ b/extensions/cornerstone/src/hps/mammo.ts @@ -0,0 +1,57 @@ +export const mgCC = { + id: 'mgCC', + name: 'mammo-cc', + imageLoadStrategy: 'interleaveTopToBottom', + protocolMatchingRules: [ + { attribute: 'ModalitiesInStudy', constraint: { contains: ['MG', 'DX'] } }, + ], + displaySetSelectors: { + isRCC: { + seriesMatchingRules: [ + { weight: 1, attribute: 'isRCC', constraint: { equals: { value: true } } }, + ], + }, + isLCC: { + seriesMatchingRules: [ + { weight: 1, attribute: 'isLCC', constraint: { equals: { value: true } } }, + ], + }, + }, + stages: [ + { + name: 'default', + viewportStructure: { layoutType: 'grid', properties: { rows: 1, columns: 2 } }, + viewports: [{ displaySets: [{ id: 'isRCC' }] }, { displaySets: [{ id: 'isLCC' }] }], + }, + ], + numberOfPriorsReferenced: -1, +}; + +export const mgMLO = { + id: 'mgMLO', + name: 'mammo-mlo', + imageLoadStrategy: 'interleaveTopToBottom', + protocolMatchingRules: [ + { attribute: 'ModalitiesInStudy', constraint: { contains: ['MG', 'DX'] } }, + ], + displaySetSelectors: { + isRMLO: { + seriesMatchingRules: [ + { weight: 1, attribute: 'isRMLO', constraint: { equals: { value: true } } }, + ], + }, + isLMLO: { + seriesMatchingRules: [ + { weight: 1, attribute: 'isLMLO', constraint: { equals: { value: true } } }, + ], + }, + }, + stages: [ + { + name: 'default', + viewportStructure: { layoutType: 'grid', properties: { rows: 1, columns: 2 } }, + viewports: [{ displaySets: [{ id: 'isRMLO' }] }, { displaySets: [{ id: 'isLMLO' }] }], + }, + ], + numberOfPriorsReferenced: -1, +}; diff --git a/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts b/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts index 929f31100cb..0118b0d71f3 100644 --- a/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts +++ b/platform/core/src/services/HangingProtocolService/HangingProtocolService.ts @@ -10,6 +10,7 @@ import * as HangingProtocol from '../../types/HangingProtocol'; import { isDisplaySetFromUrl, sopInstanceLocation } from './custom-attribute/isDisplaySetFromUrl'; import numberOfDisplaySetsWithImages from './custom-attribute/numberOfDisplaySetsWithImages'; import seriesDescriptionsFromDisplaySets from './custom-attribute/seriesDescriptionsFromDisplaySets'; +import isMammoPos from './custom-attribute/isMammoPos'; import uuidv4 from '../../utils/uuidv4'; type Protocol = HangingProtocol.Protocol | HangingProtocol.ProtocolGenerator; @@ -110,6 +111,22 @@ export default class HangingProtocolService extends PubSubService { description: 'Number of displays sets with images', callback: numberOfDisplaySetsWithImages, }, + isRCC: { + name: 'is rcc', + callback: displaySet => isMammoPos(displaySet, 'R', 'CC'), + }, + isLCC: { + name: 'is lcc', + callback: displaySet => isMammoPos(displaySet, 'L', 'CC'), + }, + isRMLO: { + name: 'is rmlo', + callback: displaySet => isMammoPos(displaySet, 'R', 'MLO'), + }, + isLMLO: { + name: 'is lmlo', + callback: displaySet => isMammoPos(displaySet, 'L', 'MLO'), + }, }; listeners = {}; registeredImageLoadStrategies = {}; diff --git a/platform/core/src/services/HangingProtocolService/custom-attribute/isMammoPos.ts b/platform/core/src/services/HangingProtocolService/custom-attribute/isMammoPos.ts new file mode 100644 index 00000000000..7f6de2687d1 --- /dev/null +++ b/platform/core/src/services/HangingProtocolService/custom-attribute/isMammoPos.ts @@ -0,0 +1,15 @@ +export default function isMammoPos(displaySet: any, pos: 'R' | 'L', type: 'CC' | 'MLO') { + const instanceTags = displaySet.instances[0]; + const viewCode = instanceTags.ViewCodeSequence?.[0]?.CodeValue; + const laterality = + instanceTags.ImageLaterality || + instanceTags.Laterality || + instanceTags.SharedFunctionalGroupsSequence?.[0]?.FrameAnatomySequence?.[0]?.FrameLaterality; + + const typeToCodeMap = { + CC: 'R-10242', + MLO: 'R-10226', + }; + + return laterality === pos && viewCode === typeToCodeMap[type]; +}