Cannot destructure property 'pixelRepresentation'
When I use wadouri in volume type and then invoke volumeLoader.createAndCacheVolume , it will throw this error. Stack type is okay

@zixiCat I think you may not add the metadata into the cornerstoneWADOImageLoader.
you need to add the metadata to cornerstoneWADOImageLoader first before creating a volume
you can use a function similar to this
cacheMetaData: async function (series) {
let wadoRsRoot = `${window.location.origin}/dicom-web`;
const client = new dicomwebClient.api.DICOMwebClient({ url: wadoRsRoot });
const studyInstanceUID = series["0020000D"]["Value"][0];
const seriesInstanceUID = series["0020000E"]["Value"][0];
let instances = await client.retrieveSeriesMetadata({
studyInstanceUID: studyInstanceUID,
seriesInstanceUID: seriesInstanceUID,
});
const imageIds = instances.map((instanceMetaData) => {
const SeriesInstanceUID = instanceMetaData["0020000E"].Value[0];
const SOPInstanceUID = instanceMetaData["00080018"].Value[0];
const prefix = "wadors:";
const imageId = `${prefix}${wadoRsRoot}/studies/${studyInstanceUID}/series/${SeriesInstanceUID}/instances/${SOPInstanceUID}/frames/1`;
cornerstoneWADOImageLoader.wadors.metaDataManager.add(imageId, instanceMetaData);
return imageId;
});
return imageIds;
},
You can then pass the returned imageIds to createAndCacheVolume.
@IbrahimCSAE
I mean I want to display local dicom files by using wadouri prefix, not wadors , is there any way to get these UID?(studyInstanceUID, seriesInstanceUID)
I don't know the exact process, but I think that they need to be loaded into memory and parsed first, I don't think you can just pass the disk location of the file to the function
I've used this method before and it didn't work, whether I use "streaming" or not, but thanks
------------------ 原始邮件 ------------------ 发件人: @.>; 发送时间: 2022年8月27日(星期六) 中午1:42 收件人: @.>; 抄送: @.>; @.>; 主题: Re: [cornerstonejs/cornerstone3D-beta] Cannot destructure property 'pixelRepresentation' (Issue #180)
@IbrahimCSAE I mean I want to display local dicom files by using wadouri prefix, not wadors , is there any way to get these UID?(studyInstanceUID, seriesInstanceUID)
You might need to do something like this this let imageIds = [] let imageId = cornerstoneWADOImageLoader.wadouri.fileManager.add(file); imageIds.push(imageId)
then you pass that array of imageIds to the volumeLoader, and try making the scheme 'wadouri' without the word streaming.
I didn't try this so I'm not sure if it will work, I usually don't work with local dicoms. If you can post your code here I can try to modify it and make it work.
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>
Hey, I have the same problem but in production, in my local i don't have this problem.
here I call my custom method createImageIdsAndCacheMetaData
await initProviders();
await initCornerstoneWADOImageLoader()
await initVolumeLoader()
await cornerstone3D.init();
await cornerstone3DTools.init();
const imageIds = await createImageIdsAndCacheMetaData({
StudyInstanceUID: caseId,
SeriesInstanceUID: imageId,
wadoRsRoot: process.env.REACT_APP_WADO_RS_ROOT,
type: 'VOLUME',
});
// Define a volume in memory
const volume = await volumeLoader.createAndCacheVolume(volumeId, {
imageIds,
});
and in that method I insert the metadata:
const client = new api.DICOMwebClient({ url: wadoRsRoot });
const instances = await client.retrieveSeriesMetadata(studySearchOptions);
const modality = instances[0][MODALITY].Value[0];
const imageIds = instances.map((instanceMetaData) => {
const SeriesInstanceUID = instanceMetaData[SERIES_INSTANCE_UID].Value[0];
const SOPInstanceUID = instanceMetaData[SOP_INSTANCE_UID].Value[0];
const prefix = type === VOLUME ? 'streaming-wadors:' : 'wadors:';
const imageId =
prefix +
wadoRsRoot +
'/studies/' +
StudyInstanceUID +
'/series/' +
SeriesInstanceUID +
'/instances/' +
SOPInstanceUID +
'/frames/1';
cornerstoneWADOImageLoader.wadors.metaDataManager.add(
imageId,
instanceMetaData
);
WADORSHeaderProvider.addInstance(imageId, instanceMetaData);
// Add calibrated pixel spacing
const m = JSON.parse(JSON.stringify(instanceMetaData));
const instance = DicomMetaDictionary.naturalizeDataset(m);
const pixelSpacing = getPixelSpacingInformation(instance);
calibratedPixelSpacingMetadataProvider.add(
imageId,
pixelSpacing.map((s) => parseFloat(s))
);
return imageId;
});
idk if it's a cache thing because in my local server works but in production this messages jumps out 😢
Hey, I have the same problem but in production, in my local i don't have this problem.
here I call my custom method createImageIdsAndCacheMetaData
await initProviders(); await initCornerstoneWADOImageLoader() await initVolumeLoader() await cornerstone3D.init(); await cornerstone3DTools.init(); const imageIds = await createImageIdsAndCacheMetaData({ StudyInstanceUID: caseId, SeriesInstanceUID: imageId, wadoRsRoot: process.env.REACT_APP_WADO_RS_ROOT, type: 'VOLUME', }); // Define a volume in memory const volume = await volumeLoader.createAndCacheVolume(volumeId, { imageIds, });and in that method I insert the metadata:
const client = new api.DICOMwebClient({ url: wadoRsRoot }); const instances = await client.retrieveSeriesMetadata(studySearchOptions); const modality = instances[0][MODALITY].Value[0]; const imageIds = instances.map((instanceMetaData) => { const SeriesInstanceUID = instanceMetaData[SERIES_INSTANCE_UID].Value[0]; const SOPInstanceUID = instanceMetaData[SOP_INSTANCE_UID].Value[0]; const prefix = type === VOLUME ? 'streaming-wadors:' : 'wadors:'; const imageId = prefix + wadoRsRoot + '/studies/' + StudyInstanceUID + '/series/' + SeriesInstanceUID + '/instances/' + SOPInstanceUID + '/frames/1'; cornerstoneWADOImageLoader.wadors.metaDataManager.add( imageId, instanceMetaData ); WADORSHeaderProvider.addInstance(imageId, instanceMetaData); // Add calibrated pixel spacing const m = JSON.parse(JSON.stringify(instanceMetaData)); const instance = DicomMetaDictionary.naturalizeDataset(m); const pixelSpacing = getPixelSpacingInformation(instance); calibratedPixelSpacingMetadataProvider.add( imageId, pixelSpacing.map((s) => parseFloat(s)) ); return imageId; });idk if it's a cache thing because in my local server works but in production this messages jumps out 😢
Do u have a demo link where the error pops up?
Yes there is a link but is not public yet, I have to give you the credentials.
However, I'm printing the naturalizedDataset variable in WADORSHeaderProvider and print all the metadata variables correctly:
-- Production (with the error)

-- Same thing in development ( no error )

Yes there is a link but is not public yet, I have to give you the credentials.
However, I'm printing the naturalizedDataset variable in WADORSHeaderProvider and print all the metadata variables correctly:
-- Production (with the error)
-- Same thing in development ( no error )
in the makeVolumeMetadata.ts file
export default function makeVolumeMetadata(
imageIds: Array<string>
): Types.Metadata {
const imageId0 = imageIds[0];
const {
pixelRepresentation,
bitsAllocated,
bitsStored,
highBit,
photometricInterpretation,
samplesPerPixel,
} = metaData.get('imagePixelModule', imageId0);
Try placing a breakpoint here, whats the value of imageId0 ? does it match the imageId you created in createImageIdsAndCacheMetaData method?
The only way I see this happening in production and not development is if something causes the ImageIds to be messed up or if the metadataprovider is not being registered
Also the
const prefix = type === VOLUME ? 'streaming-wadors:' : 'wadors:';
is there a variable VOLUME defined somewhere? if not it should be 'VOLUME' as a string
Yep, it match 😢
this is the first imageId resulting of createImageIdsAndCacheMetaData function
and this is the imageIds object of makeVolumeMetadata
I will attach the run function, but it's the same of one of the examples.
/* -- VOLUME -- */
const viewportId1 = 'CT_AXIAL';
const viewportId2 = 'CT_SAGITTAL';
const viewportId3 = 'CT_CORONAL';
const viewportColors = {
[viewportId1]: 'rgb(200, 0, 0)', [viewportId2]: 'rgb(200, 200, 0)', [viewportId3]: 'rgb(0, 200, 0)',
};
const viewportReferenceLineControllable = [
viewportId1, viewportId2, viewportId3,
];
const viewportReferenceLineDraggableRotatable = [
viewportId1, viewportId2, viewportId3,
];
const viewportReferenceLineSlabThicknessControlsOn = [
viewportId1, viewportId2, viewportId3,
];
const getReferenceLineColor = (viewportId) => {
return viewportColors[viewportId];
}
const getReferenceLineControllable = (viewportId) => {
const index = viewportReferenceLineControllable.indexOf(viewportId);
return index !== -1;
}
const getReferenceLineDraggableRotatable = (viewportId) => {
const index = viewportReferenceLineDraggableRotatable.indexOf(viewportId);
return index !== -1;
}
const getReferenceLineSlabThicknessControlsOn = (viewportId) => {
const index =
viewportReferenceLineSlabThicknessControlsOn.indexOf(viewportId);
return index !== -1;
}
const volumeLoaderScheme = 'cornerstoneStreamingImageVolume'; // Loader id which defines which volume loader to use
const ctVolumeName = 'CT_VOLUME_ID'; // Id of the volume less loader prefix
const volumeId = `${volumeLoaderScheme}:${ctVolumeName}`; // VolumeId with loader id + volume id
export const runVolume = async (
cornerstone3D,
cornerstone3DTools,
imageId,
caseId,
viewerRef1,
viewerRef2,
viewerRef3
) => {
const {
CONSTANTS, RenderingEngine, setVolumesForViewports, volumeLoader, metaData
} = cornerstone3D;
const {
ToolGroupManager, StackScrollMouseWheelTool, CrosshairsTool, Enums: csToolsEnums, WindowLevelTool, PanTool, ZoomTool
} = cornerstone3DTools;
const { MouseBindings } = csToolsEnums;
const { ViewportType } = cornerstone3D.Enums;
const { ORIENTATION } = CONSTANTS;
const toolGroupId = 'TOOLGROUP_ID';
await initProviders();
await initCornerstoneWADOImageLoader()
await initVolumeLoader()
await cornerstone3D.init();
await cornerstone3DTools.init();
const imageIds = await createImageIdsAndCacheMetaData({
StudyInstanceUID: caseId,
SeriesInstanceUID: imageId,
wadoRsRoot: process.env.REACT_APP_WADO_RS_ROOT,
type: 'VOLUME',
});
// Define a volume in memory
const volume = await volumeLoader.createAndCacheVolume(volumeId, {
imageIds,
});
// Instantiate a rendering engine
const renderingEngineId = 'myRenderingEngine';
const renderingEngine = new RenderingEngine(renderingEngineId);
// Create the viewports
if (
viewerRef1.current && viewerRef2.current && viewerRef3.current
) {
const viewportInputArray = [
{
viewportId: viewportId1,
type: ViewportType.ORTHOGRAPHIC,
element: viewerRef1.current,
defaultOptions: {
orientation: ORIENTATION.AXIAL,
background: [0, 0, 0],
},
},
{
viewportId: viewportId2,
type: ViewportType.ORTHOGRAPHIC,
element: viewerRef2.current,
defaultOptions: {
orientation: ORIENTATION.SAGITTAL,
background: [0, 0, 0],
},
},
{
viewportId: viewportId3,
type: ViewportType.ORTHOGRAPHIC,
element: viewerRef3.current,
defaultOptions: {
orientation: ORIENTATION.CORONAL,
background: [0, 0, 0],
},
},
];
renderingEngine.setViewports(viewportInputArray);
}
// Set the volume to load
volume.load();
// Set volumes on the viewports
await setVolumesForViewports(
renderingEngine,
[
{
volumeId,
callback: setCtTransferFunctionForVolumeActor,
},
],
[viewportId1, viewportId2, viewportId3]
);
let toolGroup = ToolGroupManager.getToolGroup(toolGroupId);
if (!toolGroup) {
toolGroup = ToolGroupManager.createToolGroup(toolGroupId);
}
// For the crosshairs to operate, the viewports must currently be
// added ahead of setting the tool active. This will be improved in the future.
toolGroup.addViewport(viewportId1, renderingEngineId);
toolGroup.addViewport(viewportId2, renderingEngineId);
toolGroup.addViewport(viewportId3, renderingEngineId);
// Manipulation Tools
toolGroup.addTool(StackScrollMouseWheelTool.toolName);
toolGroup.addTool(WindowLevelTool.toolName);
toolGroup.addTool(PanTool.toolName);
toolGroup.addTool(ZoomTool.toolName);
// Add Crosshairs tool and configure it to link the three viewports
// These viewports could use different tool groups. See the PET-CT example
// for a more complicated used case.
toolGroup.addTool(CrosshairsTool.toolName, {
getReferenceLineColor,
getReferenceLineControllable,
getReferenceLineDraggableRotatable,
getReferenceLineSlabThicknessControlsOn,
});
toolGroup?.setToolActive(CrosshairsTool.toolName, {
bindings: [{ mouseButton: MouseBindings.Primary }],
});
// As the Stack Scroll mouse wheel is a tool using the `mouseWheelCallback`
// hook instead of mouse buttons, it does not need to assign any mouse button.
toolGroup?.setToolActive(StackScrollMouseWheelTool.toolName);
// Render the image
await renderingEngine.renderViewports([viewportId1, viewportId2, viewportId3]);
}
I mean I want to display local dicom files by using wadouri prefix, not wadors , is there any way to get these UID?(studyInstanceUID, seriesInstanceUID)
WADO-URI or just "DICOM Part 10 over HTTP" isn't supported out the of box by the Cornerstone3D libraries.
You need to use a WADO-RS compliant endpoint to fetch the metadata ahead of time, and then WADO-RS retrieve frames for the URLs.
Or you could write your own loader for all of this, but its not recommended for MPR for the reasons outlined here.