All files / packages/tools/src/utilities/math/basic BasicStatsCalculator.ts

89.18% Statements 33/37
44.44% Branches 4/9
100% Functions 10/10
88.57% Lines 31/35

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        1x 1x 1x 1x 1x             1x 1945x                     1945x 1945x   1945x 1945x   1945x 1945x 1945x   1945x   1945x                                 1x 21x 21x 21x   21x 21x     21x                                                               21x               21x 21x 21x 21x 21x   21x         84x    
import { NamedStatistics, Statistics } from '../../../types';
import Calculator from './Calculator';
 
export default class BasicStatsCalculator extends Calculator {
  private static max = [-Infinity];
  private static sum = [0];
  private static sumSquares = [0];
  private static squaredDiffSum = [0];
  private static count = 0;
 
  /**
   * This callback is used when we verify if the point is in the annotion drawn so we can get every point
   * in the shape to calculate the statistics
   * @param value of the point in the shape of the annotation
   */
  static statsCallback = ({ value: newValue }): void => {
    Iif (
      Array.isArray(newValue) &&
      newValue.length > 1 &&
      this.max.length === 1
    ) {
      this.max.push(this.max[0], this.max[0]);
      this.sum.push(this.sum[0], this.sum[0]);
      this.sumSquares.push(this.sumSquares[0], this.sumSquares[0]);
      this.squaredDiffSum.push(this.squaredDiffSum[0], this.squaredDiffSum[0]);
    }
 
    const newArray = Array.isArray(newValue) ? newValue : [newValue];
    this.count += 1;
 
    this.max.forEach(
      (it, idx) => (this.max[idx] = Math.max(it, newArray[idx]))
    );
    this.sum.map((it, idx) => (this.sum[idx] += newArray[idx]));
    this.sumSquares.map(
      (it, idx) => (this.sumSquares[idx] += newArray[idx] ** 2)
    );
    this.squaredDiffSum.map(
      (it, idx) =>
        (this.squaredDiffSum[idx] += Math.pow(
          newArray[idx] - this.sum[idx] / this.count,
          2
        ))
    );
  };
 
  /**
   * Basic function that calculates statictics for a given array of points.
   * @returns An object that contains :
   * max : The maximum value of the array
   * mean : mean of the array
   * stdDev : standard deviation of the array
   * stdDevWithSumSquare : standard deviation of the array using sum²
   * array : An array of hte above values, in order.
   */
 
  static getStatistics = (): NamedStatistics => {
    const mean = this.sum.map((sum) => sum / this.count);
    const stdDev = this.squaredDiffSum.map((squaredDiffSum) =>
      Math.sqrt(squaredDiffSum / this.count)
    );
    const stdDevWithSumSquare = this.sumSquares.map((it, idx) =>
      Math.sqrt(this.sumSquares[idx] / this.count - mean[idx] ** 2)
    );
 
    const named: NamedStatistics = {
      max: {
        name: 'max',
        label: 'Max Pixel',
        value: singleArrayAsNumber(this.max),
        unit: null,
      },
      mean: {
        name: 'mean',
        label: 'Mean Pixel',
        value: singleArrayAsNumber(mean),
        unit: null,
      },
      stdDev: {
        name: 'stdDev',
        label: 'Standard Deviation',
        value: singleArrayAsNumber(stdDev),
        unit: null,
      },
      stdDevWithSumSquare: {
        name: 'stdDevWithSumSquare',
        value: singleArrayAsNumber(stdDevWithSumSquare),
        unit: null,
      },
      count: {
        name: 'count',
        label: 'Pixel Count',
        value: this.count,
        unit: null,
      },
      array: [],
    };
    named.array.push(
      named.max,
      named.mean,
      named.stdDev,
      named.stdDevWithSumSquare,
      named.count
    );
 
    this.max = [-Infinity];
    this.sum = [0];
    this.sumSquares = [0];
    this.squaredDiffSum = [0];
    this.count = 0;
 
    return named;
  };
}
 
function singleArrayAsNumber(val: number[]) {
  return val.length === 1 ? val[0] : val;
}