diff --git a/extensions/cornerstone/jest.config.js b/extensions/cornerstone/jest.config.js index 2978b062ed1..9e0ecb3e4ec 100644 --- a/extensions/cornerstone/jest.config.js +++ b/extensions/cornerstone/jest.config.js @@ -5,6 +5,11 @@ module.exports = { ...base, name: pkg.name, displayName: pkg.name, + moduleNameMapper: { + ...base.moduleNameMapper, + '^@ohif/(.*)$': '/../../platform/$1/src', + '^@cornerstonejs/tools(.*)$': '/../../node_modules/@cornerstonejs/tools', + }, // rootDir: "../.." // testMatch: [ // //`/platform/${pack.name}/**/*.spec.js` diff --git a/extensions/cornerstone/src/commandsModule.ts b/extensions/cornerstone/src/commandsModule.ts index 5da90b32990..44cc430a2ab 100644 --- a/extensions/cornerstone/src/commandsModule.ts +++ b/extensions/cornerstone/src/commandsModule.ts @@ -5,6 +5,7 @@ import { utilities as csUtils, Types as CoreTypes, BaseVolumeViewport, + metaData, } from '@cornerstonejs/core'; import { ToolGroupManager, @@ -21,6 +22,7 @@ import toggleStackImageSync from './utils/stackSync/toggleStackImageSync'; import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/utils/selection'; import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement'; import { CornerstoneServices } from './types'; +import { getImageFlips } from './utils/getImageFlips'; function commandsModule({ servicesManager, @@ -35,6 +37,7 @@ function commandsModule({ cornerstoneViewportService, uiNotificationService, measurementService, + customizationService, } = servicesManager.services as CornerstoneServices; const { measurementServiceSource } = this; @@ -483,6 +486,16 @@ function commandsModule({ viewport.resetProperties?.(); viewport.resetCamera(); + const { criteria: isOrientationCorrectionNeeded } = customizationService.get( + 'orientationCorrectionCriterion' + ); + const instance = metaData.get('instance', viewport.getCurrentImageId()); + + if ((isOrientationCorrectionNeeded as (input) => boolean)?.(instance)) { + const { hFlip, vFlip } = getImageFlips(instance); + (hFlip || vFlip) && viewport.setCamera({ flipHorizontal: hFlip, flipVertical: vFlip }); + } + viewport.render(); }, scaleViewport: ({ direction }) => { diff --git a/extensions/cornerstone/src/getCustomizationModule.ts b/extensions/cornerstone/src/getCustomizationModule.ts index acb06424462..9d22282e261 100644 --- a/extensions/cornerstone/src/getCustomizationModule.ts +++ b/extensions/cornerstone/src/getCustomizationModule.ts @@ -1,6 +1,7 @@ import { Enums } from '@cornerstonejs/tools'; import { toolNames } from './initCornerstoneTools'; import DicomUpload from './components/DicomUpload/DicomUpload'; +import isOrientationCorrectionNeeded from './utils/isOrientationCorrectionNeeded'; const tools = { active: [ @@ -37,6 +38,8 @@ function getCustomizationModule() { id: 'cornerstone.overlayViewportTools', tools, }, + // TODO: Move this customization to MG specific mode when introduced in OHIF. + { id: 'orientationCorrectionCriterion', criteria: isOrientationCorrectionNeeded }, ], }, ]; diff --git a/extensions/cornerstone/src/index.tsx b/extensions/cornerstone/src/index.tsx index ac53c8f0f27..531e979f67a 100644 --- a/extensions/cornerstone/src/index.tsx +++ b/extensions/cornerstone/src/index.tsx @@ -30,6 +30,7 @@ import * as csWADOImageLoader from './initWADOImageLoader.js'; import { measurementMappingUtils } from './utils/measurementServiceMappings'; import type { PublicViewportOptions } from './services/ViewportService/Viewport'; import ImageOverlayViewerTool from './tools/ImageOverlayViewerTool'; +import { getImageFlips } from './utils/getImageFlips'; const Component = React.lazy(() => { return import(/* webpackPrefetch: true */ './Viewport/OHIFCornerstoneViewport'); @@ -116,6 +117,7 @@ const cornerstoneExtension: Types.Extensions.Extension = { }, getEnabledElement, dicomLoaderService, + getImageFlips, }, }, { diff --git a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts index 1180d8036f5..4882ca743cd 100644 --- a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts +++ b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts @@ -10,8 +10,9 @@ import { VolumeViewport3D, cache, Enums as csEnums, + metaData, + eventTarget, } from '@cornerstonejs/core'; - import { utilities as csToolsUtils, Enums as csToolsEnums } from '@cornerstonejs/tools'; import { IViewportService } from './IViewportService'; import { RENDERING_ENGINE_ID } from './constants'; @@ -20,6 +21,7 @@ import { StackViewportData, VolumeViewportData } from '../../types/CornerstoneCa import { Presentation, Presentations } from '../../types/Presentation'; import JumpPresets from '../../utils/JumpPresets'; +import { getImageFlips } from '../../utils/getImageFlips'; const EVENTS = { VIEWPORT_DATA_CHANGED: 'event::cornerstoneViewportService:viewportDataChanged', @@ -325,6 +327,8 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi viewportInfo: ViewportInfo, presentations: Presentations ): Promise { + const { segmentationService, displaySetService, customizationService } = + this.servicesManager.services; const displaySetOptions = viewportInfo.getDisplaySetOptions(); const { imageIds, initialImageIndex, displaySetInstanceUID } = viewportData.data; @@ -354,24 +358,48 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi } } - const segmentations = this.servicesManager.services.segmentationService.getSegmentations(false); + const { criteria: isOrientationCorrectionNeeded } = customizationService.get( + 'orientationCorrectionCriterion' + ); + const instance = metaData.get('instance', imageIds[initialImageIndexToUse]); + + let hFlip = false, + vFlip = false; + if ((isOrientationCorrectionNeeded as (input) => boolean)?.(instance)) { + ({ hFlip, vFlip } = getImageFlips(instance)); + } + + const segmentations = segmentationService.getSegmentations(false); const toolgroupId = viewportInfo.getToolGroupId(); for (const segmentation of segmentations) { const toolGroupSegmentationRepresentations = - this.servicesManager.services.segmentationService.getSegmentationRepresentationsForToolGroup( - toolgroupId - ) || []; + segmentationService.getSegmentationRepresentationsForToolGroup(toolgroupId) || []; const isSegmentationInToolGroup = toolGroupSegmentationRepresentations.find( representation => representation.segmentationId === segmentation.id ); + const callback = evt => { + if (viewport.id !== evt.detail.viewportId) { + return; + } + + eventTarget.removeEventListener(csEnums.Events.STACK_VIEWPORT_IMAGES_ADDED, callback); + + const camera = presentations.positionPresentation?.camera; + if (isSegmentationInToolGroup && camera) { + viewport.setCamera(camera); + } else { + (hFlip || vFlip) && viewport.setCamera({ flipHorizontal: hFlip, flipVertical: vFlip }); + } + }; + + eventTarget.addEventListener(csEnums.Events.STACK_VIEWPORT_IMAGES_ADDED, callback); + if (!isSegmentationInToolGroup) { - const segDisplaySet = this.servicesManager.services.displaySetService.getDisplaySetByUID( - segmentation.id - ); + const segDisplaySet = displaySetService.getDisplaySetByUID(segmentation.id); segDisplaySet && - this.servicesManager.services.segmentationService.addSegmentationRepresentationToToolGroup( + segmentationService.addSegmentationRepresentationToToolGroup( toolgroupId, segmentation.id, segDisplaySet.isOverlayDisplaySet @@ -382,6 +410,11 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi return viewport.setStack(imageIds, initialImageIndexToUse).then(() => { viewport.setProperties({ ...properties }); const camera = presentations.positionPresentation?.camera; + + !camera && + (hFlip || vFlip) && + viewport.setCamera({ flipHorizontal: hFlip, flipVertical: vFlip }); + if (camera) { viewport.setCamera(camera); } diff --git a/extensions/cornerstone/src/utils/getImageFlips.test.js b/extensions/cornerstone/src/utils/getImageFlips.test.js new file mode 100644 index 00000000000..7f29b867cfa --- /dev/null +++ b/extensions/cornerstone/src/utils/getImageFlips.test.js @@ -0,0 +1,159 @@ +import { getImageFlips } from './getImageFlips'; + +const orientationDirectionVectorMap = { + L: [1, 0, 0], // Left + R: [-1, 0, 0], // Right + P: [0, 1, 0], // Posterior/ Back + A: [0, -1, 0], // Anterior/ Front + H: [0, 0, 1], // Head/ Superior + F: [0, 0, -1], // Feet/ Inferior +}; + +const getDirectionsFromPatientOrientation = patientOrientation => { + if (typeof patientOrientation === 'string') { + patientOrientation = patientOrientation.split('\\'); + } + + return { + rowDirection: patientOrientation[0], + columnDirection: patientOrientation[1][0], + }; +}; + +const getOrientationStringLPS = vector => { + const sampleVectorDirectionMap = { + '1,0,0': 'L', + '-1,0,0': 'R', + '0,1,0': 'P', + '0,-1,0': 'A', + '0,0,1': 'H', + '0,0,-1': 'F', + }; + + return sampleVectorDirectionMap[vector.toString()]; +}; + +jest.mock('@cornerstonejs/tools ', () => ({ + utilities: { orientation: { getOrientationStringLPS } }, +})); +jest.mock('@ohif/core', () => ({ + defaults: { orientationDirectionVectorMap }, + utils: { getDirectionsFromPatientOrientation }, +})); + +describe('getImageFlips', () => { + test('should return empty object if none of the parameters are provided', () => { + const flipsNeeded = getImageFlips({}); + expect(flipsNeeded).toEqual({}); + }); + + test('should return empty object if ImageOrientationPatient and PatientOrientation is not provided', () => { + const ImageLaterality = 'L'; + const flipsNeeded = getImageFlips({ + ImageLaterality, + }); + expect(flipsNeeded).toEqual({}); + }); + + test('should return empty object if ImageLaterality is not privided', () => { + const ImageOrientationPatient = [0, 1, 0, 0, 0, 1], + PatientOrientation = ['P', 'H']; + const flipsNeeded = getImageFlips({ + ImageOrientationPatient, + PatientOrientation, + }); + expect(flipsNeeded).toEqual({}); + }); + + test('should return { hFlip: false, vFlip: false } if ImageOrientationPatient is [0, 1, 0, 0, 0, -1] and ImageLaterality is R', () => { + const ImageOrientationPatient = [0, 1, 0, 0, 0, -1], + PatientOrientation = ['P', 'F'], + ImageLaterality = 'R'; + const flipsNeeded = getImageFlips({ + ImageOrientationPatient, + PatientOrientation, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({ hFlip: false, vFlip: false }); + }); + + test('should return { hFlip: false, vFlip: true } if ImageOrientationPatient is [0, -1, 0, 0, 0, 1] and ImageLaterality is L', () => { + const ImageOrientationPatient = [0, -1, 0, 0, 0, 1], + ImageLaterality = 'L'; + const flipsNeeded = getImageFlips({ + ImageOrientationPatient, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({ hFlip: false, vFlip: true }); + }); + + test('should return { hFlip: true, vFlip: true } if ImageOrientationPatient is [0, -1, 0, -1, 0, 0] and ImageLaterality is R', () => { + const ImageOrientationPatient = [0, -1, 0, -1, 0, 0], + ImageLaterality = 'R'; + const flipsNeeded = getImageFlips({ + ImageOrientationPatient, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({ hFlip: true, vFlip: true }); + }); + + test("should return { hFlip: true, vFlip: true } if ImageOrientationPatient is not present, PatientOrientation is ['P', 'H'] and ImageLaterality is L", () => { + const PatientOrientation = ['P', 'H'], + ImageLaterality = 'L'; + const flipsNeeded = getImageFlips({ + PatientOrientation, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({ hFlip: true, vFlip: true }); + }); + + test("should return { hFlip: true, vFlip: false } if ImageOrientationPatient is not present, PatientOrientation is ['A', 'F'] and ImageLaterality is R", () => { + const PatientOrientation = ['A', 'F'], + ImageLaterality = 'R'; + const flipsNeeded = getImageFlips({ + PatientOrientation, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({ hFlip: true, vFlip: false }); + }); + + test("should return { hFlip: true, vFlip: false } if ImageOrientationPatient is not present, PatientOrientation is ['A', 'FL'] and ImageLaterality is R", () => { + const PatientOrientation = ['A', 'FL'], + ImageLaterality = 'R'; + const flipsNeeded = getImageFlips({ + PatientOrientation, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({ hFlip: true, vFlip: false }); + }); + + test("should return { hFlip: true, vFlip: false } if ImageOrientationPatient ans ImageLaterality is not present, PatientOrientation is ['P', 'FL'] and FrameLaterality is L", () => { + const PatientOrientation = ['P', 'FL'], + FrameLaterality = 'L'; + const flipsNeeded = getImageFlips({ + PatientOrientation, + FrameLaterality, + }); + expect(flipsNeeded).toEqual({ hFlip: true, vFlip: false }); + }); + + test("should return empty object if ImageOrientationPatient is not present, PatientOrientation is ['H', 'R'] and ImageLaterality is R since the orientation is rotated, not flipped", () => { + const PatientOrientation = ['H', 'R'], + ImageLaterality = 'R'; + const flipsNeeded = getImageFlips({ + PatientOrientation, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({}); + }); + + test("should return empty object if ImageOrientationPatient is not present, PatientOrientation is ['F', 'L'] and ImageLaterality is L since the orientation is rotated, not flipped", () => { + const PatientOrientation = ['F', 'L'], + ImageLaterality = 'L'; + const flipsNeeded = getImageFlips({ + PatientOrientation, + ImageLaterality, + }); + expect(flipsNeeded).toEqual({}); + }); +}); diff --git a/extensions/cornerstone/src/utils/getImageFlips.ts b/extensions/cornerstone/src/utils/getImageFlips.ts new file mode 100644 index 00000000000..bbe95a5b0e2 --- /dev/null +++ b/extensions/cornerstone/src/utils/getImageFlips.ts @@ -0,0 +1,123 @@ +import { defaults, utils } from '@ohif/core'; +import { utilities } from '@cornerstonejs/tools'; +import { vec3 } from 'gl-matrix'; + +const { orientationDirectionVectorMap } = defaults; +const { getOrientationStringLPS } = utilities.orientation; + +type IOP = [number, number, number, number, number, number]; +type PO = [string, string] | string; +type IL = string; +type FL = string; +type Instance = { + ImageOrientationPatient?: IOP; + PatientOrientation?: PO; + ImageLaterality?: IL; + FrameLaterality?: FL; +}; + +/** + * A function to get required flipping to correct the image according to Orientation and Laterality. + * This function does not handle rotated images. + * @param instance Metadata instance of the image. + * @returns vertical and horizontal flipping needed to correct the image if possible. + */ +export function getImageFlips(instance: Instance): { vFlip?: boolean; hFlip?: boolean } { + const { ImageOrientationPatient, PatientOrientation, ImageLaterality, FrameLaterality } = + instance; + + if (!(ImageOrientationPatient || PatientOrientation) || !(ImageLaterality || FrameLaterality)) { + console.warn( + 'Skipping image orientation correction due to missing ImageOrientationPatient/ PatientOrientation or/and ImageLaterality/ FrameLaterality' + ); + return {}; + } + + let rowDirectionCurrent, columnDirectionCurrent, rowCosines, columnCosines; + if (ImageOrientationPatient) { + rowCosines = ImageOrientationPatient.slice(0, 3); + columnCosines = ImageOrientationPatient.slice(3, 6); + rowDirectionCurrent = getOrientationStringLPS(rowCosines); + columnDirectionCurrent = getOrientationStringLPS(columnCosines)[0]; + } else { + ({ rowDirection: rowDirectionCurrent, columnDirection: columnDirectionCurrent } = + utils.getDirectionsFromPatientOrientation(PatientOrientation)); + + rowCosines = orientationDirectionVectorMap[rowDirectionCurrent]; + columnCosines = orientationDirectionVectorMap[columnDirectionCurrent]; + } + + const scanAxisNormal = vec3.create(); + vec3.cross(scanAxisNormal, rowCosines, columnCosines); + + const scanAxisDirection = getOrientationStringLPS(scanAxisNormal as [number, number, number]); + + if (isImageRotated(rowDirectionCurrent, columnDirectionCurrent)) { + // TODO: Correcting images with rotation is not implemented. + console.warn('Correcting images by rotating is not implemented'); + return {}; + } + + let rowDirectionTarget, columnDirectionTarget; + switch (scanAxisDirection[0]) { + // Sagittal + case 'L': + case 'R': + if ((ImageLaterality || FrameLaterality) === 'L') { + rowDirectionTarget = 'A'; + } else { + rowDirectionTarget = 'P'; + } + columnDirectionTarget = 'F'; + break; + // Coronal + case 'A': + case 'P': + if ((ImageLaterality || FrameLaterality) === 'L') { + rowDirectionTarget = 'R'; + } else { + rowDirectionTarget = 'L'; + } + columnDirectionTarget = 'F'; + break; + // Axial + case 'H': + case 'F': + if ((ImageLaterality || FrameLaterality) === 'L') { + rowDirectionTarget = 'A'; + columnDirectionTarget = 'R'; + } else { + rowDirectionTarget = 'P'; + columnDirectionTarget = 'L'; + } + break; + } + + let hFlip = false, + vFlip = false; + if (rowDirectionCurrent !== rowDirectionTarget) { + hFlip = true; + } + if (columnDirectionCurrent !== columnDirectionTarget) { + vFlip = true; + } + + return { hFlip, vFlip }; +} + +function isImageRotated(rowDirection: string, columnDirection: string): boolean { + const possibleValues: { [key: string]: [string, string] } = { + xDirection: ['L', 'R'], + yDirection: ['P', 'A'], + zDirection: ['H', 'F'], + }; + + if ( + possibleValues.yDirection.includes(columnDirection) || + possibleValues.zDirection.includes(rowDirection) + ) { + return true; + } + + return false; +} diff --git a/extensions/cornerstone/src/utils/isOrientationCorrectionNeeded.ts b/extensions/cornerstone/src/utils/isOrientationCorrectionNeeded.ts new file mode 100644 index 00000000000..83e24545231 --- /dev/null +++ b/extensions/cornerstone/src/utils/isOrientationCorrectionNeeded.ts @@ -0,0 +1,10 @@ +const DEFAULT_AUTO_FLIP_MODALITIES: string[] = ['MG']; + +export default function isOrientationCorrectionNeeded(instance) { + const { Modality } = instance; + + // Check Modality + const isModalityIncluded = DEFAULT_AUTO_FLIP_MODALITIES.includes(Modality); + + return isModalityIncluded; +} diff --git a/platform/core/src/classes/MetadataProvider.ts b/platform/core/src/classes/MetadataProvider.ts index de12ff4e33c..4c52d80198f 100644 --- a/platform/core/src/classes/MetadataProvider.ts +++ b/platform/core/src/classes/MetadataProvider.ts @@ -6,6 +6,7 @@ import DicomMetadataStore from '../services/DicomMetadataStore'; import fetchPaletteColorLookupTableData from '../utils/metadataProvider/fetchPaletteColorLookupTableData'; import toNumber from '../utils/toNumber'; import combineFrameInstance from '../utils/combineFrameInstance'; +import { orientationDirectionVectorMap } from '../defaults'; class MetadataProvider { constructor() { @@ -494,7 +495,7 @@ export default metadataProvider; const WADO_IMAGE_LOADER = { imagePlaneModule: instance => { - const { ImageOrientationPatient } = instance; + const { ImageOrientationPatient, PatientOrientation } = instance; // Fallback for DX images. // TODO: We should use the rest of the results of this function @@ -515,6 +516,13 @@ const WADO_IMAGE_LOADER = { if (ImageOrientationPatient) { rowCosines = ImageOrientationPatient.slice(0, 3); columnCosines = ImageOrientationPatient.slice(3, 6); + } else if (PatientOrientation) { + let patientOrientation = PatientOrientation; + if (typeof patientOrientation === 'string') { + patientOrientation = patientOrientation.split('\\'); + } + rowCosines = orientationDirectionVectorMap[patientOrientation[0]]; + columnCosines = orientationDirectionVectorMap[patientOrientation[1][0]]; } return { diff --git a/platform/core/src/defaults/index.js b/platform/core/src/defaults/index.js index f8c065d7b7f..ad4be530cfb 100644 --- a/platform/core/src/defaults/index.js +++ b/platform/core/src/defaults/index.js @@ -1,4 +1,5 @@ import hotkeyBindings from './hotkeyBindings'; import windowLevelPresets from './windowLevelPresets'; -export { hotkeyBindings, windowLevelPresets }; -export default { hotkeyBindings, windowLevelPresets }; +import orientationDirectionVectorMap from './orientationDirectionVectors'; +export { hotkeyBindings, windowLevelPresets, orientationDirectionVectorMap }; +export default { hotkeyBindings, windowLevelPresets, orientationDirectionVectorMap }; diff --git a/platform/core/src/defaults/orientationDirectionVectors.ts b/platform/core/src/defaults/orientationDirectionVectors.ts new file mode 100644 index 00000000000..2809673b26a --- /dev/null +++ b/platform/core/src/defaults/orientationDirectionVectors.ts @@ -0,0 +1,12 @@ +import { Types } from '@cornerstonejs/core'; + +const orientationDirectionVectorMap: { [key: string]: Types.Point3 } = { + L: [1, 0, 0], // Left + R: [-1, 0, 0], // Right + P: [0, 1, 0], // Posterior/ Back + A: [0, -1, 0], // Anterior/ Front + H: [0, 0, 1], // Head/ Superior + F: [0, 0, -1], // Feet/ Inferior +}; + +export default orientationDirectionVectorMap; diff --git a/platform/core/src/types/OrientationDirections.ts b/platform/core/src/types/OrientationDirections.ts new file mode 100644 index 00000000000..d44cec4d96d --- /dev/null +++ b/platform/core/src/types/OrientationDirections.ts @@ -0,0 +1 @@ +export type OrientationDirections = { rowDirection: string; columnDirection: string }; diff --git a/platform/core/src/types/index.ts b/platform/core/src/types/index.ts index efcc8ec3ccf..088a5935f60 100644 --- a/platform/core/src/types/index.ts +++ b/platform/core/src/types/index.ts @@ -18,6 +18,7 @@ export type * from './StudyMetadata'; export type * from './PanelModule'; export type * from './IPubSub'; export type * from './Color'; +export type * from './OrientationDirections'; // Enum exports export * from './TimingEnum'; diff --git a/platform/core/src/utils/getDirectionsFromPatientOrientation.ts b/platform/core/src/utils/getDirectionsFromPatientOrientation.ts new file mode 100644 index 00000000000..33058df6f14 --- /dev/null +++ b/platform/core/src/utils/getDirectionsFromPatientOrientation.ts @@ -0,0 +1,16 @@ +import { OrientationDirections } from '../types'; + +export default function getDirectionsFromPatientOrientation( + patientOrientation: string | [string, string] +): OrientationDirections { + if (typeof patientOrientation === 'string') { + patientOrientation = patientOrientation.split('\\') as [string, string]; + } + + // TODO: We are only considering first direction in column orientation. + // ex: in ['P', 'HL'], we are only taking 'H' instead of 'HL' as column orientation. + return { + rowDirection: patientOrientation[0], + columnDirection: patientOrientation[1][0], + }; +} diff --git a/platform/core/src/utils/index.js b/platform/core/src/utils/index.js index d7862618e0b..860ddbf6eb5 100644 --- a/platform/core/src/utils/index.js +++ b/platform/core/src/utils/index.js @@ -37,6 +37,7 @@ import { } from './sortStudy'; import { subscribeToNextViewportGridChange } from './subscribeToNextViewportGridChange'; import { splitComma, getSplitParam } from './splitComma'; +import getDirectionsFromPatientOrientation from './getDirectionsFromPatientOrientation'; // Commented out unused functionality. // Need to implement new mechanism for derived displaySets using the displaySetManager. @@ -80,6 +81,7 @@ const utils = { splitComma, getSplitParam, generateAcceptHeader, + getDirectionsFromPatientOrientation, }; export { @@ -112,6 +114,7 @@ export { splitComma, getSplitParam, generateAcceptHeader, + getDirectionsFromPatientOrientation, }; export default utils; diff --git a/platform/core/src/utils/index.test.js b/platform/core/src/utils/index.test.js index 30d8f70ef51..044df94a749 100644 --- a/platform/core/src/utils/index.test.js +++ b/platform/core/src/utils/index.test.js @@ -41,6 +41,7 @@ describe('Top level exports', () => { 'subscribeToNextViewportGridChange', 'uuidv4', 'addAccessors', + 'getDirectionsFromPatientOrientation', ].sort(); const exports = Object.keys(utils.default).sort();