feat(Thumbnail): Display set messages support & displaying of series inconsistencies in the thumbnail (#3499)

Co-authored-by: Igor Octaviano <igoroctaviano@gmail.com>
This commit is contained in:
rodrigobasilio2022andIgor Octaviano authored and GitHub committed 2023-08-11 19:16:25 -03:00
1 parent aedb9d1576
commit 5302e5b62b
31 files changed
+1126 -12

No files matched your search

+2
View File
@@ -39,6 +39,8 @@ describe('Top level exports', () => {
'UserAuthenticationService',
'IWebApiDataSource',
'DicomMetadataStore',
'DisplaySetMessage',
'DisplaySetMessageList',
'pubSubServiceInterface',
'PubSubService',
'PanelService',
+7
View File
@@ -33,6 +33,11 @@ import {
PanelService,
} from './services';
import {
DisplaySetMessage,
DisplaySetMessageList,
} from './services/DisplaySetService';
import IWebApiDataSource from './DataSources/IWebApiDataSource';
const hotkeys = {
@@ -107,6 +112,8 @@ export {
UINotificationService,
UIViewportDialogService,
DisplaySetService,
DisplaySetMessage,
DisplaySetMessageList,
MeasurementService,
ToolbarService,
ViewportGridService,
@@ -0,0 +1,49 @@
/**
* Defines a displaySet message, that could be any pf the potential problems of a displaySet
*/
class DisplaySetMessage {
id: number;
static CODES = {
NO_VALID_INSTANCES: 1,
NO_POSITION_INFORMATION: 2,
NOT_RECONSTRUCTABLE: 3,
MULTIFRAME_NO_PIXEL_MEASUREMENTS: 4,
MULTIFRAME_NO_ORIENTATION: 5,
MULTIFRAME_NO_POSITION_INFORMATION: 6,
MISSING_FRAMES: 7,
IRREGULAR_SPACING: 8,
INCONSISTENT_DIMENSIONS: 9,
INCONSISTENT_COMPONENTS: 10,
INCONSISTENT_ORIENTATIONS: 11,
INCONSISTENT_POSITION_INFORMATION: 12,
};
constructor(id: number) {
this.id = id;
}
}
/**
* Defines a list of displaySet messages
*/
class DisplaySetMessageList {
messages = [];
public addMessage(messageId: number): void {
const message = new DisplaySetMessage(messageId);
this.messages.push(message);
}
public size(): number {
return this.messages.length;
}
public includesMessage(messageId: number): boolean {
return this.messages.some(message => message.id === messageId);
}
public includesAllMessages(messageIdList: number[]): boolean {
return messageIdList.every(messageId => this.include(messageId));
}
}
export { DisplaySetMessage, DisplaySetMessageList };
@@ -1,3 +1,5 @@
import DisplaySetService from './DisplaySetService';
import { DisplaySetMessage, DisplaySetMessageList } from './DisplaySetMessage';
export default DisplaySetService;
export { DisplaySetMessage, DisplaySetMessageList };
@@ -54,8 +54,8 @@ function hasPixelMeasurements(multiFrameInstance) {
Boolean(sharedSequence?.PixelMeasuresSequence) ||
Boolean(
multiFrameInstance.PixelSpacing &&
(multiFrameInstance.SliceThickness ||
multiFrameInstance.SpacingBetweenFrames)
(multiFrameInstance.SliceThickness ||
multiFrameInstance.SpacingBetweenFrames)
)
);
}
@@ -70,8 +70,8 @@ function hasOrientation(multiFrameInstance) {
Boolean(perFrameSequence?.PlaneOrientationSequence) ||
Boolean(
multiFrameInstance.ImageOrientationPatient ||
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImageOrientationPatient
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImageOrientationPatient
)
);
}
@@ -85,8 +85,8 @@ function hasPosition(multiFrameInstance) {
Boolean(perFrameSequence?.CTPositionSequence) ||
Boolean(
multiFrameInstance.ImagePositionPatient ||
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImagePositionPatient
multiFrameInstance.DetectorInformationSequence?.[0]
?.ImagePositionPatient
)
);
}
@@ -161,6 +161,7 @@ function processSingleframe(instances) {
}
let missingFrames = 0;
let averageSpacingBetweenFrames;
// Check if frame spacing is approximately equal within a spacingTolerance.
// If spacing is on a uniform grid but we are missing frames,
@@ -175,7 +176,7 @@ function processSingleframe(instances) {
return { value: false };
}
const averageSpacingBetweenFrames =
averageSpacingBetweenFrames =
_getPerpendicularDistance(firstImagePositionPatient, lastIpp) /
(instances.length - 1);
@@ -209,7 +210,7 @@ function processSingleframe(instances) {
}
}
return { value: true, missingFrames };
return { value: true, averageSpacingBetweenFrames };
}
function _isSameOrientation(iop1, iop2) {
@@ -220,7 +221,10 @@ function _isSameOrientation(iop1, iop2) {
return (
Math.abs(iop1[0] - iop2[0]) < iopTolerance &&
Math.abs(iop1[1] - iop2[1]) < iopTolerance &&
Math.abs(iop1[2] - iop2[2]) < iopTolerance
Math.abs(iop1[2] - iop2[2]) < iopTolerance &&
Math.abs(iop1[3] - iop2[3]) < iopTolerance &&
Math.abs(iop1[4] - iop2[4]) < iopTolerance &&
Math.abs(iop1[5] - iop2[5]) < iopTolerance
);
}
@@ -260,8 +264,8 @@ function _getSpacingIssue(spacing, averageSpacing) {
function _getPerpendicularDistance(a, b) {
return Math.sqrt(
Math.pow(a[0] - b[0], 2) +
Math.pow(a[1] - b[1], 2) +
Math.pow(a[2] - b[2], 2)
Math.pow(a[1] - b[1], 2) +
Math.pow(a[2] - b[2], 2)
);
}
@@ -270,3 +274,15 @@ const reconstructionIssues = {
MISSING_FRAMES: 'missingframes',
IRREGULAR_SPACING: 'irregularspacing',
};
export {
hasPixelMeasurements,
hasOrientation,
hasPosition,
isNMReconstructable,
_isSameOrientation,
_getSpacingIssue,
_getPerpendicularDistance,
reconstructionIssues,
constructableModalities,
};