All files / extensions/default/src/utils/validations areAllImagePositionsEqual.ts

81.81% Statements 18/22
33.33% Branches 2/6
100% Functions 2/2
80.95% Lines 17/21

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                                          8744x           8744x                 101x     101x 101x     101x 101x 101x   101x         101x   101x 101x 8744x 8744x   8744x                   8744x   101x    
import { vec3 } from 'gl-matrix';
import toNumber from '@ohif/core/src/utils/toNumber';
import { _getPerpendicularDistance } from '@ohif/core/src/utils/isDisplaySetReconstructable';
import calculateScanAxisNormal from '../calculateScanAxisNormal';
 
/**
 * Checks if there is a position shift between consecutive frames
 * @param {*} previousPosition
 * @param {*} actualPosition
 * @param {*} scanAxisNormal
 * @param {*} averageSpacingBetweenFrames
 * @returns
 */
function _checkSeriesPositionShift(
  previousPosition,
  actualPosition,
  scanAxisNormal,
  averageSpacingBetweenFrames
) {
  // predicted position should be the previous position added by the multiplication
  // of the scanAxisNormal and the average spacing between frames
  const predictedPosition = vec3.scaleAndAdd(
    vec3.create(),
    previousPosition,
    scanAxisNormal,
    averageSpacingBetweenFrames
  );
  return vec3.distance(actualPosition, predictedPosition) > averageSpacingBetweenFrames;
}
 
/**
 * Checks if a series has position shifts between consecutive frames
 * @param {*} instances
 * @returns
 */
export default function areAllImagePositionsEqual(instances: Array<any>): boolean {
  Iif (!instances?.length) {
    return false;
  }
  const firstImageOrientationPatient = toNumber(instances[0].ImageOrientationPatient);
  Iif (!firstImageOrientationPatient) {
    return false;
  }
  const scanAxisNormal = calculateScanAxisNormal(firstImageOrientationPatient);
  const firstImagePositionPatient = toNumber(instances[0].ImagePositionPatient);
  const lastIpp = toNumber(instances[instances.length - 1].ImagePositionPatient);
 
  Iif (!firstImagePositionPatient || !lastIpp) {
    return false;
  }
 
  const averageSpacingBetweenFrames =
    _getPerpendicularDistance(firstImagePositionPatient, lastIpp) / (instances.length - 1);
 
  let previousImagePositionPatient = firstImagePositionPatient;
  for (let i = 1; i < instances.length; i++) {
    const instance = instances[i];
    const imagePositionPatient = toNumber(instance.ImagePositionPatient);
 
    Iif (
      _checkSeriesPositionShift(
        previousImagePositionPatient,
        imagePositionPatient,
        scanAxisNormal,
        averageSpacingBetweenFrames
      )
    ) {
      return false;
    }
    previousImagePositionPatient = imagePositionPatient;
  }
  return true;
}