From 5e954dec779a03f1809ab308f4a8b94d55c86559 Mon Sep 17 00:00:00 2001 From: Thierry Zamofing Date: Tue, 23 Jan 2024 13:11:23 +0100 Subject: [PATCH] towards cta part 2 --- ctadaq.py | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ psi_device.py | 28 ++++++------ swissmx.py | 3 +- 3 files changed, 135 insertions(+), 13 deletions(-) create mode 100644 ctadaq.py diff --git a/ctadaq.py b/ctadaq.py new file mode 100644 index 0000000..7f7ae82 --- /dev/null +++ b/ctadaq.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# *-----------------------------------------------------------------------* +# | | +# | Copyright (c) 2024 by Paul Scherrer Institute (http://www.psi.ch) | +# | | +# | Author xxx (xxx.xxx@psi.ch) | +# *-----------------------------------------------------------------------* +''' +slic interface class for CTAAcquisition +based on xxx code snipplets +''' + +import numpy as np +from tqdm import tqdm + +from slic.core.acquisition import SFAcquisition +from slic.core.acquisition.sfacquisition import BSChannels, transpose_dicts, print_response +from slic.core.task import DAQTask + + +class CTAAcquisition(SFAcquisition): + + def __init__(self, cta, *args, n_block_size=None, **kwargs): + self.cta = cta + self.n_block_size = n_block_size + super().__init__(*args, **kwargs) + + def acquire(self, filename, data_base_dir=None, detectors=None, channels=None, pvs=None, scan_info=None, n_block_size=None, n_pulses=100, n_repeat=1, is_scan_step=False, wait=True, **kwargs): + if n_repeat != 1: + raise NotImplementedError("Repetitions are not implemented") #TODO + if not is_scan_step: + run_number = self.client.next_run() + print(f"Advanced run number to {run_number}.") + else: + run_number = self.client.run_number + print(f"Continuing run number {run_number}.") +# if not filename or filename == "/dev/null": +# print("Skipping retrieval since no filename was given.") +# return + if detectors is None: + print("No detectors specified, using default detector list.") + detectors = self.default_detectors + if pvs is None: + print("No PVs specified, using default PV list.") + pvs = self.default_pvs + if channels is None: + print("No channels specified, using default channel list.") + channels = self.default_channels + n_block_size = n_block_size or self.n_block_size + print("block size:", n_block_size) + bschs = BSChannels(*channels) + bschs.check() + client = self.client + client.set_config(n_pulses, filename, detectors=detectors, channels=channels, pvs=pvs, scan_info=scan_info, **kwargs) + + def _acquire(): + print('we even made it this far, woah') + self.cta.stop() + print('one more') + self.cta.start() + print('cta started') +# sleep(0.1) ###? + time_start = time() + print('time') + start_pid = self.cta.get_start_pid() + print('reached start') + print("CTA start pid:", start_pid) + print("didn't print start") + stop_pid = start_pid + n_pulses + pids = np.arange(start_pid, stop_pid) + pids_blocks = split(pids, n_block_size) + print('did a block thing') + for pb in tqdm(pids_blocks): +# if filename: + res = self.retrieve(filename, pb, run_number=run_number) +# else: +# res = {} + res = transpose_dicts(res) + filenames = res.pop("filenames") + print_response(res) + # possibly optional, because cta should be done! + while self.cta.is_running(): + sleep(self.wait_time) + delta_time = time() - time_start + print(f"Waiting since {delta_time} seconds for CTA sequence to finish") + return filenames + + def stopper(): + client.stop() + self.cta.stop() + + task = DAQTask(_acquire, stopper=stopper, filename=filename, hold=False) + self.current_task = task + if wait: + try: + task.wait() + except KeyboardInterrupt: + print("Stopped current DAQ task:") + return task + +def split(a, block_size): + if block_size is None: + return [a] + length = len(a) + indices = np.arange(block_size, length, block_size) # must not start at 0, otherwise the first entry is an empty array + return np.array_split(a, indices) + +if __name__ == "__main__": + from slic.devices.timing.events import CTASequencer + + cta = CTASequencer("SAT-CCTA-ESE") + daq = CTAAcquisition(cta, "maloja", "p19509", default_channels=["SAT-CVME-TIFALL5:EvtSet"], append_user_tag_to_data_dir=True) + + cta.cfg.repetitions = n_pulses # etc. etc. + #daq.acquire("test") + + diff --git a/psi_device.py b/psi_device.py index 680ece3..58296ea 100644 --- a/psi_device.py +++ b/psi_device.py @@ -95,12 +95,6 @@ class Jungfrau: if sim: self._sim=True return - app=QApplication.instance() - cfg=app._cfg - detectors = [ cfg.value(AppCfg.DAQ_DET) ] - bs_channels = cfg.value(AppCfg.DAQ_BS_CH) - pv_channels = cfg.value(AppCfg.DAQ_PV_CH) - loc=cfg.value(AppCfg.DAQ_LOC) try: self._pv_pulse_id=epics.PV('SAR-EXPMX-EVR0:RX-PULSEID') self._pv_pulse_id.connect() @@ -110,17 +104,24 @@ class Jungfrau: def config(self,**kwargs): if getattr(self,'_sim',False): _log.info(f'simulated') - code_gen=kwargs['code_gen'] + app=QApplication.instance() #temproary fix, couldnt access these in function, maybe the bt above needs to be self.detectors ... etc + cfg=app._cfg + detectors = [ cfg.value(AppCfg.DAQ_DET) ] + bs_channels = cfg.value(AppCfg.DAQ_BS_CH) + pv_channels = cfg.value(AppCfg.DAQ_PV_CH) + loc=cfg.value(AppCfg.DAQ_LOC) + code_gen=kwargs.get('code_gen',0) if code_gen==3: grid_cnt=kwargs['grid']['count'] kwargs['grid']['count'] self._cta=cta=CTASequencer("SAR-CCTA-ESC") - repetitions=grid_cnt[0] - cta_multiplier=grid_cnt[1]-1 + repetitions=grid_cnt[0] #'x' or number of columns + cta_multiplier=grid_cnt[1]-1 #'y' or number of appertures in a column/number of rows #kwargs['tmove'] kwargs['twait'] - xray_seq=[0]*kwargs['twait']/kwargs['tmove']+[1] # multiplier is proportional to wait_time i.e. 10 ms = 1, 20 ms =2, 30 ms =3. + xray_seq=[0,]*(kwargs['twait']//kwargs['tmove'])+[1] # multiplier is proportional to wait_time i.e. 10 ms = 1, 20 ms =2, 30 ms =3. cta.seq[200]=xray_seq*cta_multiplier # x-ray_shutter - cta.seq[215]=[1]*cta_multiplier*2 # laser_shutter + laser_seq=[1,]*(kwargs['twait']//kwargs['tmove'])+[1] + cta.seq[215]=laser_seq*cta_multiplier # laser_shutter cta.cfg.repetitions=repetitions # self._cta.cfg.repetitions = n_pulses_run/cta_multiplier cta.seq.upload() self._daq=CTAAcquisition(cta, loc['end_station'], loc['p_group'], default_detectors=detectors, @@ -147,7 +148,10 @@ class Jungfrau: _log.warning(f'failed to get _pulse_id_start: {e}') n_pulses_run = n_pulses + run['padding'] block_size = run['block_size'] - self._daq.acquire(run['prefix'], n_pulses=min(n_pulses_run, block_size), n_repeat=ceil(n_pulses_run/block_size), wait=False, cell_name=run['cell_name']) + if type(self._daq) is CTAAcquisition: + self._daq.acquire(run['prefix'], n_pulses=min(n_pulses_run, block_size), n_block_size=block_size, wait=False, cell_name=run['cell_name']) + else: + self._daq.acquire(run['prefix'], n_pulses=min(n_pulses_run, block_size), n_repeat=ceil(n_pulses_run/block_size), wait=False, cell_name=run['cell_name']) cfg.setValue(AppCfg.DAQ_RUN,run) def gather_upload(self): diff --git a/swissmx.py b/swissmx.py index 64a7300..37cccc0 100755 --- a/swissmx.py +++ b/swissmx.py @@ -2420,6 +2420,7 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch) shutter.open() jf.acquire(num_pts) sp.trigger(1.0) # send a start trigger (if needed) after given time + _log.info('start trigger sent') if dt._comm is None: dlg.setLabelText("run motion/acquisition (simulated)") dlg.setMaximum(num_pts) @@ -2450,7 +2451,7 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch) dp.plot_gather(mode=11) plt.show(block=False) #plt.show(block=True) - + _log.info('Shutter closed') shutter.close() # pv-monitor-func: start monitors if not cfg.value(AppCfg.GBL_MISC)['live_on_collect']: