fixes for beamtime prep with Manuel #210
@@ -1055,7 +1055,7 @@ class FlomniAlignmentMixin:
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Ay3.txt"), "r") as file:
|
||||
tomo_alignment_fit[1][3] = file.readline()
|
||||
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_Cy3.txt"), "r") as file:
|
||||
with open(os.path.join(dir_path, "ptychotomoalign_By3.txt"), "r") as file:
|
||||
tomo_alignment_fit[1][4] = file.readline()
|
||||
|
||||
print("New alignment parameters loaded from filesystem, meaning Matlab fit:")
|
||||
@@ -1618,7 +1618,7 @@ class Flomni(
|
||||
|
||||
self.feye_out()
|
||||
tags = ["BEC_alignment_tomo", self.sample_name]
|
||||
|
||||
self.write_alignment_scan_numbers(bec.queue.next_scan_number)
|
||||
start_angle = 0
|
||||
alignment_scan_numbers = []
|
||||
|
||||
@@ -1667,6 +1667,32 @@ class Flomni(
|
||||
print(scilog_content)
|
||||
bec.messaging.scilog.new().add_text(scilog_content.replace("\n", "<br>")).add_tags("alignmentscan").send()
|
||||
|
||||
def write_alignment_scan_numbers(self, first_scan):
|
||||
import os
|
||||
|
||||
file = os.path.expanduser("~/data/raw/logs/ptychotomoalign_scannum.txt")
|
||||
os.makedirs(os.path.dirname(file), exist_ok=True)
|
||||
|
||||
scans = [first_scan + k for k in range(5)]
|
||||
angles = [0, 45, 90, 135, 180]
|
||||
|
||||
x_vals = []
|
||||
|
||||
for angle in angles:
|
||||
x, y, z = self.get_alignment_offset(angle)
|
||||
x_vals.append(x)
|
||||
|
||||
zeros = [0] * len(angles)
|
||||
|
||||
with open(file, "w") as f:
|
||||
f.write(" ".join(map(str, scans)) + "\n")
|
||||
f.write(" ".join(map(str, angles)) + "\n")
|
||||
f.write(" ".join(f"{x:.2f}" for x in x_vals) + "\n")
|
||||
f.write(" ".join(map(str, x_vals)) + "\n")
|
||||
f.write(" ".join(map(str, zeros)) + "\n")
|
||||
|
||||
|
||||
|
||||
def sub_tomo_scan(self, subtomo_number, start_angle=None):
|
||||
"""
|
||||
Performs a sub tomogram scan.
|
||||
|
||||
@@ -158,7 +158,7 @@ def _safe_get(device_manager, dotpath: str):
|
||||
obj = device_manager.devices
|
||||
for part in dotpath.split("."):
|
||||
obj = getattr(obj, part)
|
||||
return obj.get()
|
||||
return obj.get(cached=True)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
@@ -2230,16 +2230,23 @@ function render(d){{
|
||||
handleAudioForStatus(s, prevStatus);
|
||||
}}
|
||||
|
||||
let _fetchFailCount=0;
|
||||
const FETCH_FAIL_THRESHOLD=3;
|
||||
|
||||
async function poll(){{
|
||||
try{{
|
||||
const r=await fetch(STATUS_JSON, {{cache:'no-store'}});
|
||||
if(!r.ok) throw new Error('HTTP '+r.status);
|
||||
_fetchFailCount=0;
|
||||
render(await r.json());
|
||||
}}catch(e){{
|
||||
console.warn('Fetch failed:',e);
|
||||
document.getElementById('last-update').textContent='fetch failed - retrying...';
|
||||
document.getElementById('outdated-banner').classList.add('visible');
|
||||
handleStale(true);
|
||||
_fetchFailCount++;
|
||||
console.warn('Fetch failed:',e,'('+_fetchFailCount+')');
|
||||
document.getElementById('last-update').textContent='fetch failed - retrying\u2026 ('+_fetchFailCount+')';
|
||||
if(_fetchFailCount>=FETCH_FAIL_THRESHOLD){{
|
||||
document.getElementById('outdated-banner').classList.add('visible');
|
||||
handleStale(true);
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
|
||||
|
||||
@@ -214,11 +214,13 @@ class JungfrauJochPreview:
|
||||
r = self._socket.recv_multipart(flags=zmq.NOBLOCK)
|
||||
self._parse_data(r)
|
||||
except zmq.error.Again:
|
||||
# No message received, this is expected when the receive queue is empty
|
||||
# No new message available on Preview socket within timeout that was set
|
||||
pass
|
||||
except Exception as e:
|
||||
# Consider moving this to debug level, but it can be useful to see why preview updates are not working
|
||||
logger.info(f"Error while receiving ZMQ message from JFJ preview at {self.url}: {e}")
|
||||
except Exception as exc:
|
||||
logger.info(
|
||||
f"Error parsing input data from JungfrauJoch host {self.url}. Exception: {exc}"
|
||||
)
|
||||
|
||||
finally:
|
||||
# Unsubscribe from the topic
|
||||
self._socket.setsockopt(zmq.UNSUBSCRIBE, ZMQ_TOPIC_FILTER)
|
||||
|
||||
@@ -37,6 +37,7 @@ class FlomniGalilController(GalilController):
|
||||
"get_motor_limit_switch",
|
||||
"fosaz_light_curtain_is_triggered",
|
||||
"is_motor_on",
|
||||
"is_thread_active",
|
||||
"all_axes_referenced",
|
||||
"lights_off",
|
||||
"lights_on",
|
||||
|
||||
@@ -57,6 +57,7 @@ class GalilController(Controller):
|
||||
"find_reference",
|
||||
"get_motor_limit_switch",
|
||||
"is_motor_on",
|
||||
"is_thread_active",
|
||||
"all_axes_referenced",
|
||||
]
|
||||
|
||||
@@ -85,7 +86,7 @@ class GalilController(Controller):
|
||||
return_val = self.socket_put_and_receive(val)
|
||||
if return_val != ":":
|
||||
raise GalilCommunicationError(
|
||||
f"Expected return value of ':' but instead received {return_val}"
|
||||
f"Sent {val} and expected return value of ':' but instead received {return_val}"
|
||||
)
|
||||
|
||||
def is_axis_moving(self, axis_Id, axis_Id_numeric) -> bool:
|
||||
|
||||
@@ -353,10 +353,13 @@ class RtFlomniController(Controller):
|
||||
|
||||
def laser_tracker_galil_enable(self):
|
||||
ftrackz_con = self.device_manager.devices.ftrackz.obj.controller
|
||||
ftrackz_con.socket_put_confirmed("tracken=1")
|
||||
ftrackz_con.socket_put_confirmed("trackyct=0")
|
||||
ftrackz_con.socket_put_confirmed("trackzct=0")
|
||||
ftrackz_con.socket_put_confirmed("XQ#Tracker")
|
||||
if not ftrackz_con.is_thread_active(5):
|
||||
ftrackz_con.socket_put_confirmed("tracken=1")
|
||||
ftrackz_con.socket_put_confirmed("trackyct=0")
|
||||
ftrackz_con.socket_put_confirmed("trackzct=0")
|
||||
ftrackz_con.socket_put_confirmed("XQ#Tracker")
|
||||
while not ftrackz_con.is_thread_active(5):
|
||||
time.sleep(0.1)
|
||||
|
||||
def laser_tracker_on_target(self) -> bool:
|
||||
self.laser_update_tracker_info()
|
||||
@@ -369,8 +372,8 @@ class RtFlomniController(Controller):
|
||||
def laser_tracker_wait_on_target(self):
|
||||
max_repeat = 25
|
||||
count = 0
|
||||
self.laser_tracker_galil_enable()
|
||||
while not self.laser_tracker_on_target():
|
||||
self.laser_tracker_galil_enable()
|
||||
logger.info("Waiting for laser tracker to reach target.")
|
||||
time.sleep(0.5)
|
||||
count += 1
|
||||
@@ -442,7 +445,7 @@ class RtFlomniController(Controller):
|
||||
" interferometer error."
|
||||
)
|
||||
# here exception
|
||||
(mode, number_of_positions_planned, current_position_in_scan) = self.get_scan_status()
|
||||
mode, number_of_positions_planned, current_position_in_scan = self.get_scan_status()
|
||||
|
||||
if number_of_positions_planned == 0:
|
||||
logger.error("Cannot start scan because no target positions are planned.")
|
||||
@@ -517,14 +520,11 @@ class RtFlomniSetpointSignal(RtSetpointSignal):
|
||||
tracker_status = self.parent.controller.laser_tracker_check_signalstrength()
|
||||
|
||||
if tracker_status == "toolow":
|
||||
print(
|
||||
"The interferometer signal is too low for movements. Realignment required."
|
||||
)
|
||||
print("The interferometer signal is too low for movements. Realignment required.")
|
||||
raise RtError(
|
||||
"The interferometer signal is too low for movements. Realignment required."
|
||||
)
|
||||
|
||||
|
||||
self.set_with_feedback_disabled(val)
|
||||
|
||||
def set_with_feedback_disabled(self, val):
|
||||
|
||||
Reference in New Issue
Block a user