Source code for pylinac.core.scale
from __future__ import annotations
from enum import Enum
from numpy import ndarray
def _noop(value: float | ndarray) -> float | ndarray:
"""Don't do anything."""
return value
def _mirror_360(value: float | ndarray) -> float | ndarray:
"""Mirror about 0"""
return wrap360(-value)
def _shift_and_mirror_360(value: float | ndarray) -> float | ndarray:
"""Shift by 180 degrees and then mirror about 0"""
return wrap360(180 - value)
def wrap360(value: float | ndarray) -> float | ndarray:
"""Wrap the input values to the interval [0, 360)"""
return value % 360
def wrap180(value: float | ndarray) -> float | ndarray:
"""Wrap the input values to the interval [-180, 180)"""
return wrap360(value + 180) - 180
[docs]
class MachineScale(Enum):
"""Possible machine scales. Used for specifying input and output scales for conversion.
The enum keys are conversion functions for each axis relative to IEC 61217"""
IEC61217 = {
"gantry_to_iec": _noop,
"collimator_to_iec": _noop,
"rotation_to_iec": _noop,
"gantry_from_iec": _noop,
"collimator_from_iec": _noop,
"rotation_from_iec": _noop,
}
ELEKTA_IEC = {
"gantry_to_iec": _noop,
"collimator_to_iec": _noop,
"rotation_to_iec": _mirror_360,
"gantry_from_iec": _noop,
"collimator_from_iec": _noop,
"rotation_from_iec": _mirror_360,
}
VARIAN_IEC = {
"gantry_to_iec": _noop,
"collimator_to_iec": _noop,
"rotation_to_iec": _mirror_360,
"gantry_from_iec": _noop,
"collimator_from_iec": _noop,
"rotation_from_iec": _mirror_360,
}
VARIAN_STANDARD = {
"gantry_to_iec": _shift_and_mirror_360,
"collimator_to_iec": _shift_and_mirror_360,
"rotation_to_iec": _shift_and_mirror_360,
"gantry_from_iec": _shift_and_mirror_360,
"collimator_from_iec": _shift_and_mirror_360,
"rotation_from_iec": _shift_and_mirror_360,
}
[docs]
def convert(
input_scale: MachineScale,
output_scale: MachineScale,
gantry: float | ndarray,
collimator: float | ndarray,
rotation: float | ndarray,
) -> tuple[float | ndarray, float | ndarray, float | ndarray]:
"""Convert from one coordinate scale to another. Returns gantry, collimator, rotation."""
# convert to IEC61217 since everything is defined relative to it
g = input_scale.value["gantry_to_iec"](gantry)
c = input_scale.value["collimator_to_iec"](collimator)
r = input_scale.value["rotation_to_iec"](rotation)
# now apply the inverse to go from 61217 to output scale
g_out = output_scale.value["gantry_from_iec"](g)
c_out = output_scale.value["collimator_from_iec"](c)
r_out = output_scale.value["rotation_from_iec"](r)
return g_out, c_out, r_out