diff --git a/extensions/cornerstone/src/init.tsx b/extensions/cornerstone/src/init.tsx
index 2c6169a3836..99755fa73a5 100644
--- a/extensions/cornerstone/src/init.tsx
+++ b/extensions/cornerstone/src/init.tsx
@@ -28,6 +28,7 @@ import interleaveTopToBottom from './utils/interleaveTopToBottom';
import initContextMenu from './initContextMenu';
import initDoubleClick from './initDoubleClick';
import { CornerstoneServices } from './types';
+import initViewTiming from './utils/initViewTiming';
// TODO: Cypress tests are currently grabbing this from the window?
window.cornerstone = cornerstone;
@@ -284,6 +285,8 @@ export default async function init({
element.addEventListener(EVENTS.CAMERA_RESET, resetCrosshairs);
eventTarget.addEventListener(EVENTS.STACK_VIEWPORT_NEW_STACK, toolbarEventListener);
+
+ initViewTiming({ element, eventTarget });
}
function elementDisabledHandler(evt) {
@@ -305,8 +308,8 @@ export default async function init({
viewportGridService.subscribe(
viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED,
activeViewportEventListener
- );
-}
+ );
+ }
function CPUModal() {
return (
diff --git a/extensions/cornerstone/src/utils/initViewTiming.ts b/extensions/cornerstone/src/utils/initViewTiming.ts
new file mode 100644
index 00000000000..8c4ad9f03de
--- /dev/null
+++ b/extensions/cornerstone/src/utils/initViewTiming.ts
@@ -0,0 +1,45 @@
+import { log, Types } from '@ohif/core';
+import { EVENTS } from '@cornerstonejs/core';
+
+const { TimingEnum } = Types;
+
+const IMAGE_TIMING_KEYS = [
+ TimingEnum.DISPLAY_SETS_TO_ALL_IMAGES,
+ TimingEnum.DISPLAY_SETS_TO_FIRST_IMAGE,
+ TimingEnum.STUDY_TO_FIRST_IMAGE,
+];
+
+const imageTiming = {
+ viewportsWaiting: 0,
+};
+
+/**
+ * Defines the initial view timing reporting.
+ * This allows knowing how many viewports are waiting for initial views and
+ * when the IMAGE_RENDERED gets sent out.
+ * The first image rendered will fire the FIRST_IMAGE timeEnd logs, while
+ * the last of the enabled viewport will fire the ALL_IMAGES timeEnd logs.
+ *
+ */
+
+export default function initViewTiming({ element }) {
+ if (!IMAGE_TIMING_KEYS.find(key => log.timingKeys[key])) {
+ return;
+ }
+ imageTiming.viewportsWaiting += 1;
+ element.addEventListener(EVENTS.IMAGE_RENDERED, imageRenderedListener);
+}
+
+function imageRenderedListener(evt) {
+ if (evt.detail.viewportStatus === 'preRender') {
+ return;
+ }
+ log.timeEnd(TimingEnum.DISPLAY_SETS_TO_FIRST_IMAGE);
+ log.timeEnd(TimingEnum.STUDY_TO_FIRST_IMAGE);
+ log.timeEnd(TimingEnum.SCRIPT_TO_VIEW);
+ imageTiming.viewportsWaiting -= 1;
+ evt.detail.element.removeEventListener(EVENTS.IMAGE_RENDERED, imageRenderedListener);
+ if (!imageTiming.viewportsWaiting) {
+ log.timeEnd(TimingEnum.DISPLAY_SETS_TO_ALL_IMAGES);
+ }
+}
diff --git a/extensions/default/src/getDisplaySetMessages.ts b/extensions/default/src/getDisplaySetMessages.ts
index 53c72ce83b0..4472f8de0eb 100644
--- a/extensions/default/src/getDisplaySetMessages.ts
+++ b/extensions/default/src/getDisplaySetMessages.ts
@@ -13,22 +13,23 @@ export default function getDisplaySetMessages(
isReconstructable: boolean
): DisplaySetMessageList {
const messages = new DisplaySetMessageList();
- if (!instances.length) {
+ const firstInstance = instances[0];
+ if (!instances.length || firstInstance) {
messages.addMessage(DisplaySetMessage.CODES.NO_VALID_INSTANCES);
+ return;
}
- const firstInstance = instances[0];
+ const { Modality, ImageType, NumberOfFrames } = firstInstance;
// Due to current requirements, LOCALIZER series doesn't have any messages
- if (firstInstance?.ImageType?.includes('LOCALIZER')) {
+ if (ImageType?.includes('LOCALIZER')) {
return messages;
}
- const Modality = firstInstance.Modality;
if (!constructableModalities.includes(Modality)) {
return messages;
}
- const isMultiframe = firstInstance.NumberOfFrames > 1;
+ const isMultiframe = NumberOfFrames > 1;
// Can't reconstruct if all instances don't have the ImagePositionPatient.
if (!isMultiframe && !instances.every(instance => instance.ImagePositionPatient)) {
messages.addMessage(DisplaySetMessage.CODES.NO_POSITION_INFORMATION);
diff --git a/platform/app/public/html-templates/index.html b/platform/app/public/html-templates/index.html
index 9853c121a65..eb53fc851c8 100644
--- a/platform/app/public/html-templates/index.html
+++ b/platform/app/public/html-templates/index.html
@@ -42,6 +42,10 @@
name="msapplication-config"
content="<%= PUBLIC_URL %>assets/browserconfig.xml"
/>
+
-