Trajectories get mangled for inverted axes
I have been trying to invert one of the piezo axis on id13 eh3 to make it move in a consistent direction with the hexapod mounted underneath it. No problem to actually invert the axis which had limits 0,250 (set sign: -1, offset: 250 => 0 - 250 now corresponds to 250 - 0).
However trying to use this inverted axis with kmaps that use MeshTrajectoryMaster
results in incorrectly calculated positions.
We ask for a mesh from 60.797 - 110.797 in y and z:
Exception:
File "/users/blissadm/local/daiquiri/daiquiri/daiquiri/core/components/__init__.py", line 796, in execute
**self.initkwargs
File "/users/blissadm/local/daiquiri/daiquiri_id13/daiquiri_id13/implementors/imageviewer/kmap.py", line 260, in method
result = greenlet.get()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/greenlet_utils.py", line 105, in get
return super().get(*args, **keys)
File "src/gevent/greenlet.py", line 803, in gevent._gevent_cgreenlet.Greenlet.get
File "src/gevent/greenlet.py", line 371, in gevent._gevent_cgreenlet.Greenlet._raise_exception
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/site-packages/gevent/_compat.py", line 65, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
File "/users/blissadm/local/daiquiri/id01/id01/scripts/kmap.py", line 296, in do_run
scan.run()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/scan.py", line 1776, in run
self._disable_caching()
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/contextlib.py", line 119, in __exit__
next(self.gen)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/cleanup.py", line 291, in capture_exceptions
raise value
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/cleanup.py", line 267, in capture
yield
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/scan.py", line 1649, in run
for i in scan_chain_iterators
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/scan.py", line 508, in send
return self.runner.send(arg)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/scan.py", line 527, in _run
self._gwait(prepare_tasks)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/scan.py", line 485, in _gwait
gevent.joinall(greenlets, raise_error=True)
File "src/gevent/greenlet.py", line 1057, in gevent._gevent_cgreenlet.joinall
File "src/gevent/greenlet.py", line 1073, in gevent._gevent_cgreenlet.joinall
File "src/gevent/greenlet.py", line 371, in gevent._gevent_cgreenlet.Greenlet._raise_exception
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/site-packages/gevent/_compat.py", line 65, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/chain.py", line 859, in prepare
join_tasks(tasks)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/chain.py", line 50, in join_tasks
gevent.joinall(greenlets, raise_error=True, **kw)
File "src/gevent/greenlet.py", line 1057, in gevent._gevent_cgreenlet.joinall
File "src/gevent/greenlet.py", line 1073, in gevent._gevent_cgreenlet.joinall
File "src/gevent/greenlet.py", line 371, in gevent._gevent_cgreenlet.Greenlet._raise_exception
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/site-packages/gevent/_compat.py", line 65, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/chain.py", line 107, in acq_prepare
self.acquisition_object.acq_prepare()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/chain.py", line 552, in acq_prepare
return self.prepare()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/scanning/acquisition/motor.py", line 945, in prepare
self.trajectory.move_to_start()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/motor_group.py", line 353, in move_to_start
wait=wait,
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/axis.py", line 152, in move
self.wait()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/axis.py", line 159, in wait
self.stop()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/axis.py", line 168, in stop
self._move_task.get()
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/greenlet_utils.py", line 105, in get
return super().get(*args, **keys)
File "src/gevent/greenlet.py", line 803, in gevent._gevent_cgreenlet.Greenlet.get
File "src/gevent/greenlet.py", line 371, in gevent._gevent_cgreenlet.Greenlet._raise_exception
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/site-packages/gevent/_compat.py", line 65, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/axis.py", line 392, in _move
hook.post_move(motions)
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/contextlib.py", line 119, in __exit__
next(self.gen)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/cleanup.py", line 291, in capture_exceptions
raise value
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/cleanup.py", line 267, in capture
yield
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/axis.py", line 321, in _move
motions_dict, start_motion, stop_motion, move_func, started_event
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/axis.py", line 310, in _do_move
self._monitor_move(motions_dict, move_func, stop_motion)
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/contextlib.py", line 119, in __exit__
next(self.gen)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/cleanup.py", line 291, in capture_exceptions
raise value
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/cleanup.py", line 267, in capture
yield
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/axis.py", line 287, in _do_move
gevent.joinall(start, raise_error=True)
File "src/gevent/greenlet.py", line 1057, in gevent._gevent_cgreenlet.joinall
File "src/gevent/greenlet.py", line 1073, in gevent._gevent_cgreenlet.joinall
File "src/gevent/greenlet.py", line 371, in gevent._gevent_cgreenlet.Greenlet._raise_exception
File "/users/blissadm/conda/miniconda/envs/daiquiri/lib/python3.7/site-packages/gevent/_compat.py", line 65, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/common/motor_group.py", line 319, in _move_to_trajectory
controller.move_to_trajectory(*trajectories)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/controllers/motors/pi_e712.py", line 444, in move_to_trajectory
self.start_all(*motions)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/controllers/motors/pi_e712.py", line 226, in start_all
self.command(cmd)
File "/users/blissadm/local/daiquiri/daiquiri.bliss.git/bliss/controllers/motors/pi_gcs.py", line 568, in command
"Device {0} command {1} error nb {2} => ({3})".format(*errors)
RuntimeError: Device npie712 command b'MOV 2 451.703 3 65.767' error nb 7 => (Position out of limits)
I think the scan must do a prepare on the trajectory group from https://gitlab.esrf.fr/bliss/bliss/-/blob/master/bliss/common/motor_group.py#L296 which ultimately calls trajectory.convert_to_dial()
Its easy to reproduce this in the test session with a simple axis.
simx configured as:
sign: 1
offset: 0
limits: [0,250]
steps_per_unit: 1 (as per piezo)
test script:
from bliss.scanning.acquisition.motor import MeshTrajectoryMaster
from bliss.config.static import get_config
config = get_config()
simx = config.get("simx")
simy = config.get("simy")
m = MeshTrajectoryMaster(simx, 60, 110, 5, simy, 60, 110, 5, 1)
tr = m.trajectory.trajectories[0]
dt = tr.convert_to_dial()
print("traj")
print(tr.pvt["position"])
print("traj convert_to_dial")
print(dt.pvt["position"])
sign: 1, offset: 0, limits: [0, 250]
traj
[ 55. 60. 110. 115. 110. 60. 55. 55. 60. 110. 115. 110. 60. 55.
55. 60. 110. 115. 110. 60. 55. 55. 60. 110. 115. 110. 60. 55.
55. 60. 110. 115. 110. 60. 55. 55.]
traj convert_to_dial
[ 55. 60. 110. 115. 110. 60. 55. 55. 60. 110. 115. 110. 60. 55.
55. 60. 110. 115. 110. 60. 55. 55. 60. 110. 115. 110. 60. 55.
55. 60. 110. 115. 110. 60. 55. 55.]
sign: -1, offset: 250, limits: [250, 0]
traj
[ 55. 60. 110. 115. 110. 60. 55. 55. 60. 110. 115. 110. 60. 55.
55. 60. 110. 115. 110. 60. 55. 55. 60. 110. 115. 110. 60. 55.
55. 60. 110. 115. 110. 60. 55. 55.]
traj convert_to_dial
[ 445. 440. 390. 385. 390. 440. 445. 445. 690. 640. 635. 640.
690. 695. 695. 940. 890. 885. 890. 940. 945. 945. 1190. 1140.
1135. 1140. 1190. 1195. 1195. 1440. 1390. 1385. 1390. 1440. 1445. 1445.]
=> trajectory positions now outside limits
This function gets called to do the conversion it would seem: https://gitlab.esrf.fr/bliss/bliss/-/blob/master/bliss/common/axis.py#L501
and axis.user2dial looks to work normally, so i've not yet tracked down where exactly the wrong calculation is happening.
TEST_SESSION [13]: simx.user2dial(50)
Out [13]: 200.0
which looks to be right