Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | 67x 67x 8x 8x 8x 8x 8x 8x 4x 4x 8x 8x 20x 20x 20x 8x 8x 80x 80x 104x 8x 6x 2x 2x 4x 2x 2x 4x 4x 4x 2x 2x 2x 188x 188x 13348x 376x 188x 2x 2x 2x 188x 188x 2x 2x 2x 2x | import { cache, imageLoadPoolManager, Enums } from '@cornerstonejs/core';
import zip from 'lodash.zip';
import compact from 'lodash.compact';
import flatten from 'lodash.flatten';
// Map of volumeId and SeriesInstanceId
const volumeIdMapsToLoad = new Map<string, string>();
const viewportIdVolumeInputArrayMap = new Map<string, unknown[]>();
/**
* This function caches the volumeIds until all the volumes inside the
* hanging protocol are initialized. Then it goes through the imageIds
* of the volumes, and interleave them, in order for the volumes to be loaded
* together from middle to the start and the end.
* @param {Object} {viewportData, displaySetMatchDetails}
* @returns
*/
export default function interleaveTopToBottom({
data: { viewportId, volumeInputArray },
displaySetsMatchDetails,
viewportMatchDetails: matchDetails,
}) {
viewportIdVolumeInputArrayMap.set(viewportId, volumeInputArray);
// Based on the volumeInputs store the volumeIds and SeriesInstanceIds
// to keep track of the volumes being loaded
for (const volumeInput of volumeInputArray) {
const { volumeId } = volumeInput;
const volume = cache.getVolume(volumeId);
Iif (!volume) {
return;
}
// if the volumeUID is not in the volumeUIDs array, add it
if (!volumeIdMapsToLoad.has(volumeId)) {
const { metadata } = volume;
volumeIdMapsToLoad.set(volumeId, metadata.SeriesInstanceUID);
}
}
/**
* The following is checking if all the viewports that were matched in the HP has been
* successfully created their cornerstone viewport or not. Todo: This can be
* improved by not checking it, and as soon as the matched DisplaySets have their
* volume loaded, we start the loading, but that comes at the cost of viewports
* not being created yet (e.g., in a 10 viewport ptCT fusion, when one ct viewport and one
* pt viewport are created we have a guarantee that the volumes are created in the cache
* but the rest of the viewports (fusion, mip etc.) are not created yet. So
* we can't initiate setting the volumes for those viewports. One solution can be
* to add an event when a viewport is created (not enabled element event) and then
* listen to it and as the other viewports are created we can set the volumes for them
* since volumes are already started loading.
*/
const uniqueViewportVolumeDisplaySetUIDs = new Set();
viewportIdVolumeInputArrayMap.forEach((volumeInputArray, viewportId) => {
volumeInputArray.forEach(volumeInput => {
const { volumeId } = volumeInput;
uniqueViewportVolumeDisplaySetUIDs.add(volumeId);
});
});
const uniqueMatchedDisplaySetUIDs = new Set();
matchDetails.forEach(matchDetail => {
const { displaySetsInfo } = matchDetail;
displaySetsInfo.forEach(({ displaySetInstanceUID }) => {
uniqueMatchedDisplaySetUIDs.add(displaySetInstanceUID);
});
});
if (uniqueViewportVolumeDisplaySetUIDs.size !== uniqueMatchedDisplaySetUIDs.size) {
return;
}
const volumeIds = Array.from(volumeIdMapsToLoad.keys()).slice();
// get volumes from cache
const volumes = volumeIds.map(volumeId => {
return cache.getVolume(volumeId);
});
// iterate over all volumes, and get their imageIds, and interleave
// the imageIds and save them in AllRequests for later use
const AllRequests = [];
volumes.forEach(volume => {
const requests = volume.getImageLoadRequests();
Iif (!requests?.[0]?.imageId) {
return;
}
// reverse the requests
AllRequests.push(requests.reverse());
});
// flatten the AllRequests array, which will result in a list of all the
// imageIds for all the volumes but interleaved
const interleavedRequests = compact(flatten(zip(...AllRequests)));
// set the finalRequests to the imageLoadPoolManager
const finalRequests = [];
interleavedRequests.forEach(request => {
const { imageId } = request;
AllRequests.forEach(volumeRequests => {
const volumeImageIdRequest = volumeRequests.find(req => req.imageId === imageId);
if (volumeImageIdRequest) {
finalRequests.push(volumeImageIdRequest);
}
});
});
const requestType = Enums.RequestType.Prefetch;
const priority = 0;
finalRequests.forEach(({ callLoadImage, additionalDetails, imageId, imageIdIndex, options }) => {
const callLoadImageBound = callLoadImage.bind(null, imageId, imageIdIndex, options);
imageLoadPoolManager.addRequest(callLoadImageBound, requestType, additionalDetails, priority);
});
// clear the volumeIdMapsToLoad
volumeIdMapsToLoad.clear();
// copy the viewportIdVolumeInputArrayMap
const viewportIdVolumeInputArrayMapCopy = new Map(viewportIdVolumeInputArrayMap);
// reset the viewportIdVolumeInputArrayMap
viewportIdVolumeInputArrayMap.clear();
return viewportIdVolumeInputArrayMapCopy;
}
|