Viewers
Viewers copied to clipboard
2D MPR shows blank for some of the viewers sometime
Sample dataset in private slack channel here: https://cornerstonejs.slack.com/archives/GP0DDMVMF/p1658429196108019
Upon further examination, this specific URL appears to cause the issue per @wlongabaugh: https://testing-proxy.canceridc.dev/v1/projects/canceridc-data/locations/us/datasets/idc/dicomStores/v9-viewer-only-no-downloads-see-tinyurl-dot-com-slash-3j3d9jyp/dicomWeb/studies/1.3.6.1.4.1.14519.5.2.1.163047965868107465659169009295180558950/series/undefined/metadata.
Could it be that there is some missing reference to a series somewhere that breaks some assumption?
I think the proxy URL given above is for a different issue, see #2849
@GitanjaliChhetri
This is a bug in vtk rendering at the default sliceNormal position [1,0,0] for the sagittal view. Either we fix this in vtk or a hack to fix this from the OHIF side would be to initialize the sliceNormal with a slight rotation while setting up the 2d MPR viewports. So, that would be modifying the sliceNormal [1,0,0] to [0.9999, 0.0001, 0]. Additionally, the vtk extension of OHIFv-2 uses an old version(11.14.0). I tried upgrading it to the latest version, but unfortunately it is not backward compatible.
@GitanjaliChhetri Can you detect the situation that leads to the issue with the sliceNormal? It sounds like the problem is that the vectors are parallel leading to a degenerate view, possibly when calculating a cross product. In such cases it's often possible to pick a different vector, say 90 degrees off, and use it in the calculation with the desired result. Such a fix would be more robust than adding some fuzz to the vector (which could fail in other cases). What do you think?
@GitanjaliChhetri Can you detect the situation that leads to the issue with the sliceNormal? It sounds like the problem is that the vectors are parallel leading to a degenerate view, possibly when calculating a cross product. In such cases it's often possible to pick a different vector, say 90 degrees off, and use it in the calculation with the desired result. Such a fix would be more robust than adding some fuzz to the vector (which could fail in other cases). What do you think?
@GitanjaliChhetri can you also check if the issue persists if you make a 180 degree camera rotation? i.e. sliceNormal = [-1,0,0], cameraPosition = -oldCameraPosition, please?
@pieper @fedorov, the issue is in VTK redendering, so we would need to debug it internally in VTK. Since this will imply also to update the VTK extension to latest VTK (which is not backward compatible with the OHIF-v2 extension) before applying any fix, fixing the issue in VTK may take some time. Shall Gitanjali proceed with it?
@Punzo I still would like to confirm that there's not a fix in ohif that is more robust than just fuzzing the vector and does not require a full update of VTK. @GitanjaliChhetri can you comment on whether the there's a 90 or 180 rotation option that works around the issue robustly?
@pieper I tested with 180deg rotation option, and the issue still persists. I think we need to look into the vtk side on why it's unable to render with the default sliceNormal value for the sagittal view. I have checked all the related camera settings on the OHIF side and everything looks fine. And for the 90deg rotation around either axes will end up rendering in either axial or coronal plane. So, it's either the hack of applying a slight rotation in the xy plane or we look into the vtk side.
Thank you for investigating @GitanjaliChhetri . One other question: have you determined what is different about this particular scan that makes the sagittal view fail while other scans do not?
My guess it that it has to do with the image orientation of the acquisition. Perhaps the images where acquired in the sagittal plane and this is a special case that needs to be accounted for (this is what I meant by constructing the camera parameters by picking a different cardinal direction).
@pieper I did check the IOP tag for the two axial scans with which the issue occurs. The value isnt exactly identity, the axial scan plane is slightly tilted. For ex. for the study linked in this bug has a value of [1,-2.051034e-10,0,2.051034e-10,1,0]. However, there are other axial (and also coronal) studies with similar slightly oblique scan axes and the 2d mpr works fine for them.
Interesting - that looks like rounding error to me (maybe the scans were converted from nifti, with the 32-bit float header issue). Since the diagonal elements are 1 it's not a rotation. Maybe we could try orthogonalizing the matrix before rendering.
Thanks @pieper , orthogonalizing the vector before rendering works!
So far, I have found two studies with this issue. For the other study, the IOP tag reads: [ 1, -2.01861902193734e-10, 3.632069991987841e-11 2.0510340648094427e-10, 0.9841955900192261, -0.17708474397659302 ]
As you can see there's a considerable amount of rotation here, however each of the scan axis' largest component is considerably larger than the other components. Orthogonalizing solves the issue in this case as well.
If we want do want to go with this approach then how should we handle other oblique scan orientations? for example, in case of a considerably large oblique angle? I assume such acquisitions are not that common...
Great, thanks for digging in more!
What method did you use to orthogonalize?
That IOP looks like a valid rotation and the question is if the third vector of the rotation matrix is calculated. Typically one looks at the vectors of Image Position Patient going from slice to slice. These IPP vectors should be parallel to the cross product of the IOP vectors. We need to be able to handle oblique acquisitions correctly.
For orthogonalizing, I am using vtkMath.orthogonalize3x3(). However, if the IPP matrix has the 32-bit float header issue as you mentioned, then there is still some precision error after orthogonalizing, which can be handled by first correcting for the 32float array and then orthogonalizing.
For the dataset with a valid rotation, the rotation angle is 179.985050. It is a small angle. Should we have a threshold for the rotation angle to support only certain oblique datasets?
It looks to me like the method is doing the correct thing by preserving the pure rotation and possible flip while removing any other parts. The rest of the MPR should always work with a rotated dataset so I would not want any threshold.
https://github.com/Kitware/vtk-js/blob/ffdb65acbc9ebad60f0299d41025da5a86f8bb88/Sources/Common/Core/Math/index.js#L1007-L1097
@GitanjaliChhetri next step would be opening a PR. Then Steve and I can review, thanks!