mirror of
https://github.com/bec-project/ophyd_devices.git
synced 2025-05-31 00:50:40 +02:00
refactor: eiger, refactoring done of unstage, stop and closing det and filewriter
This commit is contained in:
parent
7346f5d76a
commit
d9606a4707
@ -179,7 +179,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
Depends on hardware configuration and delay generators.
|
Depends on hardware configuration and delay generators.
|
||||||
At this point it is set up for gating mode (09/2023).
|
At this point it is set up for gating mode (09/2023).
|
||||||
"""
|
"""
|
||||||
self.stop_acquisition()
|
self._stop_detector()
|
||||||
self._set_trigger(TriggerSource.GATING)
|
self._set_trigger(TriggerSource.GATING)
|
||||||
|
|
||||||
# TODO function for abstract class?
|
# TODO function for abstract class?
|
||||||
@ -272,7 +272,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
while not os.path.exists(os.path.dirname(self.filepath)):
|
while not os.path.exists(os.path.dirname(self.filepath)):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
self._close_file_writer()
|
self._stop_file_writer()
|
||||||
logger.info(f" std_daq output filepath {self.filepath}")
|
logger.info(f" std_daq output filepath {self.filepath}")
|
||||||
# TODO Discuss with Leo if this is needed, or how to start the async writing best
|
# TODO Discuss with Leo if this is needed, or how to start the async writing best
|
||||||
try:
|
try:
|
||||||
@ -294,7 +294,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
time.sleep(0.005)
|
time.sleep(0.005)
|
||||||
|
|
||||||
# TODO function for abstract class?
|
# TODO function for abstract class?
|
||||||
def _close_file_writer(self) -> None:
|
def _stop_file_writer(self) -> None:
|
||||||
"""Close file writer"""
|
"""Close file writer"""
|
||||||
self.std_client.stop_writer()
|
self.std_client.stop_writer()
|
||||||
# TODO can I wait for a status message here maybe? To ensure writer returned
|
# TODO can I wait for a status message here maybe? To ensure writer returned
|
||||||
@ -349,6 +349,7 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
)
|
)
|
||||||
pipe.execute()
|
pipe.execute()
|
||||||
|
|
||||||
|
# TODO function for abstract class?
|
||||||
def _arm_acquisition(self) -> None:
|
def _arm_acquisition(self) -> None:
|
||||||
"""Arm detector for acquisition"""
|
"""Arm detector for acquisition"""
|
||||||
self.cam.acquire.put(1)
|
self.cam.acquire.put(1)
|
||||||
@ -369,71 +370,80 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
self._on_trigger()
|
self._on_trigger()
|
||||||
return super().trigger()
|
return super().trigger()
|
||||||
|
|
||||||
|
# TODO function for abstract class?
|
||||||
def _on_trigger(self):
|
def _on_trigger(self):
|
||||||
"""Specify action that should be taken upon trigger signal."""
|
"""Specify action that should be taken upon trigger signal."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# TODO function for abstract class?
|
||||||
# TODO threadlocked was attached, in principle unstage needs to be fast and should possibly called multiple times
|
# TODO threadlocked was attached, in principle unstage needs to be fast and should possibly called multiple times
|
||||||
@threadlocked
|
@threadlocked
|
||||||
def unstage(self) -> List[object]:
|
def unstage(self) -> List[object]:
|
||||||
"""Unstage the device, this means detector and file writer.
|
"""Unstage the device, detector and file writer.
|
||||||
|
|
||||||
|
|
||||||
This method must be idempotent, multiple calls (without a new
|
This method must be idempotent, multiple calls (without a new
|
||||||
call to 'stage') have no effect.
|
call to 'stage') have no effect.
|
||||||
"""
|
"""
|
||||||
logger.info("Waiting for Eiger9M to finish")
|
# TODO solution for multiple calls of the function to avoid calling the finished loop.
|
||||||
|
# Loop to avoid calling the finished loop multiple times
|
||||||
old_scanID = self.scaninfo.scanID
|
old_scanID = self.scaninfo.scanID
|
||||||
self.scaninfo.load_scan_metadata()
|
self.scaninfo.load_scan_metadata()
|
||||||
logger.info(f"Old scanID: {old_scanID}, ")
|
|
||||||
if self.scaninfo.scanID != old_scanID:
|
if self.scaninfo.scanID != old_scanID:
|
||||||
self._stopped = True
|
self._stopped = True
|
||||||
if self._stopped == True:
|
if self._stopped == True:
|
||||||
return super().unstage()
|
return super().unstage()
|
||||||
self._eiger9M_finished()
|
self._finished()
|
||||||
# Message to BEC
|
|
||||||
state = True
|
state = True
|
||||||
self._publish_file_location(done=state, successful=state)
|
self._publish_file_location(done=state, successful=state)
|
||||||
self._stopped = False
|
self._stopped = False
|
||||||
logger.info("Eiger9M finished")
|
|
||||||
return super().unstage()
|
return super().unstage()
|
||||||
|
|
||||||
|
# TODO function for abstract class?
|
||||||
|
# TODO necessary, how can we make this cleaner.
|
||||||
@threadlocked
|
@threadlocked
|
||||||
def _eiger9M_finished(self):
|
def _finished(self):
|
||||||
"""Function with 10s timeout"""
|
"""Check if acquisition is finished.
|
||||||
|
This function is called from unstage and stop
|
||||||
|
and will check detector and file backend status.
|
||||||
|
Timeouts after given time
|
||||||
|
"""
|
||||||
|
sleep_time = 0.1
|
||||||
|
timeout = 5
|
||||||
timer = 0
|
timer = 0
|
||||||
|
# Check status with timeout, break out if _stopped=True
|
||||||
while True:
|
while True:
|
||||||
det_ctrl = self.cam.acquire.read()[self.cam.acquire.name]["value"]
|
det_ctrl = self.cam.acquire.read()[self.cam.acquire.name]["value"]
|
||||||
# det_ctrl = 0
|
|
||||||
std_ctrl = self.std_client.get_status()["acquisition"]["state"]
|
std_ctrl = self.std_client.get_status()["acquisition"]["state"]
|
||||||
status = self.std_client.get_status()
|
status = self.std_client.get_status()
|
||||||
received_frames = status["acquisition"]["stats"]["n_write_completed"]
|
received_frames = status["acquisition"]["stats"]["n_write_completed"]
|
||||||
total_frames = int(self.scaninfo.num_points * self.scaninfo.frames_per_trigger)
|
total_frames = int(self.scaninfo.num_points * self.scaninfo.frames_per_trigger)
|
||||||
# TODO if no writing was performed before
|
|
||||||
if det_ctrl == 0 and std_ctrl == "FINISHED" and total_frames == received_frames:
|
if det_ctrl == 0 and std_ctrl == "FINISHED" and total_frames == received_frames:
|
||||||
break
|
break
|
||||||
if self._stopped == True:
|
if self._stopped == True:
|
||||||
self.stop_acquisition()
|
self._stop_detector()
|
||||||
self._close_file_writer()
|
self._stop_file_writer()
|
||||||
break
|
break
|
||||||
time.sleep(0.1)
|
time.sleep(sleep_time)
|
||||||
timer += 0.1
|
timer += sleep_time
|
||||||
if timer > 5:
|
if timer > timeout:
|
||||||
self._stopped == True
|
self._stopped == True
|
||||||
self._close_file_writer()
|
self._stop_detector()
|
||||||
self.stop_acquisition()
|
self._stop_file_writer()
|
||||||
raise EigerTimeoutError(
|
raise EigerTimeoutError(
|
||||||
f"Reached timeout with detector state {det_ctrl}, std_daq state {std_ctrl} and received frames of {received_frames} for the file writer"
|
f"Reached timeout with detector state {det_ctrl}, std_daq state {std_ctrl} and received frames of {received_frames} for the file writer"
|
||||||
)
|
)
|
||||||
self._close_file_writer()
|
self._stop_detector()
|
||||||
|
self._stop_file_writer()
|
||||||
|
|
||||||
def stop_acquisition(self) -> None:
|
def _stop_detector(self) -> None:
|
||||||
"""Stop the detector and wait for the proper status message"""
|
"""Stop the detector and wait for the proper status message"""
|
||||||
logger.info("Waiting for Eiger9m to be armed")
|
|
||||||
elapsed_time = 0
|
elapsed_time = 0
|
||||||
sleep_time = 0.01
|
sleep_time = 0.01
|
||||||
|
timeout = 5
|
||||||
|
# Stop acquisition
|
||||||
self.cam.acquire.put(0)
|
self.cam.acquire.put(0)
|
||||||
retry = False
|
retry = False
|
||||||
|
# Check status
|
||||||
while True:
|
while True:
|
||||||
det_ctrl = self.cam.detector_state.read()[self.cam.detector_state.name]["value"]
|
det_ctrl = self.cam.detector_state.read()[self.cam.detector_state.name]["value"]
|
||||||
if det_ctrl == int(DetectorState.IDLE):
|
if det_ctrl == int(DetectorState.IDLE):
|
||||||
@ -442,16 +452,17 @@ class Eiger9mCsaxs(DetectorBase):
|
|||||||
break
|
break
|
||||||
time.sleep(sleep_time)
|
time.sleep(sleep_time)
|
||||||
elapsed_time += sleep_time
|
elapsed_time += sleep_time
|
||||||
if elapsed_time > 2 and not retry:
|
if elapsed_time > timeout // 2 and not retry:
|
||||||
retry = True
|
retry = True
|
||||||
|
# Retry to stop acquisition
|
||||||
self.cam.acquire.put(0)
|
self.cam.acquire.put(0)
|
||||||
if elapsed_time > 5:
|
if elapsed_time > timeout:
|
||||||
raise EigerTimeoutError("Failed to stop the acquisition. IOC did not update.")
|
raise EigerTimeoutError("Failed to stop the acquisition. IOC did not update.")
|
||||||
|
|
||||||
def stop(self, *, success=False) -> None:
|
def stop(self, *, success=False) -> None:
|
||||||
"""Stop the scan, with camera and file writer"""
|
"""Stop the scan, with camera and file writer"""
|
||||||
self.stop_acquisition()
|
self._stop_detector()
|
||||||
self._close_file_writer()
|
self._stop_file_writer()
|
||||||
super().stop(success=success)
|
super().stop(success=success)
|
||||||
self._stopped = True
|
self._stopped = True
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user