Work on fede scans

This commit is contained in:
gac-x05la
2025-02-18 18:50:04 +01:00
parent f6fecfdc3f
commit 9d104173bd
3 changed files with 91 additions and 53 deletions

View File

@@ -49,6 +49,10 @@ class StdDaqMixin(CustomDeviceMixin):
d["image_height"] = scanargs["image_height"]
if "nr_writers" in scanargs and scanargs["nr_writers"] is not None:
d["nr_writers"] = scanargs["nr_writers"]
if "system_config" in scanargs and scanargs["system_config"] is not None:
if scanargs['system_config']['file_directory']:
file_directory = scanargs['system_config']['file_directory']
### to be used in the future to substitute the procedure using file path
if "file_path" in scanargs and scanargs["file_path"] is not None:
self.parent.file_path.set(scanargs["file_path"].replace("data", "gpfs")).wait()
print(scanargs["file_path"])
@@ -428,6 +432,7 @@ class StdDaqClient(PSIDeviceBase):
return result
status = SubscriptionStatus(self.runstatus, is_running, settle_time=0.5)
# status.set_finished()
return status
def get_daq_config(self, update=False) -> dict:

View File

@@ -57,7 +57,6 @@ class AcquireDark(Acquire):
class AcquireWhite(Acquire):
scan_name = "acquire_white"
required_kwargs = ["exp_burst", "sample_position_out", "sample_angle_out", "motor"]
gui_config = {"Acquisition parameters": ["exp_burst"]}
def __init__(self, exp_burst: int, sample_position_out: float, sample_angle_out: float, motor: DeviceBase, **kwargs):
@@ -111,20 +110,20 @@ class AcquireWhite(Acquire):
def scan_core(self):
# open the shutter and move the sample stage to the out position
self.scan_motors = [self.motor_sample, "es1_roty"] # change to the correct shutter device
yield from self._move_scan_motors_and_wait([self.sample_position_out, self.sample_angle_out])
self.scan_motors = ["eyex"] # change to the correct shutter device
yield from self._move_scan_motors_and_wait([self.dark_shutter_pos_out])
# move the sample stage to the out position and correct angular position
status_sample_out_angle = yield from self.stubs.set(device=[self.motor_sample, "es1_roty"], value=[self.sample_position_out, self.sample_angle_out], wait=False)
# open the main shutter (TODO change to the correct shutter device)
yield from self.stubs.set(device=["eyex"], value=[self.dark_shutter_pos_out])
status_sample_out_angle.wait()
# TODO add opening of fast shutter
yield from super().scan_core()
# TODO add closing of fast shutter
yield from self._move_scan_motors_and_wait([self.dark_shutter_pos_in])
yield from self.stubs.set(device=["eyex"], value=[self.dark_shutter_pos_in])
class AcquireProjections(AsyncFlyScanBase):
scan_name = "acquire_projections"
required_kwargs = ["motor", "exp_burst", "sample_position_in", "start_angle", "angular_range"]
gui_config = {"Acquisition parameters": ["exp_burst"]}
def __init__(self,
@@ -138,8 +137,6 @@ class AcquireProjections(AsyncFlyScanBase):
Acquire projection images.
Args:
motor :
motor : DeviceBase
Motor to move continuously from start to stop position
exp_burst : int
@@ -174,83 +171,69 @@ class AcquireProjections(AsyncFlyScanBase):
>>> scans.acquire_projections()
"""
super().__init__(**kwargs)
self.motor = motor
super().__init__(**kwargs)
self.burst_at_each_point = 1
self.sample_position_in = sample_position_in
self.start_angle = start_angle
self.angular_range = angular_range
#self.scan_motors = ["eyex", "eyez", "es1_roty"] # change to the correct shutter device
self.dark_shutter_pos_out = 1 ### change with a variable
self.dark_shutter_pos_in = 0 ### change with a variable
def update_scan_motors(self):
return [self.motor]
def prepare_positions(self):
self.positions = np.array([[self.start_angle], [self.start_angle+self.angular_range]])
self.num_pos = None
yield from self._set_position_offset()
def scan_core(self):
# move to in position and go to start position
self.scan_motors = ["eyez", self.motor]
yield from self._move_scan_motors_and_wait([self.sample_position_in, self.positions[0][0]])
# move to in position and go to start angular position
yield from self.stubs.set(device=["eyez", self.motor], value=[self.sample_position_in, self.positions[0][0]])
# open the shutter
self.scan_motors = ["eyex"] # change to the correct shutter device
yield from self._move_scan_motors_and_wait([self.dark_shutter_pos_out])
yield from self.stubs.set(device="eyex", value=self.dark_shutter_pos_out)
# TODO add opening of fast shutter
# start the flyer
# flyer_request = yield from self.stubs.set_with_response(
# device=self.motor, value=self.positions[1][0]
# )
flyer_request = yield from self.stubs.set(
device=self.motor, value=self.positions[1][0], wait=True
device=self.motor, value=self.positions[1][0], wait=False
)
self.connector.send_client_info(
"Starting the scan", show_asap=True, rid=self.metadata.get("RID")
)
# send a trigger
# yield from self.stubs.trigger(group="trigger", point_id=self.point_id)
yield from self.stubs.trigger(wait=False)
while True:
# read the data
# yield from self.stubs.read_and_wait(
# group="primary", wait_group="readout_primary", point_id=self.point_id
# )
)
yield from self.stubs.trigger()
while not flyer_request.done:
yield from self.stubs.read(
device=self.motor, point_id=self.point_id, wait=True
group="monitored", point_id=self.point_id
)
time.sleep(1)
if self.stubs.request_is_completed(flyer_request):
# stop the scan if the motor has reached the stop position
break
# increase the point id
self.point_id += 1
def finalize(self):
yield from super().finalize()
self.num_pos = self.point_id + 1
self.num_pos = self.point_id
class AcquireRefs(Acquire):
scan_name = "acquire_refs"
required_kwargs = []
gui_config = {}
def __init__(
self,
motor: DeviceBase,
num_darks: int = 0,
num_flats: int = 0,
sample_angle_out: float = 0,
sample_position_in: float = 0,
sample_position_out: float = 5000,
sample_position_out: float = 1,
file_prefix_dark: str = 'tmp_dark',
file_prefix_white: str = 'tmp_white',
**kwargs
@@ -262,24 +245,30 @@ class AcquireRefs(Acquire):
the sample is returned to the sample_in_position afterwards.
Args:
motor : DeviceBase
Motor to be moved to move the sample out of beam
num_darks : int , optional
Number of dark field images to acquire
num_flats : int , optional
Number of white field images to acquire
sample_angle_out : float , optional
Angular position where to take the flat field images
sample_position_in : float , optional
Sample stage X position for sample in beam [um]
sample_position_out : float ,optional
Sample stage X position for sample out of the beam [um]
sample_angle_out : float , optional
Angular position where to take the flat field images
exp_time : float, optional
Exposure time [ms]. If not specified, the currently configured value on the camera will be used
Exposure time [ms]. If not specified, the currently configured value
on the camera will be used
exp_period : float, optional
Exposure period [ms]. If not specified, the currently configured value on the camera will be used
Exposure period [ms]. If not specified, the currently configured value
on the camera will be used
image_width : int, optional
ROI size in the x-direction [pixels]. If not specified, the currently configured value on the camera will be used
ROI size in the x-direction [pixels]. If not specified, the currently
configured value on the camera will be used
image_height : int, optional
ROI size in the y-direction [pixels]. If not specified, the currently configured value on the camera will be used
ROI size in the y-direction [pixels]. If not specified, the currently
configured value on the camera will be used
acq_mode : str, optional
Predefined acquisition mode (default= 'default')
file_path : str, optional
@@ -292,6 +281,7 @@ class AcquireRefs(Acquire):
>>> scans.acquire_refs(sample_angle_out=90, sample_position_in=10, num_darks=5, num_flats=5, exp_time=0.1)
"""
self.motor = motor
super().__init__(**kwargs)
self.sample_position_in = sample_position_in
self.sample_position_out = sample_position_out
@@ -303,24 +293,30 @@ class AcquireRefs(Acquire):
def scan_core(self):
## TODO move sample in position and do not wait
## TODO move angle in position and do not wait
status_sample_out_angle = yield from self.stubs.set(device=[self.motor, "es1_roty"], value=[self.sample_position_out, self.sample_angle_out], wait=False)
if self.num_darks:
self.connector.send_client_info(
f"Acquiring {self.num_darks} dark images",
show_asap=True,
rid=self.metadata.get("RID"),
)
# to set signals on a device
yield from self.stubs.send_rpc_and_wait("gfdaq", "file_prefix.set", self.file_prefix_dark)
yield from self.stubs.send_rpc_and_wait("gfdaq", "num_images.set", self.num_darks)
darks = AcquireDark(
exp_burst=self.num_darks,
file_prefix=self.file_prefix_dark,
device_manager=self.device_manager,
metadata=self.metadata,
instruction_handler=self.stubs._instruction_handler,
**self.caller_kwargs,
)
yield from darks.scan_core()
self.point_id = darks.point_id
status_sample_out_angle.wait()
if self.num_flats:
self.connector.send_client_info(
f"Acquiring {self.num_flats} flat field images",
@@ -331,9 +327,12 @@ class AcquireRefs(Acquire):
exp_burst=self.num_flats,
sample_position_out=self.sample_position_out,
sample_angle_out=self.sample_angle_out,
motor=self.motor,
file_prefix=self.file_prefix_white,
device_manager=self.device_manager,
metadata=self.metadata,
instruction_handler=self.stubs._instruction_handler,
**self.caller_kwargs,
)
flats.point_id = self.point_id
yield from flats.scan_core()

View File

@@ -44,6 +44,10 @@ class Measurement:
self.exposure_period = self.det.cfgFramerate.get()
self.roix = self.det.cfgRoiX.get()
self.roiy = self.det.cfgRoiY.get()
self.get_position_rb()
#self.position_rb = False
#self.disable_position_rb_device()
def build_filename(self, acquisition_type='data'):
@@ -75,7 +79,8 @@ class Measurement:
exposure_period=None, roix=None, roiy=None,nimages=None,
nimages_dark=None, nimages_white=None,
start_angle=None, sample_angle_out=None,
sample_position_in=None, sample_position_out=None):
sample_position_in=None, sample_position_out=None,
position_rb=None):
"""
Reconfigure the measurement with any number of new parameter
@@ -111,6 +116,8 @@ class Measurement:
sample_position_out : float, optional
Sample stage X position for sample out of the beam [um]
(default = None)
position_rb : bool, optional
Enable position readback (default = None)
"""
if sample_name != None:
@@ -139,6 +146,13 @@ class Measurement:
self.sample_position_in = sample_position_in
if sample_position_out != None:
self.sample_position_out = sample_position_out
if position_rb != None:
if position_rb == True:
self.enable_position_rb_device()
elif position_rb == False:
self.disable_position_rb_device()
else:
print("WARNING! Position readback should be either True, False or None")
self.build_filename()
@@ -169,6 +183,12 @@ class Measurement:
self.device_name = self.enabled_detectors[0].name
self.build_filename()
def disable_position_rb_device(self):
"Disable position readback device"
dev.es1_ddaq.enabled= False
self.position_rb = False
def enable_detector(self, detector_name):
"""
@@ -198,7 +218,12 @@ class Measurement:
self.device_name = self.enabled_detectors[0].name
self.build_filename()
def enable_position_rb_device(self):
"Enable position readback device"
dev.es1_ddaq.enabled= True
self.position_rb = True
def get_available_detectors(self):
"""
@@ -216,6 +241,14 @@ class Measurement:
"""
self.enabled_detectors = [obj for obj in dev.get_devices_with_tags('camera') if obj.enabled]
def get_position_rb(self):
"""
Get position rb
"""
if dev.es1_ddaq.enabled == True:
self.position_rb = True
else:
self.position_rb = False
def show_available_detectors(self):
"""
@@ -273,6 +306,7 @@ class Measurement:
print("Sample angle out: " + str(self.sample_angle_out))
print("Sample position in: " + str(self.sample_position_in))
print("Sample position out: " + str(self.sample_position_out))
print("Position readback: " + str(self.position_rb))
def acquire_darks(self,nimages_dark=None, exposure_time=None, exposure_period=None,