All files / extensions/cornerstone/src/utils nthLoader.ts

93.33% Statements 28/30
50% Branches 1/2
100% Functions 6/6
93.1% Lines 27/29

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          34x 34x                             9x       9x 9x 9x   9x           9x 9x 9x       9x   9x 9x         9x 9x 9x   9x     9x   9x 9x   9x 462x   462x       9x     9x     9x   9x    
import { cache, imageLoadPoolManager, Enums } from '@cornerstonejs/core';
import getNthFrames from './getNthFrames';
import interleave from './interleave';
 
// Map of volumeId and SeriesInstanceId
const volumeIdMapsToLoad = new Map<string, string>();
const viewportIdVolumeInputArrayMap = new Map<string, unknown[]>();
 
/**
 * This function caches the volumeUIDs until all the volumes inside the
 * hanging protocol are initialized. Then it goes through the requests and
 * chooses a sub-selection starting the the first few objects, center objects
 * and last objects, and then the remaining nth images until all instances are
 * retrieved.  This causes the image to have a progressive load order and looks
 * visually much better.
 * @param {Object} props image loading properties from Cornerstone ViewportService
 */
export default function interleaveNthLoader({
  data: { viewportId, volumeInputArray },
  displaySetsMatchDetails,
}) {
  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) {
      console.log("interleaveNthLoader::No volume, can't load it");
      return;
    }
 
    // if the volumeUID is not in the volumeUIDs array, add it
    if (!volumeIdMapsToLoad.has(volumeId)) {
      const { metadata } = volume;
      volumeIdMapsToLoad.set(volumeId, metadata.SeriesInstanceUID);
    }
  }
 
  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 originalRequests = volumes
    .map(volume => volume.getImageLoadRequests())
    .filter(requests => requests?.[0]?.imageId);
 
  const orderedRequests = originalRequests.map(request => getNthFrames(request));
 
  // set the finalRequests to the imageLoadPoolManager
  const finalRequests = interleave(orderedRequests);
 
  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;
}