DAQ/Daq_worker - changes to rotation and raster as well as handling of responses

This commit is contained in:
2026-03-25 13:24:31 +01:00
parent fbc9890fe4
commit c9ec2e5028
2 changed files with 132 additions and 52 deletions
+66 -42
View File
@@ -46,7 +46,10 @@ from aare.common.exception_handler import (
MountingFailed,
WarningTellException,
CriticalTellException,
AXCFailed, SmargonCommunicationError, TellCommunicationError,
AXCFailed,
SmargonCommunicationError,
TellCommunicationError,
JFJochCommunicationError
)
logger = setup_logger("aareDAQ")
@@ -474,14 +477,14 @@ class AareDAQ:
except Exception as e:
self.__cfg.state_busy = False
logger.debug(f"Failed to mount sample: {e}")
self.__aare.sample_failed(target, f"Mount failed due to {e}")
# self.__aare.sample_failed(target, f"Mount failed due to {e}")
raise e
workflows.rse2sa(devs=self.__devs, cfg=self.__cfg)
self.__cfg.state_busy = False
if target is not None:
if target.db_id is not None:
self.__aare.sample_mounted(target)
self.save_screenshot_db(target.db_id, f"{target.db_id}_mounted")
# if target is not None:
# if target.db_id is not None:
# self.__aare.sample_mounted(target)
# self.save_screenshot_db(target.db_id, f"{target.db_id}_mounted")
@property
@@ -727,8 +730,9 @@ class AareDAQ:
efficiency=1.0,
bkg=0.0,
spots=0,
spots_low_res=0,
spots_indexed=0,
index=0,
mos=0.0,
b=0.0,
)
for i in range(max(1, image_count))
@@ -765,24 +769,46 @@ class AareDAQ:
logger.info(f'raster grid request: {request}')
total_time = request.exp_time_s*request.n_x*request.n_y
#self.__jfjoch.measure_raster(r, status)
if not self.__cfg.simulated_detector:
try:
logger.info('initialise detector')
self.__jfjoch.measure_raster(request, status)
logger.info('detector initialised')
except JFJochCommunicationError as e:
logger.warning(f"Failed to communicate with jfjoch: {e}")
self.__devs.aerotech.grid_scan(grid_elem_size_y_um=request.grid_size_mm.y*1000,
grid_elem_size_x_um=request.grid_size_mm.x*1000,
grid_elem_count_x=request.n_x,
grid_elem_count_y=request.n_y,
time_sec=request.exp_time_s,
run_async=True)
else:
logger.info("Simulated detector mode enabled; returning fake zero raster result.")
self.__devs.aerotech.wait_till_done(timeout=int(round(total_time*2,0)))
try:
self.__devs.aerotech.grid_scan(grid_elem_size_y_um=request.grid_size_mm.y*1000,
grid_elem_size_x_um=request.grid_size_mm.x*1000,
grid_elem_count_x=request.n_x,
grid_elem_count_y=request.n_y,
time_sec=request.exp_time_s,
run_async=True)
self.__devs.aerotech_pos = self.__cfg.abr_meas_pos
self.__devs.aerotech.wait_till_done(timeout=int(round(total_time*2,0)))
#result = self.__jfjoch.wait_till_done(60)
#return None
self.__devs.aerotech_pos = self.__cfg.abr_meas_pos
return self._build_fake_raster_result(request=request)
#return CompletedRasterGridElem(request=copy.deepcopy(request), result=result, centre_of_mass=None)
try:
result = self.__jfjoch.wait_till_done(60)
except JFJochCommunicationError as e:
logger.warning(f"Failed to communicate with jfjoch: {e}")
return self._build_fake_raster_result(request)
if result is None:
logger.warning("JFJoch returned no ScanResult; using fake result for raster scan.")
return self._build_fake_raster_result(request)
return CompletedRasterGridElem(request=copy.deepcopy(request), result=result, centre_of_mass=None)
except JFJochCommunicationError:
raise
except Exception as e:
logger.error(f"Failed during raster: {e}")
raise Exception(f"Failed during raster: {e}") from e
def measure_raster(self, r: RasterGridRequest, auto: bool) -> CompletedRasterGrid:
self.__cfg.try_set_busy(timeout=ceil(360))
@@ -809,20 +835,18 @@ class AareDAQ:
raise e
def __rotation(self, request: RotationScanRequest) -> CompletedRotationScan:
omega_start = self.omega
status = self.status
#self.__aare.create_rotation_run(self.sample, request, status)
total_time = request.exp_time_s * request.steps
try:
# if self.__cfg.simulated_detector:
# logger.info("Simulated detector mode enabled; skipping JFJoch start.")
# result = self._build_fake_rotation_result(request)
#else:
#self.__jfjoch.measure_rotation(request, status, self.__cfg.xrf)
if self.__cfg.simulated_detector:
logger.info("Simulated detector mode enabled; skipping JFJoch start.")
else:
self.__jfjoch.measure_rotation(request, status, self.__cfg.xrf)
if request.screening:
self.__devs.aerotech.screening_scan(
@@ -833,14 +857,13 @@ class AareDAQ:
run_async=True,
)
else:
#logger.info(f"rotation scan {request}")
self.__devs.aerotech.rotation_scan(
rotation_deg=request.steps*request.incr_omega_deg,
time_sec=total_time,
start_pos_deg=request.start_omega_deg,
run_async=True,
)
#logger.info(f"rotation scan in progress {request}")
#Is this for helical scans...? do we do smargon scans?
if request.start is not None and request.end is not None:
smargon_time_step = request.time_sec / float(request.steps)
@@ -852,33 +875,34 @@ class AareDAQ:
)
time.sleep(smargon_time_step)
#logger.info(f"wait till rotation scan done {request}")
self.__devs.aerotech.wait_till_done(timeout=int(round(total_time + 60,0)))
#logger.info(f"move aerotech to omega start: {omega_start}")
self.__devs.aerotech_omega = omega_start
#result = self.__jfjoch.wait_till_done(60)
# self.__aare.sample_collected(self.sample)
# if result is None:
# logger.warning("JFJoch returned no ScanResult; using fake result for rotation scan.")
# result = self._build_fake_rotation_result(request)
if self.__cfg.simulated_detector:
logger.warning("Detector in simulation mode, returning fake zero rotation result.")
result = self._build_fake_rotation_result(request)
if self.sample is not None and self.sample.db_id is not None:
self.save_screenshot_db(self.sample.db_id, "after_dc")
else:
# Let JFJochCommunicationError propagate
result = self.__jfjoch.wait_till_done(60)
# if self.sample is not None and self.sample.db_id is not None:
# self.save_screenshot_db(self.sample.db_id, "after_dc")
# try:
# self.__aare.ingest_scan(sample=self.sample, result=result,
# geom=self.sample_geometry, beam_mark_pxl=self.__cfg.get_beam_mark(self.zoom))
#
# except Exception as e:
# logger.error(f"Exception ingesting scan: {e}")
except JFJochCommunicationError:
raise
except Exception as e:
logger.error(f"Exception during rotation scan: {e}")
#result = self._build_fake_rotation_result(request)
raise
return self._build_fake_rotation_result(request)
#return CompletedRotationScan(request=copy.deepcopy(request), result=result)
return CompletedRotationScan(request=copy.deepcopy(request), result=result)
def measure_rotation(self, request: RotationScanRequest) -> CompletedRotationScan:
total_time = request.exp_time_s * request.steps
@@ -1879,7 +1903,7 @@ class AareDAQ:
def cancel(self):
if self.__cfg.state == BeamlineStateEnum.DataCollection:
self.__devs.aerotech_stop()
self.__devs.aerotech.cancel()
self.__jfjoch.cancel()
def anneal(self, time_s: float):
+66 -10
View File
@@ -692,12 +692,38 @@ class DAQWorker(QObject):
def handle_rotation_scan_response(self, reply: QNetworkReply):
try:
# Check for HTTP errors first
if reply.error() != QNetworkReply.NetworkError.NoError:
status = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute)
err_msg = reply.errorString()
try:
raw_body = reply.readAll().data().decode("utf-8")
if raw_body:
body_json = json.loads(raw_body)
if isinstance(body_json, dict):
err_msg = body_json.get("message", err_msg)
code = body_json.get("code", "")
# Check if this is a JFJoch error
if code == "JFJOCH_UNAVAILABLE" or status == 503:
self._emit_detector_message(f"JFJoch: {err_msg}", is_error=True)
except Exception:
pass
logger.error(f"Rotation scan failed: {err_msg}")
self.http_error.emit(err_msg)
reply.deleteLater()
return
response_data = self.handle_response(reply)
parsed_response = CompletedRotationScan.model_validate_json(response_data)
self.standard_scan_completed.emit(parsed_response)
except Exception as e:
logger.error(f"Exception from rotation scan response: {e}")
self.http_error.emit(str(e))
finally:
reply.deleteLater()
@Slot(RotationScanRequest)
def standard_scan(self, r: RotationScanRequest):
@@ -712,12 +738,40 @@ class DAQWorker(QObject):
def handle_raster_scan_response(self, reply: QNetworkReply):
try:
# Check for HTTP errors first
if reply.error() != QNetworkReply.NetworkError.NoError:
status = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute)
raw_body = ""
body_json = None
err_msg = reply.errorString()
try:
raw_body = reply.readAll().data().decode("utf-8")
if raw_body:
body_json = json.loads(raw_body)
if isinstance(body_json, dict):
err_msg = body_json.get("message", err_msg)
code = body_json.get("code", "")
# Check if this is a JFJoch error
if code == "JFJOCH_UNAVAILABLE" or status == 503:
self._emit_detector_message(f"JFJoch: {err_msg}", is_error=True)
except Exception:
pass
logger.error(f"Raster scan failed: {err_msg}")
self.http_error.emit(err_msg)
reply.deleteLater()
return
response_data = self.handle_response(reply)
parsed_response = CompletedRasterGrid.model_validate_json(response_data)
self.raster_scan_completed.emit(parsed_response)
except Exception as e:
logger.error(f"Exception from raster scan response: {e}")
self.http_error.emit(str(e))
finally:
reply.deleteLater()
@Slot(RasterGridRequest)
def raster_scan(self, r: RasterGridRequest):
@@ -736,13 +790,14 @@ class DAQWorker(QObject):
bkg = random.gauss(3.0, 0.1),
spots= random.randint(0, 250),
index= random.randint(0, 1),
mos = random.uniform(0, 0.1),
b= random.uniform(15.0, 80.0)
))
logger.debug("check that this works - raster scan - complete raster grid")
reply = CompletedRasterGrid(request = new_copy,
result = ScanResult(file_prefix=r.file_prefix, images=images))
logger.debug(f"It appears to work {reply}")
raster_elem = CompletedRasterGridElem(
request=new_copy,
result=ScanResult(file_prefix=r.file_prefix, images=images),
centre_of_mass = None,
)
reply = CompletedRasterGrid(r=[raster_elem])
self.raster_scan_completed.emit(reply)
return
@@ -769,13 +824,14 @@ class DAQWorker(QObject):
bkg=random.gauss(3.0, 0.1),
spots=random.randint(0, 250),
index=random.randint(0, 1),
mos=random.uniform(0, 0.1),
b=random.uniform(15.0, 80.0)
))
logger.debug("check that this works - raster scan auto - complete raster grid")
reply = CompletedRasterGrid(request=new_copy,
result=ScanResult(file_prefix=r.file_prefix, images=images))
logger.debug(f"It appears to work {reply}")
raster_elem = CompletedRasterGridElem(
request=new_copy,
result=ScanResult(file_prefix=r.file_prefix, images=images),
centre_of_mass = None,
)
reply = CompletedRasterGrid(r=[raster_elem])
self.raster_scan_completed.emit(reply)
return