fix(segmentation): failing to render SEG because it was on default tool group (#3222)

* fix: Segmentation service fixes for secondary volumes

* Remove toolgroupID in promptSeg
This commit is contained in:
Bill Wallace 2023-03-10 13:57:23 -05:00 committed by GitHub
parent 3f20b41c17
commit b7fff77e17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 97 additions and 117 deletions

View File

@ -59,7 +59,7 @@
"babel-eslint": "^8.0.3",
"babel-loader": "^8.0.0-beta.4",
"clean-webpack-plugin": "^4.0.0",
"copy-webpack-plugin": "^10.2.0",
"copy-webpack-plugin": "^11.0.0",
"cross-env": "^7.0.3",
"dotenv": "^14.1.0",
"eslint": "^5.0.1",

View File

@ -203,7 +203,7 @@ export default function PanelSegmentation({
showAddSegmentation={false}
segmentations={segmentations}
isMinimized={isMinimized}
activeSegmentationId={selectedSegmentationId}
activeSegmentationId={selectedSegmentationId || ''}
onSegmentationClick={onSegmentationClick}
onSegmentationDelete={onSegmentationDelete}
onSegmentationEdit={onSegmentationEdit}

View File

@ -1,7 +1,6 @@
async function _hydrateSEGDisplaySet({
segDisplaySet,
viewportIndex,
toolGroupId,
servicesManager,
}) {
const {
@ -55,8 +54,6 @@ async function _hydrateSEGDisplaySet({
viewportIndex: index,
displaySetInstanceUIDs: viewport.displaySetInstanceUIDs,
viewportOptions: {
viewportType: 'volume',
toolGroupId,
initialImageOptions: {
preset: 'middle',
},

View File

@ -10,13 +10,12 @@ function promptHydrateSEG({
servicesManager,
segDisplaySet,
viewportIndex,
toolGroupId = 'default',
}) {
const { UIViewportDialogService } = servicesManager.services;
const { uiViewportDialogService } = servicesManager.services;
return new Promise(async function(resolve, reject) {
const promptResult = await _askHydrate(
UIViewportDialogService,
uiViewportDialogService,
viewportIndex
);
@ -24,7 +23,6 @@ function promptHydrateSEG({
const isHydrated = await hydrateSEGDisplaySet({
segDisplaySet,
viewportIndex,
toolGroupId,
servicesManager,
});
@ -33,7 +31,7 @@ function promptHydrateSEG({
});
}
function _askHydrate(UIViewportDialogService, viewportIndex) {
function _askHydrate(uiViewportDialogService, viewportIndex) {
return new Promise(function(resolve, reject) {
const message = 'Do you want to open this Segmentation?';
const actions = [
@ -49,18 +47,18 @@ function _askHydrate(UIViewportDialogService, viewportIndex) {
},
];
const onSubmit = result => {
UIViewportDialogService.hide();
uiViewportDialogService.hide();
resolve(result);
};
UIViewportDialogService.show({
uiViewportDialogService.show({
viewportIndex,
type: 'info',
message,
actions,
onSubmit,
onOutsideClick: () => {
UIViewportDialogService.hide();
uiViewportDialogService.hide();
resolve(RESPONSE.CANCEL);
},
});

View File

@ -235,6 +235,8 @@ function OHIFCornerstoneSEGViewport(props) {
return;
}
// This creates a custom tool group which has the lifetime of this view
// only, and does NOT interfere with currently displayed segmentations.
toolGroup = createSEGToolGroupAndAddTools(
toolGroupService,
toolGroupId,
@ -249,6 +251,7 @@ function OHIFCornerstoneSEGViewport(props) {
toolGroupId
);
// Only destroy the viewport specific implementation
toolGroupService.destroyToolGroup(toolGroupId);
};
}, []);
@ -298,14 +301,12 @@ function OHIFCornerstoneSEGViewport(props) {
StudyDate,
SeriesDescription,
SpacingBetweenSlices,
SeriesNumber,
} = referencedDisplaySetRef.current.metadata;
const onStatusClick = async () => {
const isHydrated = await hydrateSEGDisplaySet({
segDisplaySet,
viewportIndex,
toolGroupId,
servicesManager,
});

View File

@ -45,8 +45,8 @@
"dependencies": {
"@babel/runtime": "^7.20.13",
"classnames": "^2.3.2",
"@cornerstonejs/adapters": "^0.3.1",
"@cornerstonejs/core": "^0.32.0",
"@cornerstonejs/tools": "^0.48.0"
"@cornerstonejs/adapters": "^0.4.1",
"@cornerstonejs/core": "^0.33.2",
"@cornerstonejs/tools": "^0.50.2"
}
}

View File

@ -43,10 +43,10 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^0.3.1",
"@cornerstonejs/core": "^0.32.0",
"@cornerstonejs/streaming-image-volume-loader": "^0.13.0",
"@cornerstonejs/tools": "^0.48.0",
"@cornerstonejs/adapters": "^0.4.1",
"@cornerstonejs/core": "^0.33.2",
"@cornerstonejs/streaming-image-volume-loader": "^0.14.1",
"@cornerstonejs/tools": "^0.50.2",
"@kitware/vtk.js": "26.5.6",
"html2canvas": "^1.4.1",
"lodash.debounce": "4.0.8",

View File

@ -32,8 +32,8 @@
"peerDependencies": {
"@ohif/core": "^3.0.0",
"classnames": "^2.3.2",
"@cornerstonejs/core": "^0.32.0",
"@cornerstonejs/tools": "^0.48.0",
"@cornerstonejs/core": "^0.33.2",
"@cornerstonejs/tools": "^0.50.2",
"@ohif/extension-cornerstone-dicom-sr": "^3.0.0",
"dcmjs": "^0.29.4",
"prop-types": "^15.6.2",

View File

@ -234,19 +234,16 @@ export default class CustomizationService extends PubSubService {
}
/**
* A single reference is either an an array, or a single customization value,
* whose id is the id in the object, or the parent id.
* This allows for general use to register customizationModule entries.
* A single reference is either an string to be loaded from a module,
* or a customization itself.
*/
addReference(
value?: Obj | Obj[] | string,
isGlobal = true,
id?: string
): void {
addReference(value?: Obj | string, isGlobal = true, id?: string): void {
if (!value) return;
if (typeof value === 'string') {
const extensionValue = this.findExtensionValue(value);
this.addReferences(extensionValue);
// The child of a reference is only a set of references when an array,
// so call the addReference direct. It could be a secondary reference perhaps
this.addReference(extensionValue);
} else if (Array.isArray(value)) {
this.addReferences(value, isGlobal);
} else {
@ -258,10 +255,10 @@ export default class CustomizationService extends PubSubService {
}
}
/** References are:
* list of customizations, added in order
* object containing a customization id and value
* This format allows for the original whitelist format.
/**
* Customizations can be specified as an array of strings or customizations,
* or as an object whose key is the reference id, and the value is the string
* or customization.
*/
addReferences(references?: Obj | Obj[], isGlobal = true): void {
if (!references) return;

View File

@ -7,7 +7,7 @@
* @property {boolean} [viewportIndex=false] Modal is dismissible via the esc key.
*/
const name = 'UIViewportDialogService';
const name = 'uiViewportDialogService';
const publicAPI = {
name,
@ -77,6 +77,7 @@ function setServiceImplementation({
export default {
REGISTRATION: {
name,
altName: 'UIViewportDialogService',
create: ({ configuration = {} }) => {
return publicAPI;
},

View File

@ -23,6 +23,7 @@ export default interface Services {
toolGroupService?: Record<string, unknown>;
uiNotificationService?: Record<string, unknown>;
uiModalService?: Record<string, unknown>;
uiViewportDialogService?: Record<string, unknown>;
viewportGridService?: ViewportGridService;
syncGroupService?: Record<string, unknown>;
cornerstoneCacheService?: Record<string, unknown>;

View File

@ -82,30 +82,29 @@ const SegmentationGroupTable = ({
activeSegmentIndex,
} = segmentation;
return (
<SegmentationGroup
id={id}
label={label}
isMinimized={isMinimized[id]}
segments={segments}
showAddSegment={showAddSegment}
segmentCount={segmentCount}
isActive={isActive}
isVisible={isVisible}
onSegmentColorClick={onSegmentColorClick}
onSegmentationClick={() => onSegmentationClick(id)}
activeSegmentIndex={activeSegmentIndex}
onToggleMinimizeSegmentation={onToggleMinimizeSegmentation}
onSegmentationEdit={onSegmentationEdit}
onSegmentationDelete={onSegmentationDelete}
onSegmentClick={onSegmentClick}
onSegmentEdit={onSegmentEdit}
onToggleSegmentVisibility={onToggleSegmentVisibility}
onToggleSegmentationVisibility={
onToggleSegmentationVisibility
}
onSegmentAdd={onSegmentAdd}
showSegmentDelete={false}
/>
<SegmentationGroup
id={id}
key={id}
label={label}
isMinimized={isMinimized[id]}
segments={segments}
showAddSegment={showAddSegment}
segmentCount={segmentCount}
isActive={isActive}
isVisible={isVisible}
onSegmentColorClick={onSegmentColorClick}
onSegmentationClick={() => onSegmentationClick(id)}
activeSegmentIndex={activeSegmentIndex}
onToggleMinimizeSegmentation={onToggleMinimizeSegmentation}
onSegmentationEdit={onSegmentationEdit}
onSegmentationDelete={onSegmentationDelete}
onSegmentClick={onSegmentClick}
onSegmentEdit={onSegmentEdit}
onToggleSegmentVisibility={onToggleSegmentVisibility}
onToggleSegmentationVisibility={onToggleSegmentationVisibility}
onSegmentAdd={onSegmentAdd}
showSegmentDelete={false}
/>
);
})}
</div>

View File

@ -35,7 +35,7 @@ const setHeaders = (res, path) => {
}
if (path.indexOf('.pdf') !== -1) {
res.setHeader('Content-Type', 'application/pdf');
} else if (path.indexOf('/frames') !== -1) {
} else if (path.indexOf('frames') !== -1) {
res.setHeader('Content-Type', 'multipart/related');
} else {
res.setHeader('Content-Type', 'application/json');

View File

@ -85,8 +85,13 @@ describe('OHIF Cornerstone Toolbar', () => {
.trigger('mousemove', 'right', { buttons: 1, force: true })
.trigger('mouseup', { buttons: 1 });
const expectedText = 'W:1930L:479';
cy.get('@viewportInfoTopLeft').should('have.text', expectedText);
// The exact text is slightly dependent on the viewport resolution, so leave a range
cy.get('@viewportInfoTopLeft').should($txt => {
const text = $txt.text();
expect(text)
.to.include('W:193')
.include('L:479');
});
});
it('checks if Pan tool will move the image inside the viewport', () => {

View File

@ -14,8 +14,9 @@ describe('OHIF MPR', () => {
});
it('should go MPR for reconstructible displaySets and come back', () => {
cy.wait(1000);
cy.wait(250);
cy.get(':nth-child(3) > [data-cy="study-browser-thumbnail"]').dblclick();
cy.wait(250);
cy.get('[data-cy="MPR"]').click();
@ -94,7 +95,7 @@ describe('OHIF MPR', () => {
});
it('should correctly render Crosshairs for MPR', () => {
cy.wait(1000);
cy.wait(250);
cy.get('[data-cy="Crosshairs"]').click();
cy.window()
@ -111,7 +112,7 @@ describe('OHIF MPR', () => {
cy.get('[data-cy="MPR"]').click();
cy.get('[data-cy="Crosshairs"]').click();
cy.wait(1000);
cy.wait(250);
// check cornerstone to see if each has crosshairs
// we can later do visual testing to match the images with a baseline

View File

@ -5,6 +5,7 @@ window.config = {
showStudyList: true,
// below flag is for performance reasons, but it might not work for all servers
omitQuotationForMultipartRequest: true,
maxNumberOfWebWorkers: 3,
showWarningMessageForCrossOrigin: false,
showCPUFallbackMessage: false,
// filterQueryParam: false,

View File

@ -9,7 +9,7 @@ window.config = {
},
],
extensions: [],
modes: [],
modes: ['@ohif/mode-test'],
showStudyList: true,
maxNumberOfWebWorkers: 4,
// below flag is for performance reasons, but it might not work for all servers

View File

@ -1407,10 +1407,10 @@
resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
"@cornerstonejs/adapters@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-0.3.1.tgz#50cfaf3de3c5a55f22f7fae1a9f6584a1c343ffa"
integrity sha512-+tqMLVYeSZjzwtzbAPqRMq5iI47nrtXz4f3GQ1jKUSmZqQyvgWRzAizcfnl6OEIrgjeg/2MHdSGOEWu12H8M+w==
"@cornerstonejs/adapters@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/adapters/-/adapters-0.4.1.tgz#fedab0d9cfea609f5219950c86e546198ad0f3c8"
integrity sha512-DQabSBdTN/A5tsncnDLdsb6LI5I/FTG3gSmNpDAkc9fAZY6Ljj0lCLt9KHB5OA1Gbvrlcab/DGJ/2YW6Z7ifRg==
dependencies:
"@babel/runtime-corejs2" "^7.17.8"
dcmjs "^0.29.4"
@ -1443,28 +1443,36 @@
resolved "https://registry.npmjs.org/@cornerstonejs/codec-openjph/-/codec-openjph-2.4.2.tgz#e96721d56f6ec96f7f95c16321d88cc8467d8d81"
integrity sha512-lgdvBvvNezleY+4pIe2ceUsJzlZe/0PipdeubQ3vZZOz3xxtHHMR1XFCl4fgd8gosR8COHuD7h6q+MwgrwBsng==
"@cornerstonejs/core@^0.32.0":
version "0.32.0"
resolved "https://registry.npmjs.org/@cornerstonejs/core/-/core-0.32.0.tgz#75fb782cc30c82642d6085d7900ec91df51aee36"
integrity sha512-Ep7b+jUO5OtRuEYRlb2Q386ZZfndAdgkDApPoTOYR+BzrwVfMF8/BEmP7UagT/bpAFk5lp5PHt/akN0qM2KR/Q==
"@cornerstonejs/core@^0.33.1":
version "0.33.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-0.33.1.tgz#dfbcad81239141c2702fd2ab0a3edbe408e7bfad"
integrity sha512-QXrnKZBEMharA/FIYqtvkTXD8JeEf742yHybNmehB1cJU1hrsjRJ1JuqXXu6IHWJFx3cAsCaWk4oZyA09OB7OQ==
dependencies:
detect-gpu "^4.0.45"
lodash.clonedeep "4.5.0"
"@cornerstonejs/streaming-image-volume-loader@^0.13.0":
version "0.13.0"
resolved "https://registry.npmjs.org/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.13.0.tgz#0b27bde776585274b6f5ab98eb2366711f8fc878"
integrity sha512-js+qaw+I5en0FR/SzJVwGY5WKfldPiVfoJvMuZb7/mNoeoi+N/U47W9WzKlCPqM81xb1mlnjXPyhVdxQ78F36Q==
"@cornerstonejs/core@^0.33.2":
version "0.33.2"
resolved "https://registry.yarnpkg.com/@cornerstonejs/core/-/core-0.33.2.tgz#63aea3eb9787622be0c75052696119a0e58117e6"
integrity sha512-iRHq7WIcZOUxOIMV9KEY7iJjTpcpk7vJPAIZM5tqVvTIbcfaACmxpTlpc2NPqT52o0shRQImIkMFiotUKx0Pug==
dependencies:
"@cornerstonejs/core" "^0.32.0"
detect-gpu "^4.0.45"
lodash.clonedeep "4.5.0"
"@cornerstonejs/streaming-image-volume-loader@^0.14.1":
version "0.14.1"
resolved "https://registry.yarnpkg.com/@cornerstonejs/streaming-image-volume-loader/-/streaming-image-volume-loader-0.14.1.tgz#9830e1cbb65aa0e050336b7f5cb9c81d23e09fc5"
integrity sha512-4m2efDbv00pFQfL/ZjnWjo4RJ3yo4ibv4J/8oro7ZrzhXUJl9L4mwdA1HYCAkS+rZQndZba138AO6b+g4nrmXQ==
dependencies:
"@cornerstonejs/core" "^0.33.1"
cornerstone-wado-image-loader "^4.10.0"
"@cornerstonejs/tools@^0.48.0":
version "0.48.0"
resolved "https://registry.npmjs.org/@cornerstonejs/tools/-/tools-0.48.0.tgz#c881866a58dd7fe5338256166630e3de633b14e7"
integrity sha512-uMrfY84m1bzVQ8I6HAkmKjZDuB3cHy9T7SWiOhXqfQGdcftkEJXYzXA6WbXDbsG8LpslnSv79Ovbx1uvH2GrWQ==
"@cornerstonejs/tools@^0.50.2":
version "0.50.2"
resolved "https://registry.yarnpkg.com/@cornerstonejs/tools/-/tools-0.50.2.tgz#0134b21016ec64290b8f9a43ac1a485654ed86eb"
integrity sha512-MedGsiisDjd2eOewhojwPpWReKM13x1krKIhPNL3hi8rZjV57T8RTpWfztxSjuUpOvapmlJXutrDPuLSUXs01g==
dependencies:
"@cornerstonejs/core" "^0.32.0"
"@cornerstonejs/core" "^0.33.2"
lodash.clonedeep "4.5.0"
lodash.get "^4.4.2"
@ -6438,11 +6446,6 @@ array-union@^2.1.0:
resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
array-union@^3.0.1:
version "3.0.1"
resolved "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975"
integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==
array-uniq@^1.0.1:
version "1.0.3"
resolved "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
@ -8463,18 +8466,6 @@ copy-text-to-clipboard@^3.0.1:
resolved "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c"
integrity sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q==
copy-webpack-plugin@^10.2.0:
version "10.2.4"
resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz#6c854be3fdaae22025da34b9112ccf81c63308fe"
integrity sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg==
dependencies:
fast-glob "^3.2.7"
glob-parent "^6.0.1"
globby "^12.0.2"
normalize-path "^3.0.0"
schema-utils "^4.0.0"
serialize-javascript "^6.0.0"
copy-webpack-plugin@^11.0.0:
version "11.0.0"
resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a"
@ -12013,18 +12004,6 @@ globby@^11.0.1, globby@^11.0.2, globby@^11.0.3, globby@^11.0.4, globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"
globby@^12.0.2:
version "12.2.0"
resolved "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22"
integrity sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==
dependencies:
array-union "^3.0.1"
dir-glob "^3.0.1"
fast-glob "^3.2.7"
ignore "^5.1.9"
merge2 "^1.4.1"
slash "^4.0.0"
globby@^13.1.1:
version "13.1.3"
resolved "https://registry.npmjs.org/globby/-/globby-13.1.3.tgz#f62baf5720bcb2c1330c8d4ef222ee12318563ff"
@ -12757,7 +12736,7 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
ignore@^5.0.0, ignore@^5.1.1, ignore@^5.1.8, ignore@^5.1.9, ignore@^5.2.0:
ignore@^5.0.0, ignore@^5.1.1, ignore@^5.1.8, ignore@^5.2.0:
version "5.2.4"
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==