Skip to content

motor

borealis.motor

Created on Mon Mar 6 10:50:29 2023.

@author: René Bes

Motor(alias, motor_id, motor_offset, controller, positive_direction=True, soft_limit_low=-inf, soft_limit_high=inf)

Bases: ControllerComponent

Motor generic class.

Source code in borealis/motor.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
def __init__(self, alias: str, motor_id: str, motor_offset: float, controller: Controller,
             positive_direction: bool = True, soft_limit_low: float = -inf, soft_limit_high: float = inf) -> None:
    self._controller = controller
    self.motor_name = alias
    super().__init__(session_orchestrator)
    self.motor_id = motor_id
    self.offset = motor_offset
    self._direction_coeff = -1 if positive_direction is False else 1
    self._limit_low = soft_limit_low
    self._limit_high = soft_limit_high
    self._dial_position = self._controller.get_axis_position(self.motor_id)
    self._user_position = self.dial_position + self.offset
    self._is_ready = self._controller.is_axis_ready(self.motor_id)
    LOGGER.info("Motor %s created.", self.motor_name)

amove(user_position)

Move the motor to a new position (user) in absolute scale.

Parameters:

Name Type Description Default
user_position float

New position (user) to move the motor to.

required

Returns:

Type Description
None.
Source code in borealis/motor.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
def amove(self, user_position: float):
    """
    Move the motor to a new position (user) in absolute scale.

    Parameters
    ----------
    user_position : float
        New position (user) to move the motor to.

    Returns
    -------
    None.

    """
    self._check_is_ready()
    self.check_soft_limits(user_position)

    dial = (user_position - self.offset) / self._direction_coeff
    self._controller.move_axis(self.motor_id, dial)
    self._controller.wait_motion_end(self.motor_id, dial)
    self.log(logging.DEBUG, "moved to %.2f.", self.user_position)

check_soft_limits(target_user)

Check if dial value is within the limits (inclusive).

Parameters:

Name Type Description Default
target_user float

Target position in user unit.

required

Raises:

Type Description
SoftLimitError when dial is outside the allowed range.
Source code in borealis/motor.py
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
def check_soft_limits(self, target_user: float) -> None:
    """
    Check if dial value is within the limits (inclusive).

    Parameters
    ----------
    target_user : float
        Target position in user unit.

    Raises
    ------
    SoftLimitError when dial is outside the allowed range.
    """
    target_dial = (target_user - self.offset) / self._direction_coeff
    try:
        assert self._limit_low <= target_dial <= self._limit_high
    except AssertionError:
        self.log(logging.ERROR, 'Soft Limit Error: the dial position %.2f is outside the available soft limit range [%.2f : %.2f]', target_dial, self._limit_low, self._limit_high)
        raise SoftLimitError(target_dial, self.motor_name, self._limit_low, self._limit_high)

log(level, msg, *args, **kwargs)

Log a message with prepending the device's alias in front of the message.

Source code in borealis/motor.py
40
41
42
43
def log(self, level, msg, *args, **kwargs):
    """Log a message with prepending the device's alias in front of the message."""
    kwargs['stacklevel'] = 2
    LOGGER.log(level, f'{self.motor_name}: {msg}', *args, **kwargs)

rmove(rel_position)

Move the motor by a relative position.

Parameters:

Name Type Description Default
rel_position float

Relative value to move the motor by.

required

Returns:

Type Description
None.
Source code in borealis/motor.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
def rmove(self, rel_position: float):
    """
    Move the motor by a relative position.

    Parameters
    ----------
    rel_position : float
        Relative value to move the motor by.

    Returns
    -------
    None.

    """
    self._check_is_ready()
    self.check_soft_limits(self.user_position + rel_position)

    dial = self.dial_position + rel_position * self._direction_coeff
    self._controller.move_axis(self.motor_id, dial)
    self._controller.wait_motion_end(self.motor_id, dial)
    self.log(logging.DEBUG, "moved to %.2f.", self.user_position)

scan(start, stop, step, acq_time=0.0)

Perform a scan, if acq_time > 0 will also do an acquisition on all sensors.

Parameters:

Name Type Description Default
start float

Start of interval. The interval includes this value.

required
stop float

End of interval. The interval does not include this value.

required
step float

Spacing between values. For any output out, this is the distance between two adjacent values, out[i+1] - out[i].

required
acq_time float
0.0
Source code in borealis/motor.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def scan(self, start: float, stop: float, step: float, acq_time: float = 0.):
    """
    Perform a scan, if acq_time > 0 will also do an acquisition on all sensors.

    Parameters
    ----------
    start : float
        Start of interval. The interval includes this value.
    stop : float
        End of interval. The interval does not include this value.
    step : float
        Spacing between values. For any output `out`, this is the distance
        between two adjacent values, ``out[i+1] - out[i]``.
    acq_time : float

    """
    self._check_is_ready()

    scan_points = np.arange(start, stop, step, dtype=np.float32)
    self.send(message='Scan', scan_points=scan_points, acq_time=acq_time)

set_current_as_zero()

Set motor current position as 0.

Source code in borealis/motor.py
170
171
172
173
174
175
def set_current_as_zero(self):
    """Set motor current position as 0."""
    current_position = self.dial_position
    self._controller.set_axis_to_zero(self.motor_id)
    self.log(logging.WARNING, "Dial position reset to 0. Initial dial value was %.2f.",
             current_position)

where()

Print motor dial / user positions from controller.

Returns:

Type Description
str
Source code in borealis/motor.py
66
67
68
69
70
71
72
73
74
75
def where(self):
    """
    Print motor dial / user positions from controller.

    Returns
    -------
    str

    """
    print(f'{self.motor_name:20} at : {self.user_position:6.2f} (user)')