fix: jump to measurement forever (#4867)

This commit is contained in:
Alireza authored and GitHub committed 2025-03-28 10:53:04 -04:00
1 parent eafa2efda5
commit d7bd36544a
39 files changed
+731 -448

No files matched your search

@@ -670,8 +670,11 @@ class MeasurementService extends PubSubService {
measurement,
});
this._broadcastEvent(EVENTS.JUMP_TO_MEASUREMENT_VIEWPORT, consumableEvent);
// Important: we should broadcast the layout event first, since
// in the layout there might be a viewport that we can match and choose
// and jump in it before we decide on changing the orientation of different viewports
this._broadcastEvent(EVENTS.JUMP_TO_MEASUREMENT_LAYOUT, consumableEvent);
this._broadcastEvent(EVENTS.JUMP_TO_MEASUREMENT_VIEWPORT, consumableEvent);
}
_getSourceUID(name, version) {
@@ -38,6 +38,10 @@ class ViewportGridService extends PubSubService {
this.presentationIdProviders.set(id, provider);
}
public setIsReferenceViewable(viewportId: string, isReferenceViewable: boolean): void {
this.serviceImplementation._setIsReferenceViewable(viewportId, isReferenceViewable);
}
public getPresentationId(id: string, viewportId: string): string | null {
const state = this.getState();
const viewport = state.viewports.get(viewportId);
@@ -93,7 +97,12 @@ class ViewportGridService extends PubSubService {
set: setImplementation,
getNumViewportPanes: getNumViewportPanesImplementation,
setViewportIsReady: setViewportIsReadyImplementation,
setIsReferenceViewable: setIsReferenceViewableImplementation,
getViewportState: getViewportStateImplementation,
}): void {
if (getViewportStateImplementation) {
this.serviceImplementation._getViewportState = getViewportStateImplementation;
}
if (getStateImplementation) {
this.serviceImplementation._getState = getStateImplementation;
}
@@ -123,6 +132,9 @@ class ViewportGridService extends PubSubService {
if (setViewportIsReadyImplementation) {
this.serviceImplementation._setViewportIsReady = setViewportIsReadyImplementation;
}
if (setIsReferenceViewableImplementation) {
this.serviceImplementation._setIsReferenceViewable = setIsReferenceViewableImplementation;
}
}
public publishViewportsReady() {
@@ -148,8 +160,7 @@ class ViewportGridService extends PubSubService {
}
public getViewportState(viewportId: string) {
const state = this.getState();
return state.viewports.get(viewportId);
return this.serviceImplementation._getViewportState(viewportId);
}
public setViewportIsReady(viewportId, callback) {
@@ -45,6 +45,10 @@ export interface ViewportGridState {
activeViewportId: string | null;
layout: Layout;
isHangingProtocolLayout: boolean;
isReferenceViewable: (props: {
viewportId: string;
reference: Record<string, unknown>;
}) => boolean;
viewports: GridViewports;
}
@@ -0,0 +1,54 @@
import { vec3 } from 'gl-matrix';
/**
* Get the plane (orientation) to which the ImageOrientationPatient is most closely aligned
*
* @param displaySetService
* @param displaySetInstanceUID
* @returns orientation
*/
export default function getClosestOrientationFromIOP(displaySetService, displaySetInstanceUID) {
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
const imageOrientationPatient = displaySet.instances[0].ImageOrientationPatient as Array<number>;
// ImageOrientationPatient must be an array of length 6.
if (imageOrientationPatient?.length !== 6) {
return;
}
// Take cross product to get vector coming "out" of image plane
const rowCosineVec = vec3.fromValues(
imageOrientationPatient[0],
imageOrientationPatient[1],
imageOrientationPatient[2]
);
const colCosineVec = vec3.fromValues(
imageOrientationPatient[3],
imageOrientationPatient[4],
imageOrientationPatient[5]
);
const scanAxisNormal = vec3.cross(vec3.create(), rowCosineVec, colCosineVec);
// Define the reference vectors for axial, coronal, and sagittal planes
const unitVectors = {
axial: vec3.fromValues(0, 0, 1),
coronal: vec3.fromValues(0, 1, 0),
sagittal: vec3.fromValues(1, 0, 0),
};
// Compute dot products for each reference plane
// Because all vectors are normalized, dot product is bounded between -1 and 1
let maxDot = 0;
let maxOrientation: string = '';
for (const [k, v] of Object.entries(unitVectors)) {
// Absolute value of dot product because we only care about alignment with the axis
// For example, dot product of -1 for a given axis means perfect alignment
// but the image is pointing in the "opposite" direction
const res = Math.abs(vec3.dot(scanAxisNormal, v));
if (res > maxDot) {
maxDot = res;
maxOrientation = k;
}
}
return maxOrientation;
}
-53
View File
@@ -1,53 +0,0 @@
import * as utils from './index';
describe('Top level exports', () => {
test('should export the modules ', () => {
const expectedExports = [
'guid',
'ObjectPath',
'absoluteUrl',
'seriesSortCriteria',
'sortBy',
'sortStudy',
'sortBySeriesDate',
'sortStudyInstances',
'sortStudySeries',
'sortingCriteria',
'splitComma',
'getSplitParam',
'isLowPriorityModality',
'writeScript',
'debounce',
'downloadCSVReport',
'imageIdToURI',
'roundNumber',
'b64toBlob',
'sopClassDictionary',
'createStudyBrowserTabs',
'formatDate',
'formatTime',
'formatPN',
'generateAcceptHeader',
'isEqualWithin',
//'loadAndCacheDerivedDisplaySets',
'isDisplaySetReconstructable',
'isImage',
'urlUtil',
'makeDeferred',
'makeCancelable',
'hotkeys',
'Queue',
'isDicomUid',
'resolveObjectPath',
'hierarchicalListUtils',
'progressTrackingUtils',
'uuidv4',
'addAccessors',
'MeasurementFilters',
].sort();
const exports = Object.keys(utils.default).sort();
expect(exports).toEqual(expectedExports);
});
});
+3 -1
View File
@@ -40,7 +40,7 @@ import { splitComma, getSplitParam } from './splitComma';
import { createStudyBrowserTabs } from './createStudyBrowserTabs';
import { sopClassDictionary } from './sopClassDictionary';
import * as MeasurementFilters from './measurementFilters';
import getClosestOrientationFromIOP from './getClosestOrientationFromIOP';
// Commented out unused functionality.
// Need to implement new mechanism for derived displaySets using the displaySetManager.
@@ -86,6 +86,7 @@ const utils = {
generateAcceptHeader,
createStudyBrowserTabs,
MeasurementFilters,
getClosestOrientationFromIOP,
};
export {
@@ -120,6 +121,7 @@ export {
generateAcceptHeader,
createStudyBrowserTabs,
MeasurementFilters,
getClosestOrientationFromIOP,
};
export default utils;