feat(tmtv): add more stages to pt/ct (#3290)

* feat(tmtv): add more stages to pt/ct

* make error stage change to info

* apply review comments
This commit is contained in:
Alireza 2023-03-30 10:01:48 -04:00 committed by GitHub
parent d5ff590dfc
commit ca3b83b2b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 656 additions and 495 deletions

View File

@ -329,7 +329,7 @@ const commandsModule = ({
uiNotificationService.show({
title: 'Change Stage',
message: 'The hanging protocol has no more applicable stages',
type: 'error',
type: 'info',
duration: 3000,
});
},

View File

@ -1,3 +1,219 @@
import {
ctAXIAL,
ctCORONAL,
ctSAGITTAL,
fusionAXIAL,
fusionCORONAL,
fusionSAGITTAL,
mipSAGITTAL,
ptAXIAL,
ptCORONAL,
ptSAGITTAL,
} from './utils/hpViewports';
/**
* represents a 3x4 viewport layout configuration. The layout displays CT axial, sagittal, and coronal
* images in the first row, PT axial, sagittal, and coronal images in the second row, and fusion axial,
* sagittal, and coronal images in the third row. The fourth column is fully spanned by a MIP sagittal
* image, covering all three rows. It has synchronizers for windowLevel for all CT and PT images, and
* also camera synchronizer for each orientation
*/
const stage1 = {
name: 'default',
viewportStructure: {
layoutType: 'grid',
properties: {
rows: 3,
columns: 4,
layoutOptions: [
{
x: 0,
y: 0,
width: 1 / 4,
height: 1 / 3,
},
{
x: 1 / 4,
y: 0,
width: 1 / 4,
height: 1 / 3,
},
{
x: 2 / 4,
y: 0,
width: 1 / 4,
height: 1 / 3,
},
{
x: 0,
y: 1 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 1 / 4,
y: 1 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 2 / 4,
y: 1 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 0,
y: 2 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 1 / 4,
y: 2 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 2 / 4,
y: 2 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 3 / 4,
y: 0,
width: 1 / 4,
height: 1,
},
],
},
},
viewports: [
ctAXIAL,
ctSAGITTAL,
ctCORONAL,
ptAXIAL,
ptSAGITTAL,
ptCORONAL,
fusionAXIAL,
fusionSAGITTAL,
fusionCORONAL,
mipSAGITTAL,
],
createdDate: '2021-02-23T18:32:42.850Z',
};
/**
* The layout displays CT axial image in the top-left viewport, fusion axial image
* in the top-right viewport, PT axial image in the bottom-left viewport, and MIP
* sagittal image in the bottom-right viewport. The layout follows a simple grid
* pattern with 2 rows and 2 columns. It includes synchronizers as well.
*/
const stage2 = {
name: 'Fusion 2x2',
viewportStructure: {
layoutType: 'grid',
properties: {
rows: 2,
columns: 2,
},
},
viewports: [ctAXIAL, fusionAXIAL, ptAXIAL, mipSAGITTAL],
};
/**
* The top row displays CT images in axial, sagittal, and coronal orientations from
* left to right, respectively. The bottom row displays PT images in axial, sagittal,
* and coronal orientations from left to right, respectively.
* The layout follows a simple grid pattern with 2 rows and 3 columns.
* It includes synchronizers as well.
*/
const stage3 = {
name: '2x3-layout',
viewportStructure: {
layoutType: 'grid',
properties: {
rows: 2,
columns: 3,
},
},
viewports: [ctAXIAL, ctSAGITTAL, ctCORONAL, ptAXIAL, ptSAGITTAL, ptCORONAL],
};
/**
* In this layout, the top row displays PT images in coronal, sagittal, and axial
* orientations from left to right, respectively, followed by a MIP sagittal image
* that spans both rows on the rightmost side. The bottom row displays fusion images
* in coronal, sagittal, and axial orientations from left to right, respectively.
* There is no viewport in the bottom row's rightmost position, as the MIP sagittal viewport
* from the top row spans the full height of both rows.
* It includes synchronizers as well.
*/
const stage4 = {
name: '2x4-layout',
viewportStructure: {
layoutType: 'grid',
properties: {
rows: 2,
columns: 4,
layoutOptions: [
{
x: 0,
y: 0,
width: 1 / 4,
height: 1 / 2,
},
{
x: 1 / 4,
y: 0,
width: 1 / 4,
height: 1 / 2,
},
{
x: 2 / 4,
y: 0,
width: 1 / 4,
height: 1 / 2,
},
{
x: 3 / 4,
y: 0,
width: 1 / 4,
height: 1,
},
{
x: 0,
y: 1 / 2,
width: 1 / 4,
height: 1 / 2,
},
{
x: 1 / 4,
y: 1 / 2,
width: 1 / 4,
height: 1 / 2,
},
{
x: 2 / 4,
y: 1 / 2,
width: 1 / 4,
height: 1 / 2,
},
],
},
},
viewports: [
ptCORONAL,
ptSAGITTAL,
ptAXIAL,
mipSAGITTAL,
fusionCORONAL,
fusionSAGITTAL,
fusionAXIAL,
],
};
const ptCT = {
id: '@ohif/extension-tmtv.hangingProtocolModule.ptCT',
locked: true,
@ -100,500 +316,7 @@ const ptCT = {
},
},
stages: [
{
name: 'default',
viewportStructure: {
layoutType: 'grid',
properties: {
rows: 3,
columns: 4,
layoutOptions: [
{
x: 0,
y: 0,
width: 1 / 4,
height: 1 / 3,
},
{
x: 1 / 4,
y: 0,
width: 1 / 4,
height: 1 / 3,
},
{
x: 2 / 4,
y: 0,
width: 1 / 4,
height: 1 / 3,
},
{
x: 0,
y: 1 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 1 / 4,
y: 1 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 2 / 4,
y: 1 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 0,
y: 2 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 1 / 4,
y: 2 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 2 / 4,
y: 2 / 3,
width: 1 / 4,
height: 1 / 3,
},
{
x: 3 / 4,
y: 0,
width: 1 / 4,
height: 1,
},
],
},
},
viewports: [
{
viewportOptions: {
viewportId: 'ctAXIAL',
viewportType: 'volume',
orientation: 'axial',
toolGroupId: 'ctToolGroup',
initialImageOptions: {
// index: 5,
preset: 'first', // 'first', 'last', 'middle'
},
syncGroups: [
{
type: 'cameraPosition',
id: 'axialSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: true,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'ctSAGITTAL',
viewportType: 'volume',
orientation: 'sagittal',
toolGroupId: 'ctToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'sagittalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: true,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'ctCORONAL',
viewportType: 'volume',
orientation: 'coronal',
toolGroupId: 'ctToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'coronalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: true,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'ptAXIAL',
viewportType: 'volume',
background: [1, 1, 1],
orientation: 'axial',
toolGroupId: 'ptToolGroup',
initialImageOptions: {
// index: 5,
preset: 'first', // 'first', 'last', 'middle'
},
syncGroups: [
{
type: 'cameraPosition',
id: 'axialSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
},
displaySets: [
{
options: {
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'ptSAGITTAL',
viewportType: 'volume',
orientation: 'sagittal',
background: [1, 1, 1],
toolGroupId: 'ptToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'sagittalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
},
displaySets: [
{
options: {
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'ptCORONAL',
viewportType: 'volume',
orientation: 'coronal',
background: [1, 1, 1],
toolGroupId: 'ptToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'coronalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
},
displaySets: [
{
options: {
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'fusionAXIAL',
viewportType: 'volume',
orientation: 'axial',
toolGroupId: 'fusionToolGroup',
initialImageOptions: {
// index: 5,
preset: 'first', // 'first', 'last', 'middle'
},
syncGroups: [
{
type: 'cameraPosition',
id: 'axialSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: false,
target: true,
},
{
type: 'voi',
id: 'fusionWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: false,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
{
options: {
colormap: 'hsv',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
},
id: 'ptDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'fusionSAGITTAL',
viewportType: 'volume',
orientation: 'sagittal',
toolGroupId: 'fusionToolGroup',
// initialImageOptions: {
// index: 180,
// preset: 'middle', // 'first', 'last', 'middle'
// },
syncGroups: [
{
type: 'cameraPosition',
id: 'sagittalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: false,
target: true,
},
{
type: 'voi',
id: 'fusionWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: false,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
{
options: {
colormap: 'hsv',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
},
id: 'ptDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'fusionCoronal',
viewportType: 'volume',
orientation: 'coronal',
toolGroupId: 'fusionToolGroup',
// initialImageOptions: {
// index: 180,
// preset: 'middle', // 'first', 'last', 'middle'
// },
syncGroups: [
{
type: 'cameraPosition',
id: 'coronalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: false,
target: true,
},
{
type: 'voi',
id: 'fusionWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: false,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
{
options: {
colormap: 'hsv',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
},
id: 'ptDisplaySet',
},
],
},
{
viewportOptions: {
viewportId: 'mipSagittal',
viewportType: 'volume',
orientation: 'sagittal',
background: [1, 1, 1],
toolGroupId: 'mipToolGroup',
syncGroups: [
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
// Custom props can be used to set custom properties which extensions
// can react on.
customViewportProps: {
// We use viewportDisplay to filter the viewports which are displayed
// in mip and we set the scrollbar according to their rotation index
// in the cornerstone extension.
hideOverlays: true,
},
},
displaySets: [
{
options: {
blendMode: 'MIP',
slabThickness: 'fullVolume',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
},
],
createdDate: '2021-02-23T18:32:42.850Z',
},
],
stages: [stage1, stage2, stage3, stage4],
numberOfPriorsReferenced: -1,
};

View File

@ -0,0 +1,438 @@
const ctAXIAL = {
viewportOptions: {
viewportId: 'ctAXIAL',
viewportType: 'volume',
orientation: 'axial',
toolGroupId: 'ctToolGroup',
initialImageOptions: {
// index: 5,
preset: 'first', // 'first', 'last', 'middle'
},
syncGroups: [
{
type: 'cameraPosition',
id: 'axialSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: true,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
],
};
const ctSAGITTAL = {
viewportOptions: {
viewportId: 'ctSAGITTAL',
viewportType: 'volume',
orientation: 'sagittal',
toolGroupId: 'ctToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'sagittalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: true,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
],
};
const ctCORONAL = {
viewportOptions: {
viewportId: 'ctCORONAL',
viewportType: 'volume',
orientation: 'coronal',
toolGroupId: 'ctToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'coronalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: true,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
],
};
const ptAXIAL = {
viewportOptions: {
viewportId: 'ptAXIAL',
viewportType: 'volume',
background: [1, 1, 1],
orientation: 'axial',
toolGroupId: 'ptToolGroup',
initialImageOptions: {
// index: 5,
preset: 'first', // 'first', 'last', 'middle'
},
syncGroups: [
{
type: 'cameraPosition',
id: 'axialSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
},
displaySets: [
{
options: {
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
};
const ptSAGITTAL = {
viewportOptions: {
viewportId: 'ptSAGITTAL',
viewportType: 'volume',
orientation: 'sagittal',
background: [1, 1, 1],
toolGroupId: 'ptToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'sagittalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
},
displaySets: [
{
options: {
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
};
const ptCORONAL = {
viewportOptions: {
viewportId: 'ptCORONAL',
viewportType: 'volume',
orientation: 'coronal',
background: [1, 1, 1],
toolGroupId: 'ptToolGroup',
syncGroups: [
{
type: 'cameraPosition',
id: 'coronalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
},
displaySets: [
{
options: {
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
};
const fusionAXIAL = {
viewportOptions: {
viewportId: 'fusionAXIAL',
viewportType: 'volume',
orientation: 'axial',
toolGroupId: 'fusionToolGroup',
initialImageOptions: {
// index: 5,
preset: 'first', // 'first', 'last', 'middle'
},
syncGroups: [
{
type: 'cameraPosition',
id: 'axialSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: false,
target: true,
},
{
type: 'voi',
id: 'fusionWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: false,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
{
options: {
colormap: 'hsv',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
},
id: 'ptDisplaySet',
},
],
};
const fusionSAGITTAL = {
viewportOptions: {
viewportId: 'fusionSAGITTAL',
viewportType: 'volume',
orientation: 'sagittal',
toolGroupId: 'fusionToolGroup',
// initialImageOptions: {
// index: 180,
// preset: 'middle', // 'first', 'last', 'middle'
// },
syncGroups: [
{
type: 'cameraPosition',
id: 'sagittalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: false,
target: true,
},
{
type: 'voi',
id: 'fusionWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: false,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
{
options: {
colormap: 'hsv',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
},
id: 'ptDisplaySet',
},
],
};
const fusionCORONAL = {
viewportOptions: {
viewportId: 'fusionCoronal',
viewportType: 'volume',
orientation: 'coronal',
toolGroupId: 'fusionToolGroup',
// initialImageOptions: {
// index: 180,
// preset: 'middle', // 'first', 'last', 'middle'
// },
syncGroups: [
{
type: 'cameraPosition',
id: 'coronalSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ctWLSync',
source: false,
target: true,
},
{
type: 'voi',
id: 'fusionWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: false,
target: true,
},
],
},
displaySets: [
{
id: 'ctDisplaySet',
},
{
options: {
colormap: 'hsv',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
},
id: 'ptDisplaySet',
},
],
};
const mipSAGITTAL = {
viewportOptions: {
viewportId: 'mipSagittal',
viewportType: 'volume',
orientation: 'sagittal',
background: [1, 1, 1],
toolGroupId: 'mipToolGroup',
syncGroups: [
{
type: 'voi',
id: 'ptWLSync',
source: true,
target: true,
},
{
type: 'voi',
id: 'ptFusionWLSync',
source: true,
target: false,
},
],
// Custom props can be used to set custom properties which extensions
// can react on.
customViewportProps: {
// We use viewportDisplay to filter the viewports which are displayed
// in mip and we set the scrollbar according to their rotation index
// in the cornerstone extension.
hideOverlays: true,
},
},
displaySets: [
{
options: {
blendMode: 'MIP',
slabThickness: 'fullVolume',
voi: {
windowWidth: 5,
windowCenter: 2.5,
},
voiInverted: true,
},
id: 'ptDisplaySet',
},
],
};
export {
ctAXIAL,
ctSAGITTAL,
ctCORONAL,
ptAXIAL,
ptSAGITTAL,
ptCORONAL,
fusionAXIAL,
fusionSAGITTAL,
fusionCORONAL,
mipSAGITTAL,
};