Skip to content

Commit

Permalink
to address the issue mxcube#894. Most of the fix is just adding a ne…
Browse files Browse the repository at this point in the history
…w line in the docstrings
  • Loading branch information
AnnieHeroux committed Mar 20, 2024
1 parent 3ed02c8 commit 8498825
Show file tree
Hide file tree
Showing 19 changed files with 368 additions and 256 deletions.
13 changes: 9 additions & 4 deletions mxcubecore/HardwareObjects/BlissActuator.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
"""
Use bliss to set different actuators in/out.
If private_state not specified, True will be send to set in and False for out.
Example xml file:
<device class="BlissActuator">
If private_state not specified, ``True`` will be send to set in and ``False`` for out.
Example of a configuration via xml file::
<device class="BlissActuator">
<username>Detector Cover</username>
<object href="/bliss" role="controller"/>
</device>
</device>
"""

import logging
from warnings import warn

Expand Down
46 changes: 27 additions & 19 deletions mxcubecore/HardwareObjects/BlissEnergy.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,27 @@
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.
"""
Energy and Wavelength with bliss.
Example xml file:
- for tunable wavelength beamline:
<object class="Energy">
<object href="/energy" role="energy_motor"/>
<object href="/bliss" role="bliss"/>
</object>
The energy should have methods get_value, get_limits, get_state and move.
If used, the controller should have method moveEnergy.
- for fixed wavelength beamline:
<object class="Energy">
<read_only>True</read_only>
<energy>12.8123</energy>
or
<object href="/energy" role="energy_motor"/>
The energy should have methods get_value and get_state
</object>
Example xml file for tunable wavelength beamline::
<object class="Energy">
<object href="/energy" role="energy_motor"/>
<object href="/bliss" role="bliss"/>
</object>
The energy should have methods ``get_value``, ``get_limits``, ``get_state`` and ``move``.
If used, the controller should have the ``moveEnergy`` method.
Example xml file for fixed wavelength beamline::
<object class="Energy">
<read_only>True</read_only>
<energy>12.8123</energy> or
<object href="/energy" role="energy_motor"/>
</object>
The energy should have ``get_value`` and ``get_state`` methods
"""
import logging
import math
Expand Down Expand Up @@ -71,6 +75,7 @@ def init(self):

def get_value(self):
"""Read the energy.
Returns:
(float): Energy [keV]
"""
Expand All @@ -80,6 +85,7 @@ def get_value(self):

def get_limits(self):
"""Return energy low and high limits.
Returns:
(tuple): two floats tuple (low limit, high limit) [keV].
"""
Expand All @@ -92,7 +98,8 @@ def stop(self):
self._energy_motor.stop()

def _set_value(self, value):
"""Execute the sequence to move to an energy
"""Execute the sequence to move to an energy.
Args:
value (float): target energy
"""
Expand All @@ -102,7 +109,8 @@ def _set_value(self, value):
self._energy_motor.set_value(value)

def set_value(self, value, timeout=0):
"""Move energy to absolute position. Wait the move to finish.
"""Move energy to absolute position and wait ``move`` to finish.
Args:
value (float): target value.
timeout (float): optional - timeout [s],
Expand Down
30 changes: 18 additions & 12 deletions mxcubecore/HardwareObjects/BlissNState.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,16 @@
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.

"""
bliss implementation of AbstartNState
Example xml file:
<device class="BlissNState">
<username>Detector Cover</username>
<actuator_name>detcover</>
<object href="/bliss" role="controller"/>
<values>{"IN": "IN", "OUT": "OUT"}</values>
</device>
bliss implementation of AbstractNState.
Example of a configuartion xml file::
<device class="BlissNState">
<username>Detector Cover</username>
<actuator_name>detcover</>
<object href="/bliss" role="controller"/>
<values>{"IN": "IN", "OUT": "OUT"}</values>
</device>
"""
from enum import Enum
from mxcubecore.HardwareObjects.abstract.AbstractMotor import MotorStates
Expand All @@ -40,7 +42,7 @@


class BlissNState(AbstractNState):
"""bliss implementation of AbstartNState"""
"""bliss implementation of AbstractNState"""

SPECIFIC_STATES = MotorStates

Expand Down Expand Up @@ -79,9 +81,10 @@ def _update_state(self):
self.update_state(self.STATES.READY)

def get_value(self):
"""Get the device value
"""Get the device value.
Returns:
(Enum): Enum member, corresponding to the value or UNKNOWN.
(Enum): Enum member, corresponding to the value or ``UNKNOWN``.
"""
if self.device_type == "motor":
_val = self._bliss_obj.position
Expand All @@ -100,6 +103,7 @@ def get_value(self):

def _set_value(self, value):
"""Set device to value.
Args:
value (str or enum): target value
"""
Expand All @@ -125,6 +129,7 @@ def _set_value(self, value):

def get_state(self):
"""Get the device state.
Returns:
(enum 'HardwareObjectState'): Device state.
"""
Expand Down Expand Up @@ -153,7 +158,8 @@ def _update_state_motor(self, state):
return self.update_state(state)

def initialise_values(self):
"""Get the predefined valies. Create the VALUES Enum
"""Get the predefined values and create the ``VALUES Enum``.
Returns:
(Enum): "ValueEnum" with predefined values.
"""
Expand Down
38 changes: 24 additions & 14 deletions mxcubecore/HardwareObjects/BlissShutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@
# along with MXCuBE. If not, see <http://www.gnu.org/licenses/>.

""" BlissShutter class - interface for shutter controlled by BLISS
Implements _set_value, get_value methods
Bliss states are: UNKNOWN, OPEN, CLOSED, FAULT
"MOVING", "DISABLE", "STANDBY", "RUNNING"
Example xml file:
<devic class="BlissShutter">
<username>Safety Shutter</username>
<name>safshut</name>
<type>tango</type>
<object href="/bliss" role="controller"/>
</device>
Implements ``_set_value``, ``get_value`` methods
Example xml file::
<device class="BlissShutter">
<username>Safety Shutter</username>
<name>safshut</name>
<type>tango</type>
<object href="/bliss" role="controller"/>
</device>
"""
from enum import Enum, unique
import gevent
Expand All @@ -42,7 +44,11 @@

@unique
class BlissShutterStates(Enum):
"""Shutter states definitions."""
"""Shutter states definitions corresponding to the HardwareObjectState.
States are:
``OPEN``, ``CLOSED``, ``FAULT``, ``MOVING``, ``DISABLE``, ``UNKNOWN``, ``AUTOMATIC``
"""

OPEN = HardwareObjectState.READY, "OPEN"
CLOSED = HardwareObjectState.READY, "CLOSED"
Expand Down Expand Up @@ -103,6 +109,7 @@ def _initialise_values(self):

def get_state(self):
"""Get the device state.
Returns:
(enum 'HardwareObjectState'): Device state.
"""
Expand All @@ -113,9 +120,10 @@ def get_state(self):
return self.SPECIFIC_STATES[_state].value[0]

def get_value(self):
"""Get the device value
"""Get the device value.
Returns:
(Enum): Enum member, corresponding to the value or UNKNOWN.
(Enum): Enum member, corresponding to the value or ``UNKNOWN``.
"""
# the return from BLISS value is an Enum
_val = self._bliss_obj.state.name
Expand All @@ -128,9 +136,11 @@ def _set_value(self, value):
self._bliss_obj.close()

def set_mode(self, value):
"""Set automatic or manual mode for a Frontend shutter
"""Set automatic or manual mode for a Frontend shutter.
Args:
value (str): MANUAL or AUTOMATIC
Raises: NotImplementedError: Not a Fronend shutter.
"""
self._bliss_obj.mode = value
Expand Down
28 changes: 15 additions & 13 deletions mxcubecore/HardwareObjects/Camera.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
"""Class for cameras connected to framegrabbers run by Taco Device Servers
"""Class for cameras connected to framegrabbers run by Taco Device Servers.
Example of a configuration using a xml file::
template:
<device class = "Camera">
<username>user label</username>
<!-- <taconame>device server name (//host/.../.../...)</taconame> -->
<interval>polling interval (in ms.)</interval>
<!-- <calibration>
<zoomMotor>Zoom motor Hardware Object reference</zoomMotor>
<calibrationData>
<offset>Zoom motor position (user units)</offset>
<pixelsPerMmY>pixels per mm (Y axis)</pixelsPerMmY>
<pixelsPerMmZ>pixels per mm (Z axis)</pixelsPerMmZ>
</calibrationData>
</calibration> -->
<username>user label</username>
<!-- <taconame>device server name (//host/.../.../...)</taconame> -->
<interval>polling interval (in ms.)</interval>
<!-- <calibration>
<zoomMotor>Zoom motor Hardware Object reference</zoomMotor>
<calibrationData>
<offset>Zoom motor position (user units)</offset>
<pixelsPerMmY>pixels per mm (Y axis)</pixelsPerMmY>
<pixelsPerMmZ>pixels per mm (Z axis)</pixelsPerMmZ>
</calibrationData>
</calibration> -->
</device>
"""

from mxcubecore import BaseHardwareObjects
from mxcubecore import CommandContainer
import gevent
Expand Down
48 changes: 28 additions & 20 deletions mxcubecore/HardwareObjects/CentringMath.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ class CentringMath(Procedure):

def init(self):
"""
Ggonio axes definitions are static
motorHO is expected to have get_value() that returns coordinate in mm
Gonio axes definitions are static
motorHO is expected to have ``get_value()`` that returns coordinates in mm.
This version is lacking video microscope object. Therefore we model only
static camera axes directions, but no camera axes scaling or center - which
are dynamic. Therefore, camera coordinates are relative, in mm.
"""
self.motorConstraints = []
self.gonioAxes = []
Expand All @@ -29,11 +33,6 @@ def init(self):
}
)

"""
This version is lacking video microscope object. Therefore we model only
static camera axes directions, but no camera axes scaling or center - which
are dynamic. Therefore, camera coordinates are relative, in mm.
"""
self.cameraAxes = []
for axis in self["cameraAxes"]:
self.cameraAxes.append(
Expand All @@ -44,14 +43,20 @@ def init(self):
self.calibrate()

def centringToScreen(self, centring_dict, factorized=False):
if not factorized:
self.factorize()
"""
One _must_ self.factorize() before!!!
Input positions are indexed by motor name as in original MiniDiff.
One *must* use ``factorize()`` before!!!
Input positions are indexed by motor name as in the original MiniDiff.
For symmetry, output camera coordinates are indexed by camera axis name, like {'X':<float>,'Y':<float>},
but not just x,y as in original MiniDiff.
but not just x,y as in the original MiniDiff.
Args:
centring_dict
factorized: default ``False``
"""
if not factorized:
self.factorize()

tau_cntrd = self.centred_positions_to_vector(centring_dict)
if self.tau is not None and tau_cntrd is not None:
dum = self.tau - tau_cntrd
Expand All @@ -69,25 +74,25 @@ def listOfCentringsToScreen(self, list_of_centring_dicts):
return lst

def factorize(self):
# this should be automatic, on the gonio both rot and trans datum update
"""This should be automatic, on the gonio both rot and trans datum update."""
self.F = self.factor_matrix()
self.tau = self.translation_datum()

def initCentringProcedure(self):
# call before starting rotate-click sequence
"""call before starting rotate-click sequence."""
self.centringDataTensor = []
self.centringDataMatrix = []
self.motorConstraints = []

def appendCentringDataPoint(self, camera_coordinates):
# call after each click and send click points - but relative in mm
"""call after each click and send click points - but relative in mm."""
self.centringDataTensor.append(self.factor_matrix())
self.centringDataMatrix.append(
self.camera_coordinates_to_vector(camera_coordinates)
)

def centeredPosition(self, return_by_name=False):
# call after appending the last click. Returns a {motorHO:position} dictionary.
"""call after appending the last click. Returns a {motorHO:position} dictionary."""
M = numpy.zeros(shape=(self.translationAxesCount, self.translationAxesCount))
V = numpy.zeros(shape=(self.translationAxesCount))

Expand Down Expand Up @@ -128,7 +133,7 @@ def apply_constraints(self, M, tau):
return tau

def factor_matrix(self):
# This should be connected to goniostat rotation datum update, with F globalized
"""This should be connected to goniostat rotation datum update, with F globalized."""
F = numpy.zeros(shape=(self.translationAxesCount, len(self.cameraAxes)))
R = self.mI
j = 0
Expand Down Expand Up @@ -235,9 +240,12 @@ def appendMotorConstraint(self, motor_HO, position):
return

def camera2alignmentMotor(self, motor_HO, camxy):
# motor_HO must reference an ALIGNMENT motor!
# finds a projection of camera vector {"X":x,"Y":y} onto a motor axis of a
# motor_HO
"""find a projection of camera vector {"X":x,"Y":y} onto a motor axis of a motor_HO.
Args:
motor_HO: must reference an ALIGNMENT motor!
"""
for axis in self.gonioAxes:
if axis["type"] == "translation" and motor_HO is axis["motor_HO"]:
res = 0.0
Expand Down
Loading

0 comments on commit 8498825

Please sign in to comment.