All files / packages/tools/src/utilities/contours/interpolation getInterpolationData.ts

84.84% Statements 28/33
56% Branches 14/25
85.71% Functions 6/7
83.87% Lines 26/31

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              1x                                                                       13x 13x 13x 13x     13x             21x           13x 13x       13x                         13x       13x 54x 88x     54x 33x     21x   21x 33x     33x 33x 36x   21x         21x 21x       13x    
import type {
  InterpolationViewportData,
  Annotation,
  ContourSegmentationAnnotation,
} from '../../../types';
import { getAnnotations } from '../../../stateManagement/annotation/annotationState';
 
const DEFAULT_CONTOUR_SEG_TOOLNAME = 'PlanarFreehandContourSegmentationTool';
 
export type FilterParam = {
  /**
   * Selects a parent value from the given annotation to get the comparison values from.
   * Was originally a key name, but this became too limited to match multiple levels
   * of selection, so was changed to a function returning the values.
   */
  parentKey?: (annotation) => any;
 
  /**
   * The attribute to extract the value from the parent object, compared with
   * value to see if the filter matches.
   */
  key: string;
 
  /**
   * The comparison value to compare against.  If an array, will compare sub-values.
   */
  value: unknown;
};
 
/**
 * getInterpolationData - Gets the list of the slice locations of the 2D
 * polygons that make up the interpolated annotation, along with the annotations
 * which match the specified filterParams on that slice.
 *
 * @param viewportData - the annotation/viewport to start the interpolation from
 * @param filterParams - A selector for annotations for interpolation
 * @returns The list of interpolated locations in the stack
 */
 
export default function getInterpolationData(
  viewportData: InterpolationViewportData,
  filterParams = []
): Map<number, Annotation[]> {
  const { viewport, sliceData, annotation } = viewportData;
  const interpolationDatas = new Map<number, Annotation[]>();
  const { toolName, originalToolName } = annotation.metadata;
  const testToolName = originalToolName || toolName;
  // Get a copy of the annotations list by filtering it for only
  // items which are originally the right tool name
  const annotations = (
    (getAnnotations(
      testToolName,
      viewport.element
    ) as ContourSegmentationAnnotation[]) || []
  ).filter(
    (annotation) =>
      !annotation.metadata.originalToolName ||
      annotation.metadata.originalToolName === testToolName
  );
 
  // Then add the default contour seg tool name which has the testTool name
  // to the segmentations list.
  Eif (testToolName !== DEFAULT_CONTOUR_SEG_TOOLNAME) {
    const modifiedAnnotations = getAnnotations(
      DEFAULT_CONTOUR_SEG_TOOLNAME,
      viewport.element
    ) as ContourSegmentationAnnotation[];
    Iif (modifiedAnnotations?.length) {
      modifiedAnnotations.forEach((annotation) => {
        const { metadata } = annotation;
        if (
          metadata.originalToolName === testToolName &&
          metadata.originalToolName !== metadata.toolName
        ) {
          annotations.push(annotation);
        }
      });
    }
  }
 
  Iif (!annotations?.length) {
    return interpolationDatas;
  }
 
  for (let i = 0; i < sliceData.numberOfSlices; i++) {
    const imageAnnotations = annotations.filter(
      (x) => x.metadata.sliceIndex === i
    );
 
    if (!imageAnnotations?.length) {
      continue;
    }
 
    const filteredInterpolatedAnnotations = imageAnnotations.filter(
      (imageAnnotation) => {
        return filterParams.every((x) => {
          const parent = x.parentKey
            ? x.parentKey(imageAnnotation)
            : imageAnnotation;
          const value = parent?.[x.key];
          if (Array.isArray(value)) {
            return value.every((item, index) => item === x.value[index]);
          }
          return value === x.value;
        });
      }
    );
 
    Eif (filteredInterpolatedAnnotations.length) {
      interpolationDatas.set(i, filteredInterpolatedAnnotations);
    }
  }
 
  return interpolationDatas;
}