"""
Utilities for axes definition
"""
from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from typing import Tuple
from ..utils import Point3D
# Define axes and scans
[docs]
@dataclass
class Axis:
"""
Define an axis object for goniometer or detector.
Attributes:
name (str): Axis name.
depends (str): Name of the axis it depends on.
transformation_type (TransformationType): Rotation or translation.
vector (Point3D | Tuple): Axis vector.
start_pos (float, optional): Start position of axis. Defaults to 0.0.
increment (float, optional): Scan step size if the axis moves. Defaults to 0.0.
num_steps (int, optional): Number of scan points. Defaults to 0.0.
offset (Point3D | Tuple, optional): Axis offset. Defaults to (0.0, 0.0, 0.0).
Properties:
units (str): Defined depending on transformation type: deg or mm.
end_pos (float): Last point recorded in a scan colletion. Calculated from start_pos, increment and num_steps, 1-indexed.
is_scan (bool): Whether axis is a scan axis.
"""
name: str
depends: str
transformation_type: TransformationType
vector: Point3D | Tuple[float, float, float]
start_pos: float = 0.0
increment: float = 0.0
num_steps: int = 0
offset: Point3D | Tuple[float, float, float] = (0.0, 0.0, 0.0)
def __post_init__(self):
if type(self.vector) is Point3D:
self.vector = (self.vector.x, self.vector.y, self.vector.z)
if type(self.offset) is Point3D:
self.offset = (self.offset.x, self.offset.y, self.offset.z)
@property
def units(self) -> str:
if self.transformation_type == "translation":
return "mm"
else:
return "deg"
@property
def end_pos(self) -> float:
# Using the same system as scanspec
return self.start_pos + self.increment * (self.num_steps - 1)
@property
def is_scan(self) -> bool:
if self.increment != 0.0:
return True
return False