All files / core/src/utilities createSigmoidRGBTransferFunction.ts

0% Statements 0/9
0% Branches 0/1
0% Functions 0/3
0% Lines 0/9

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                                                                                                             
import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';
import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';
import type { VOIRange } from '../types/voi';
import * as windowLevelUtil from './windowLevel';
import { logit } from './logit';
 
/**
 * A utility that can be used to generate an Sigmoid RgbTransferFunction.
 * Sigmoid transfer functions are used in the dicom specification:
 * https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.11.2.html
 *
 * @example
 * Setting an RGB Transfer function from the viewport:
 * ```
 * const sigmoidRGBTransferFunction = createSigmoidRGBTransferFunction(0, 255, { lower: 0, upper: 255} );
 * viewport
 *   .getActor()
 *   .getProperty()
 *   .setRGBTransferFunction(0, sigmoidRGBTransferFunction);
 * ```
 *
 * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}
 * @param voiRange
 * @param approximationNodes
 */
export default function createSigmoidRGBTransferFunction(
  voiRange: VOIRange,
  approximationNodes: number = 1024 // humans can perceive no more than 900 shades of gray doi: 10.1007/s10278-006-1052-3
): vtkColorTransferFunction {
  const { windowWidth, windowCenter } = windowLevelUtil.toWindowLevel(
    voiRange.lower,
    voiRange.upper
  );
 
  // we slice out the first and last value to avoid 0 and 1 Infinity values
  const range: number[] = Array.from(
    { length: approximationNodes },
    (_, i) => (i + 1) / (approximationNodes + 2)
  );
 
  const table: number[] = range.flatMap((y) => {
    const x = logit(y, windowCenter, windowWidth);
    return [x, y, y, y, 0.5, 0.0];
  });
 
  const cfun = vtkColorTransferFunction.newInstance();
  cfun.buildFunctionFromArray(
    vtkDataArray.newInstance({
      values: table,
      numberOfComponents: 6,
    }) // Type assertion might be necessary if vtkDataArray types are not fully compatible
  );
  return cfun;
}