Skip to content

Commit

Permalink
port CentringMath HWOBJ to work with the yaml config API changes
Browse files Browse the repository at this point in the history
Don't use [] expression to read config properties.

Renamed attributes self.cameraAxes and self.gonioAxes, to
self._camera_axes and self._gonio_axes, as they now collide with
the 'auto created' properties on the ConfiguredObject superclass.

Use calls to self.get_property() when populating these attributes.
  • Loading branch information
elmjag committed Sep 19, 2024
1 parent 0da701f commit 95de0d4
Showing 1 changed file with 49 additions and 31 deletions.
80 changes: 49 additions & 31 deletions mxcubecore/HardwareObjects/CentringMath.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,54 @@ class CentringMath(Procedure):
CentringMath procedure
"""

def __init__(self, name: str):
super().__init__(name)
self._gonio_axes = []
self._camera_axes = []

def init(self):
"""
Ggonio axes definitions are static
motorHO is expected to have get_value() that returns coordinate in mm
"""
self.motorConstraints = []
self.gonioAxes = []
for axis in self["gonioAxes"]:
self.gonioAxes.append(
{
"type": axis.type,
"direction": eval(axis.direction),
"motor_name": axis.motorname,

def get_axis_property(property_name: str) -> list:
#
# get 'axis' key from the specified config property
#
# treat the property as optional, if not specified,
# return an empty list
#
return self.get_property(property_name, {}).get("axis", [])

def get_gonio_axes():
for axis in get_axis_property("gonioAxes"):
yield {
"type": axis["type"],
"direction": eval(axis["direction"]),
"motor_name": axis["motorname"],
"motor_HO": HWR.get_hardware_repository().get_hardware_object(
axis.motorHO
axis["motorHO"]
),
}
)

def get_camera_axes():
for axis in get_axis_property("cameraAxes"):
yield {
"axis_name": axis["axisname"],
"direction": eval(axis["direction"]),
}

self.motorConstraints = []
self._gonio_axes = list(get_gonio_axes())

"""
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(
{"axis_name": axis.axisname, "direction": eval(axis.direction)}
)

self._camera_axes = list(get_camera_axes())
self.mI = numpy.diag([1.0, 1.0, 1.0]) # identity matrix
self.calibrate()

Expand Down Expand Up @@ -93,13 +111,13 @@ def centeredPosition(self, return_by_name=False):

for l in range(0, self.translationAxesCount):
for i in range(0, len(self.centringDataMatrix)):
for k in range(0, len(self.cameraAxes)):
for k in range(0, len(self._camera_axes)):
V[l] += (
self.centringDataTensor[i][l][k] * self.centringDataMatrix[i][k]
)
for m in range(0, self.translationAxesCount):
for i in range(0, len(self.centringDataMatrix)):
for k in range(0, len(self.cameraAxes)):
for k in range(0, len(self._camera_axes)):
M[l][m] += (
self.centringDataTensor[i][l][k]
* self.centringDataTensor[i][m][k]
Expand Down Expand Up @@ -129,10 +147,10 @@ def apply_constraints(self, M, tau):

def factor_matrix(self):
# This should be connected to goniostat rotation datum update, with F globalized
F = numpy.zeros(shape=(self.translationAxesCount, len(self.cameraAxes)))
F = numpy.zeros(shape=(self.translationAxesCount, len(self._camera_axes)))
R = self.mI
j = 0
for axis in self.gonioAxes: # skip base gonio axis
for axis in self._gonio_axes: # skip base gonio axis
if axis["type"] == "rotation":
Ra = self.rotation_matrix(
axis["direction"], axis["motor_HO"].get_value()
Expand All @@ -141,15 +159,15 @@ def factor_matrix(self):
elif axis["type"] == "translation":
f = numpy.dot(R, axis["direction"])
k = 0
for camera_axis in self.cameraAxes:
for camera_axis in self._camera_axes:
F[j][k] = numpy.dot(f, camera_axis["direction"])
k += 1
j += 1
return F

def calibrate(self):
count = 0
for axis in self.gonioAxes: # make first gonio rotation matrix for base axis
for axis in self._gonio_axes: # make first gonio rotation matrix for base axis
if axis["type"] == "rotation":
d = axis["direction"]
axis["mT"] = numpy.outer(d, d)
Expand All @@ -161,7 +179,7 @@ def calibrate(self):
count += 1
self.translationAxesCount = count
count = 0
for axis in self.cameraAxes:
for axis in self._camera_axes:
axis["index"] = count
count += 1

Expand All @@ -177,15 +195,15 @@ def rotation_matrix(self, dir, angle):

def translation_datum(self):
vector = []
for axis in self.gonioAxes:
for axis in self._gonio_axes:
if axis["type"] == "translation":
vector.append(axis["motor_HO"].get_value())
return vector

def centred_positions_to_vector(self, centrings_dictionary):
vector = numpy.zeros(shape=(self.translationAxesCount))
index = 0
for axis in self.gonioAxes:
for axis in self._gonio_axes:
if axis["type"] == "translation":
motname = axis["motor_name"]
if centrings_dictionary[motname] is not None:
Expand All @@ -198,7 +216,7 @@ def centred_positions_to_vector(self, centrings_dictionary):
def vector_to_centred_positions(self, vector, return_by_name=False):
dic = {}
index = 0
for axis in self.gonioAxes:
for axis in self._gonio_axes:
if axis["type"] == "translation":
if return_by_name:
dic[axis["motor_name"]] = vector[index]
Expand All @@ -209,24 +227,24 @@ def vector_to_centred_positions(self, vector, return_by_name=False):

def camera_coordinates_to_vector(self, camera_coordinates_dictionary):
vector = []
for index in range(0, len(self.cameraAxes)):
for index in range(0, len(self._camera_axes)):
vector.append(
camera_coordinates_dictionary[self.cameraAxes[index]["axis_name"]]
camera_coordinates_dictionary[self._camera_axes[index]["axis_name"]]
)
return vector

def vector_to_camera_coordinates(self, vector):
dic = {}
index = 0
for axis in self.cameraAxes:
for axis in self._camera_axes:
dic[axis["axis_name"]] = vector[index]
index += 1
return dic

def appendMotorConstraint(self, motor_HO, position):
index = 0
self.motorConstraints = []
for axis in self.gonioAxes:
for axis in self._gonio_axes:
if axis["type"] == "translation" and motor_HO is axis["motor_HO"]:
index += 1
self.motorConstraints.append(
Expand All @@ -238,10 +256,10 @@ 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
for axis in self.gonioAxes:
for axis in self._gonio_axes:
if axis["type"] == "translation" and motor_HO is axis["motor_HO"]:
res = 0.0
for camaxis in self.cameraAxes:
for camaxis in self._camera_axes:
res = (
res
+ numpy.dot(axis["direction"], camaxis["direction"])
Expand Down

0 comments on commit 95de0d4

Please sign in to comment.