Skip to content

Commit d349c87

Browse files
committed
test: add regression test for labelmap with different direction matrix
Verifies paint tool works correctly on coronal view when the segment group has a different direction matrix than the parent image (e.g., TotalSegmenter output). Also refactors shared manifest to configTestUtils.
1 parent 5fadbc7 commit d349c87

5 files changed

Lines changed: 164 additions & 43 deletions

package-lock.json

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
137 KB
Loading

tests/specs/configTestUtils.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,43 @@ export const PROSTATE_SEGMENT_GROUP = {
2626
name: 'prostate-total.seg.nii.gz',
2727
} as const;
2828

29+
export const PROSTATE_WITH_LABELMAP_MANIFEST = {
30+
version: '6.1.0',
31+
dataSources: [
32+
{
33+
id: 0,
34+
type: 'uri',
35+
uri: `/tmp/${PROSTATEX_DATASET.name}`,
36+
},
37+
{
38+
id: 1,
39+
type: 'uri',
40+
uri: `/tmp/${PROSTATE_SEGMENT_GROUP.name}`,
41+
},
42+
],
43+
labelMaps: [
44+
{
45+
id: 'seg-1',
46+
dataSourceId: 1,
47+
metadata: {
48+
name: 'Prostate Segmentation',
49+
parentImage: '0',
50+
segments: {
51+
order: [1],
52+
byValue: {
53+
'1': {
54+
value: 1,
55+
name: 'Prostate',
56+
color: [255, 0, 0, 255],
57+
visible: true,
58+
},
59+
},
60+
},
61+
},
62+
},
63+
],
64+
} as const;
65+
2966
export const MRA_HEAD_NECK_DATASET = {
3067
url: 'https://data.kitware.com/api/v1/item/6352a2b311dab8142820a33b/download',
3168
name: 'MRA-Head_and_Neck.zip',
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import {
2+
PROSTATEX_DATASET,
3+
PROSTATE_SEGMENT_GROUP,
4+
PROSTATE_WITH_LABELMAP_MANIFEST,
5+
} from './configTestUtils';
6+
import { downloadFile, writeManifestToFile } from './utils';
7+
import { volViewPage } from '../pageobjects/volview.page';
8+
import { DOWNLOAD_TIMEOUT, TEMP_DIR } from '../../wdio.shared.conf';
9+
import * as path from 'path';
10+
import * as fs from 'fs';
11+
import { cleanuptotal } from 'wdio-cleanuptotal-service';
12+
13+
/**
14+
* Regression test for labelmap with different direction matrix than parent image.
15+
*
16+
* The prostate DICOM and TotalSegmenter segment group have different direction matrices:
17+
* Base image: [1, 0, 0, 0, 0.97, -0.24, 0, 0.24, 0.97]
18+
* Segment group: [1, 0, 0, 0, -0.97, 0.24, 0, 0.24, 0.97]
19+
*
20+
* This caused bugs where paint tool painted at wrong location and
21+
* coronal slice didn't show segment overlay.
22+
*/
23+
describe('Labelmap with different direction matrix', () => {
24+
it('paint tool works on coronal view', async () => {
25+
await downloadFile(PROSTATEX_DATASET.url, PROSTATEX_DATASET.name);
26+
await downloadFile(PROSTATE_SEGMENT_GROUP.url, PROSTATE_SEGMENT_GROUP.name);
27+
28+
const config = {
29+
layouts: {
30+
'Coronal Only': [['coronal']],
31+
},
32+
};
33+
34+
const manifestFileName = 'different-direction-labelmap.volview.json';
35+
await writeManifestToFile(
36+
PROSTATE_WITH_LABELMAP_MANIFEST,
37+
manifestFileName
38+
);
39+
40+
const configFileName = 'different-direction-labelmap-config.json';
41+
const configFilePath = path.join(TEMP_DIR, configFileName);
42+
await fs.promises.writeFile(configFilePath, JSON.stringify(config));
43+
cleanuptotal.addCleanup(async () => {
44+
fs.unlinkSync(configFilePath);
45+
});
46+
47+
const urlParams = `?urls=[tmp/${manifestFileName}]&config=[tmp/${configFileName}]`;
48+
await volViewPage.open(urlParams);
49+
await volViewPage.waitForViews();
50+
const notifications = await volViewPage.getNotificationsCount();
51+
expect(notifications).toEqual(0);
52+
53+
const annotationsTab = await $(
54+
'button[data-testid="module-tab-Annotations"]'
55+
);
56+
await annotationsTab.click();
57+
58+
const segmentGroupsTab = await $('button.v-tab*=Segment Groups');
59+
await segmentGroupsTab.waitForClickable();
60+
await segmentGroupsTab.click();
61+
62+
await browser.waitUntil(
63+
async () => {
64+
const segmentGroups = await $$('.segment-group-list .v-list-item');
65+
return (await segmentGroups.length) >= 1;
66+
},
67+
{
68+
timeout: DOWNLOAD_TIMEOUT,
69+
timeoutMsg: 'Segment group not found in segment groups list',
70+
}
71+
);
72+
73+
await volViewPage.openLayoutMenu(1);
74+
await volViewPage.selectLayoutOption('Coronal Only');
75+
await volViewPage.waitForViewCounts(1, false);
76+
77+
await volViewPage.focusFirst2DView();
78+
await volViewPage.advanceSliceAndWait();
79+
await volViewPage.advanceSliceAndWait();
80+
await volViewPage.advanceSliceAndWait();
81+
82+
await volViewPage.activatePaint();
83+
84+
const views2D = await volViewPage.getViews2D();
85+
const coronalView = views2D[0];
86+
const canvas = await coronalView.$('canvas');
87+
88+
const location = await canvas.getLocation();
89+
const size = await canvas.getSize();
90+
const centerX = location.x + size.width / 2;
91+
const centerY = location.y + size.height / 2;
92+
93+
await browser
94+
.action('pointer')
95+
.move({ x: Math.round(centerX), y: Math.round(centerY) })
96+
.down()
97+
.move({ x: Math.round(centerX + 40), y: Math.round(centerY) })
98+
.move({ x: Math.round(centerX + 40), y: Math.round(centerY + 40) })
99+
.up()
100+
.perform();
101+
102+
await browser.waitUntil(
103+
async () => {
104+
const result = await browser.checkElement(
105+
coronalView,
106+
'different_direction_labelmap_paint_coronal'
107+
);
108+
return (result as number) < 5;
109+
},
110+
{
111+
timeout: 10000,
112+
timeoutMsg:
113+
'Paint stroke on coronal view with misaligned labelmap should match baseline',
114+
interval: 1000,
115+
}
116+
);
117+
});
118+
});

tests/specs/sparse-manifest.e2e.ts

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import {
22
MINIMAL_DICOM,
33
PROSTATEX_DATASET,
44
PROSTATE_SEGMENT_GROUP,
5+
PROSTATE_WITH_LABELMAP_MANIFEST,
56
} from './configTestUtils';
67
import {
78
downloadFile,
89
openVolViewPage,
910
writeManifestToFile,
1011
writeManifestToZip,
1112
} from './utils';
13+
import { DOWNLOAD_TIMEOUT } from '../../wdio.shared.conf';
1214

1315
describe('Sparse manifest.json', () => {
1416
it('loads manifest with only URL data source', async () => {
@@ -118,45 +120,8 @@ describe('Sparse manifest.json', () => {
118120
await downloadFile(PROSTATEX_DATASET.url, PROSTATEX_DATASET.name);
119121
await downloadFile(PROSTATE_SEGMENT_GROUP.url, PROSTATE_SEGMENT_GROUP.name);
120122

121-
const sparseManifest = {
122-
version: '6.1.0',
123-
dataSources: [
124-
{
125-
id: 0,
126-
type: 'uri',
127-
uri: `/tmp/${PROSTATEX_DATASET.name}`,
128-
},
129-
{
130-
id: 1,
131-
type: 'uri',
132-
uri: `/tmp/${PROSTATE_SEGMENT_GROUP.name}`,
133-
},
134-
],
135-
labelMaps: [
136-
{
137-
id: 'seg-1',
138-
dataSourceId: 1,
139-
metadata: {
140-
name: 'Prostate Segmentation',
141-
parentImage: '0',
142-
segments: {
143-
order: [1],
144-
byValue: {
145-
'1': {
146-
value: 1,
147-
name: 'Prostate',
148-
color: [255, 0, 0, 255],
149-
visible: true,
150-
},
151-
},
152-
},
153-
},
154-
},
155-
],
156-
};
157-
158123
const fileName = 'remote-segment-group.volview.json';
159-
await writeManifestToFile(sparseManifest, fileName);
124+
await writeManifestToFile(PROSTATE_WITH_LABELMAP_MANIFEST, fileName);
160125
await openVolViewPage(fileName);
161126

162127
const annotationsTab = await $(
@@ -175,7 +140,7 @@ describe('Sparse manifest.json', () => {
175140
return count >= 1;
176141
},
177142
{
178-
timeout: 15000,
143+
timeout: DOWNLOAD_TIMEOUT,
179144
timeoutMsg: 'Segment group not found in segment groups list',
180145
}
181146
);

0 commit comments

Comments
 (0)