Closed sedghi closed 10 months ago
It is the same issue in the v2 as well, so definitely the metadata provider of OHIF getting those metadata from instance somehow wrong
Seems like in the cs3d demos we are adding metadata to the wado rs metadata manager via
But OHIF doesn't do that since we use the naturalized instance via dcmjs to store metadata. So we need to see what is happening there
Hi @sedghi
I have been testing my own viewer with cornerstone3d using both the old wado image loader 3.3.2 and the new one 4.8.x +
I encountered several instances of this problem when the window level / center values for CT images were an array of different values. metadata was ok but createImage in image loader may be responsible. I never debug the problem beyond a user interface.
I only encountered this with 3.3.2, every version > 4 worked
Thanks @heyflynn , we will look into this, can you be more specific which version worked? You are saying every version of wado loader > 4 works? I'm confused
yes. every version > 4 this was OK. I created a simple app that loaded old cornerstonejs, new cornerstone3d and the small dicom.ts renderer.
"cornerstone-wado-image-loader": "^3.0.0",
"cornerstone-wado-image-loader": "^4.10.0",
@sedghi, some dicom metadata stores the initial WW/WL in a different tag (sharedFunctionalGroupsSequence), is the correct initial ww/wl values stored here for the image?
let center, width;
try {
const sharedFunctionalGroupsSequence = dataSet.elements.x52009229;
const frameVOILUTSequence = sharedFunctionalGroupsSequence.items[0];
const frameDataset = frameVOILUTSequence.dataSet.elements.x00289132;
const windowDataset = frameDataset.items[0].dataSet;
center = getNumberValues(windowDataset, 'x00281050', 1);
width = getNumberValues(windowDataset, 'x00281051', 1);
} catch {
center = getNumberValues(dataSet, 'x00281050', 1);
width = getNumberValues(dataSet, 'x00281051', 1);
}
sharedFunctionalGroupsSequence
is for multiframe data, but this is happening even for the regular dicom files.
@heyflynn I guess you don't have OHIF right? since it works fine inside cs3d, but NOT in OHIF. I expect the problem is the fact that in the cs3d demo we use wadors metadataManager but OHIF uses its own metadata provider which has priority and OHIF metadataProvider is based on naturalized instance of dcmjs
I don't have OHIF. I downloaded your files and tested them ok on both 3 and 4 of CWIL so I assume they are unrelated issues.
Hi @sedghi
I gave this a look. I'm not sure if it's a bug, but maybe because cornerstone3D/OHIF is using the WW/WL of the first image in the stack? I also verified dcmjs values and they look correct, so it's not dcmjs.
MR.1.3.12.2.1107.5.2.32.35162.1999123112191238865917962
It has really different WW/WL and I believe it is at the start of stack, it's WL/WW is 35/99, which matches OHIF
If you drop it into https://www.cornerstonejs.org/live-examples/local.html, you will see the same WW/WL from OHIF too.
I think cornerstone3D is causing the problem since it doesn't update the WL/WW from the metadata for each image, it's always using the first image? (should it be different for each image? RadiAnt does it that way)
this method called this._setPropertiesFromCache();
sets the WL/WW to the first image always, isn't this supposed to be updated for each imageId?
I removed it and added this part copied from after the if condition in the original code above ^
const {
imagePixelModule,
} = this._getImageDataMetadata(image);
const { windowCenter, windowWidth, voiLUTFunction } = imagePixelModule;
let voiRange =
typeof windowCenter === 'number' && typeof windowWidth === 'number'
? windowLevelUtil.toLowHighRange(windowWidth, windowCenter)
: undefined;
const isPreScaled =
this.csImage.isPreScaled || this.csImage.preScale?.scaled;
if (imagePixelModule.modality === 'PT' && isPreScaled) {
voiRange = { lower: 0, upper: 5 };
}
this.initialVOIRange = voiRange;
if (this.voiApplied && typeof voiRange === 'undefined') {
voiRange = this.voiRange;
}
if (Object.values(VOILUTFunctionType).indexOf(voiLUTFunction) === -1) {
this.VOILUTFunction = VOILUTFunctionType.LINEAR;
} else {
this.VOILUTFunction = voiLUTFunction;
}
this.setProperties({ voiRange });
return;
now OHIF looks like this
which behaves like RadiAnt viewer that I used as a reference. you will notice the WW/WL value change in the viewer overlay.
A fix can be added to _checkVTKImageDataMatchesCornerstoneImage()
so it checks for the WW/WL everytime and returns false if different? right now this returns true since it doesn’t check for that.
this problem is also in the other cornerstone that isn't 3D, same behavior somewhere in the rendering functions, so I'm not sure if this really a problem, looks like it's done this way intentionally in cornerstone/cornerstone3D (use first image in stack always)?
If the value is supposed to match the first imageId always then i think there's nothing wrong with cornerstone3D/cornerstone or OHIF?, it's just the first image in the stack looks like that.
RadiAnt initially uses the values for each image, but if a user selects a custom WL/WW, then that's when it makes it uniform for everything
@IbrahimCSAE great debugging, I came across the same conclusion yesterday as well. Interesting that you confirmed it now! We decided to apply a per-slice ww/wl on each image for the stack viewport. and as soon as the user modifies it it becomes global for the stack and later when reset happens we go back to per slice.
Great! Happy to help.
Seems like our stack viewport has a wrong initial voi set.
For instance for this study https://www.dropbox.com/sh/j6mxoutxb4x3moh/AAB69hV6SfvxYj06YsuHlaoza?dl=0
Drag and drop one instance into the https://www.cornerstonejs.org/live-examples/local.html
it works correctly![image](https://user-images.githubusercontent.com/7490180/220710656-9b933818-a0bd-466f-b4b6-e79a7ce81c93.png)
But dragging and dropping it into the v3-demo.ohif.org/local (or local server)
Since it works in cs3d, and not in OHIF, I expect the metadata provider of OHIF metadata for windowlevel and width is different than what cs3d has