All files / tools/src/utilities/segmentation getUniqueSegmentIndices.ts

0% Statements 0/44
0% Branches 0/22
0% Functions 0/13
0% Lines 0/43

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                                                                                                                                                                                                                             
import type { Types } from '@cornerstonejs/core';
import { cache } from '@cornerstonejs/core';
import { SegmentationRepresentations } from '../../enums';
import { getCachedSegmentIndices, setCachedSegmentIndices } from './utilities';
import { getSegmentation } from '../../stateManagement/segmentation/getSegmentation';
 
/**
 * Retrieves the unique segment indices from a given segmentation.
 *
 * @param segmentationId - The ID of the segmentation.
 * @returns An array of unique segment indices.
 * @throws If no geometryIds are found for the segmentationId.
 */
function getUniqueSegmentIndices(segmentationId) {
  // Attempt to fetch from cache first
  const cachedResult = getCachedSegmentIndices(segmentationId);
  if (cachedResult) {
    return cachedResult;
  }
 
  const segmentation = getSegmentation(segmentationId);
  if (!segmentation) {
    throw new Error(
      `No segmentation found for segmentationId ${segmentationId}`
    );
  }
 
  let indices;
  if (segmentation.representationData.Labelmap) {
    indices = handleLabelmapSegmentation(segmentation, segmentationId);
  } else if (segmentation.representationData.Contour) {
    indices = handleContourSegmentation(segmentation);
  } else if (segmentation.representationData.Surface) {
    indices = handleSurfaceSegmentation(segmentation);
  } else {
    throw new Error(
      `Unsupported segmentation type: ${segmentation.representationData}`
    );
  }
 
  // Update cache
  setCachedSegmentIndices(segmentationId, indices);
 
  return indices;
}
 
function handleLabelmapSegmentation(segmentation, segmentationId) {
  const labelmapData =
    segmentation.representationData[SegmentationRepresentations.Labelmap];
  const keySet = new Set();
 
  if (labelmapData.imageIds) {
    addImageSegmentIndices(keySet, labelmapData.imageIds);
  } else {
    addVolumeSegmentIndices(keySet, segmentationId);
  }
 
  return Array.from(keySet)
    .map(Number)
    .sort((a, b) => a - b);
}
 
function addVolumeSegmentIndices(keySet, segmentationId) {
  const volume = cache.getVolume(segmentationId);
  volume.voxelManager.forEach(({ value }) => {
    if (value !== 0) {
      keySet.add(value);
    }
  });
}
 
function addImageSegmentIndices(keySet, imageIds) {
  imageIds.forEach((segmentationImageId) => {
    const image = cache.getImage(segmentationImageId);
    const scalarData = image.voxelManager.getScalarData();
    scalarData.forEach((segmentIndex) => {
      if (segmentIndex !== 0) {
        keySet.add(segmentIndex);
      }
    });
  });
}
 
function handleContourSegmentation(segmentation) {
  const { annotationUIDsMap, geometryIds } =
    segmentation.representationData.Contour || {};
  if (!geometryIds) {
    throw new Error(
      `No geometryIds found for segmentationId ${segmentation.segmentationId}`
    );
  }
 
  const indices = new Set([...annotationUIDsMap.keys()]);
  geometryIds.forEach((geometryId) => {
    const geometry = cache.getGeometry(geometryId);
    indices.add((geometry.data as Types.IContourSet).segmentIndex);
  });
 
  return Array.from(indices).sort((a, b) => a - b);
}
 
function handleSurfaceSegmentation(segmentation) {
  const geometryIds =
    segmentation.representationData.Surface?.geometryIds ?? [];
  return Array.from(geometryIds.keys())
    .map(Number)
    .sort((a, b) => a - b);
}
 
export { getUniqueSegmentIndices };