SFELPHOTON-1335:try to debug

This commit is contained in:
2024-10-24 12:11:50 +02:00
parent 3fc4f50c15
commit 7014351eb4
2 changed files with 128 additions and 72 deletions

View File

@@ -16,6 +16,10 @@ psigithub git@git.psi.ch:epics_support_apps/ppmac.git --> ~/Documents/prj/Sw
packages needed by PBTools for lowest level communication to PowerBrick packages needed by PBTools for lowest level communication to PowerBrick
additional module 'slic' is needed, which is provided by Sven and covers the JungFrau acquisition framefork additional module 'slic' is needed, which is provided by Sven and covers the JungFrau acquisition framefork
For motion/frame synchronization read:
~/Documents/prj/SwissFEL/apps/PBSwissMX/Readme.md
``` ```
deployment and tests (update: 18.01.24) deployment and tests (update: 18.01.24)
@@ -24,7 +28,6 @@ deployment and tests (update: 18.01.24)
#initial full deployment: #initial full deployment:
git commit-amend && git push psigithub -f && make uninstall init update git commit-amend && git push psigithub -f && make uninstall init update
Document to start SwissMX in cristallina environment: Document to start SwissMX in cristallina environment:
https://docs.google.com/document/d/1yEmV_DbRBKQKVCoovjXriNgSjNEBaz50WA0l3yA5jtg/edit#heading=h.z9io692b8tow https://docs.google.com/document/d/1yEmV_DbRBKQKVCoovjXriNgSjNEBaz50WA0l3yA5jtg/edit#heading=h.z9io692b8tow
``` ```
@@ -32,25 +35,18 @@ https://docs.google.com/document/d/1yEmV_DbRBKQKVCoovjXriNgSjNEBaz50WA0l3yA5jtg/
* push local stuff to git * * push local stuff to git *
*************************** ***************************
zamofing_t@ganymede: zamofing_t@ganymede:
cd ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX &&\ cd ~/Documents/prj/SwissFEL/apps/SwissMX &&\
git commit-amend &&\ git commit-amend &&\
git push psigithub git push psigithub -f
cd ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX &&\ cd ~/Documents/prj/SwissFEL/apps/PBSwissMX &&\
git commit-amend &&\ git commit-amend &&\
git push psigithub git push psigithub -f
************************************* *************************************
* switch to latest test environment * * switch to latest test environment *
************************************* *************************************
ssh zamofing_t@saresc-cons-03 ssh saresc-cons-03
#first time only:
cd /sf/cristallina/applications/
git clone -o psigithub git@git.psi.ch:grp-sf_cristallina/SwissMX.git
git clone -o psigithub git@git.psi.ch:grp-sf_cristallina/SwissMX_PB.git
rsync -vain ~/Documents/prj/SwissFEL/apps/SwissMX/simCamImg saresc-cons-03:/sf/cristallina/applications/SwissMX/
cd /sf/cristallina/applications/SwissMX
cd /sf/cristallina/applications/SwissMX &&\ cd /sf/cristallina/applications/SwissMX &&\
git checkout master &&\ git checkout master &&\
@@ -60,7 +56,7 @@ git reset psigithub/master --hard &&\
git stash pop git stash pop
#git pull psigithub --ff-only master #git pull psigithub --ff-only master
cd /sf/cristallina/applications/SwissMX_PB &&\ cd /sf/cristallina/applications/SwissMX/PBSwissMX &&\
git checkout master &&\ git checkout master &&\
git stash push &&\ git stash push &&\
git fetch psigithub master &&\ git fetch psigithub master &&\
@@ -68,18 +64,22 @@ git reset psigithub/master --hard &&\
git stash pop git stash pop
#git pull psigithub --ff-only master #git pull psigithub --ff-only master
chmod -R g+w /sf/cristallina/applications/SwissMX
******************* *******************
* run application * * run application *
******************* *******************
additionally needed packages on an RH8 system:
pip install --user pandas zmq qtawesome
mkdir -p /sf/cristallina/applications/python3.6-packages
pip3.6 install --prefix /sf/cristallina/applications/SwissMX pandas zmq qtawesome
cd /sf/cristallina/applications/SwissMX *** with official python ***
/opt/gfa/python-3.8/latest/bin/python swissmx.py additionally needed packages:
RH7:
[saresc-vcons-01 ~]$ /opt/gfa/python-3.8/latest/bin/pip install --user qtawesome
RH8:
[saresc-cons-03 ~]$ pip install --user qtawesome
swissmx
#with conda environment:
ssh gac-cristall@saresc-cons-03 (pw:ValToira_2021) ssh gac-cristall@saresc-cons-03 (pw:ValToira_2021)
cd /sf/cristallina/applications/SwissMX/ cd /sf/cristallina/applications/SwissMX/
# conda env list # conda env list

View File

@@ -17,6 +17,7 @@ if __name__ == "__main__":
sys.path.insert(0, os.path.join(base,'PBSwissMX/python')) sys.path.insert(0, os.path.join(base,'PBSwissMX/python'))
elif socket.gethostname()!='ganymede': elif socket.gethostname()!='ganymede':
sys.path.insert(0, os.path.expanduser('/sf/cristallina/applications/slic/slic-package')) sys.path.insert(0, os.path.expanduser('/sf/cristallina/applications/slic/slic-package'))
sys.path.insert(0, os.path.expanduser('/sf/cristallina/applications/mx/swissmx_tools/jfj'))
from PyQt5.QtWidgets import (QApplication,) from PyQt5.QtWidgets import (QApplication,)
from app_config import AppCfg #settings, option, toggle_option from app_config import AppCfg #settings, option, toggle_option
@@ -28,12 +29,14 @@ import shapepath
try: try:
from slic.core.acquisition import SFAcquisition from slic.core.acquisition import SFAcquisition
from slic.core.acquisition.broker.tools import get_endstation
from slic.devices.timing.events import CTASequencer from slic.devices.timing.events import CTASequencer
from ctadaq import CTAAcquisition from ctadaq import CTAAcquisition
from jfjoch_device import JFJ from jfjoch_device import JFJ
except ImportError as e: except ImportError as e:
_log.warning(e) _log.warning(e)
class Shutter: class Shutter:
def __init__(self,mode=1): def __init__(self,mode=1):
@@ -49,15 +52,20 @@ class Shutter:
_log.info('open simulated shutter') _log.info('open simulated shutter')
elif mode==1: elif mode==1:
# open laser shutter # open laser shutter
epics.caput("SLAAR31-LPSYS-ESC:LHX1_SHUT_OPEN", 1) #epics.caput("SLAAR31-LPSYS-ESC:LHX1_SHUT_OPEN", 1) '''think this shutter is no longer used'''
if self.sync_flag==0: #if using cta, sets pulse_picker output to follow pulser 3 if epics.caget("SLAAR31-LPSYS-ESCIP23:ONOFF.RVAL") == 1:
epics.caput("SLAAR31-LPSYS-ESCOP0:ONOFF", 1)
_log.info('laser shutter opened')
if self.sync_flag==0: #if using cta, sets pulse_picker output to follow pulser 0
# open fast shutter # open fast shutter
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD", 3)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD2", 3)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE", 0) epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE", 0)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE2", 0) epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE2", 0)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD", 0)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD2", 0)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP", 1) epics.caput("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP", 1)
_log.info('shutter opened') _log.info('fast shutter opened')
def close(self): def close(self):
mode=self._mode mode=self._mode
@@ -66,16 +74,19 @@ class Shutter:
elif mode==1: elif mode==1:
# close laser shutter # close laser shutter
epics.caput("SLAAR31-LPSYS-ESC:LHX1_SHUT_CLOSE", 1) if epics.caget("SLAAR31-LPSYS-ESCIP23:ONOFF.RVAL") == 1:
_log.info('shutter closed') epics.caput("SLAAR31-LPSYS-ESCOP2:ONOFF", 1)
_log.info('laser shutter closed')
#epics.caput("SLAAR31-LPSYS-ESC:LHX1_SHUT_CLOSE", 1) '''think this shutter is no longer used'''
# close fast shutter # close fast shutter
epics.caput("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP", 0) epics.caput("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP", 0)
if self.sync_flag==0: #if using cta, sets pulse_picker output back to high low, could do this every time? if self.sync_flag==0: #if using cta, sets pulse_picker output back to high low, could do this every time?
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD", 1)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD2", 1)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE", 3) epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE", 3)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE2", 4) epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SOURCE2", 4)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD", 4)
epics.caput("SARES30-LTIM01-EVR0:RearUniv0_SNUMPD2", 4)
_log.info('fast shutter closed')
class Deltatau: class Deltatau:
def __init__(self,sim=False): def __init__(self,sim=False):
@@ -112,6 +123,8 @@ class Jungfrau:
self._pv_pulse_id.connect() self._pv_pulse_id.connect()
except NameError as e: except NameError as e:
_log.critical(f'Jungfrau not connected: {e}') _log.critical(f'Jungfrau not connected: {e}')
self.n_pulses_run = None
self.bsdata_scalar = 1
def config(self,**kwargs): def config(self,**kwargs):
if getattr(self,'_sim',False): if getattr(self,'_sim',False):
@@ -129,61 +142,57 @@ class Jungfrau:
code_gen=kwargs.get('code_gen',0) code_gen=kwargs.get('code_gen',0)
sync_mode=dt_misc['sync_mode'] sync_mode=dt_misc['sync_mode']
sync_flag=dt_misc['sync_flag'] sync_flag=dt_misc['sync_flag']
self.n_pulses_run = None
if loc['jungfraujoch']: if loc['jungfraujoch']:
try: try:
self.jfj = JFJ("http://sf-daq-2:5232") self.jfj = JFJ("http://sf-daq-2:5232")
self.detectors=None self.detectors=None
except: _log.info(f'JungFrauJoch connected')
except NameError as e:
self.jfj = None self.jfj = None
_log.critical(f'JungfrauJoch not connected: {e}')
is_scan_step=False
else: else:
self.jfj = None self.jfj = None
if sync_flag==0: if sync_flag==0:
grid_cnt=kwargs['grid']['count'] grid_cnt=kwargs['grid']['count']
repetitions=grid_cnt[0] #'x' or number of columns repetitions=grid_cnt[0] #'x' or number of columns
cta_multiplier=grid_cnt[1] #'y' or number of appertures in a column/number of rows cta_multiplier=grid_cnt[1] #'y' or number of appertures in a column/number of rows
number_of_appertures = repetitions*cta_multiplier
cta=CTASequencer("SAR-CCTA-ESC") cta=CTASequencer("SAR-CCTA-ESC")
cta.cfg.repetitions = repetitions
self.images=repetitions*cta_multiplier
if code_gen==3: if code_gen==3:
if kwargs['tmove']==0:
wait_pulses=0
else:
wait_pulses=kwargs['twait']//kwargs['tmove'] wait_pulses=kwargs['twait']//kwargs['tmove']
#xray_seq=[0,]*wait_pulses+[1] # multiplier is proportional to wait_time i.e. 10 ms = 1, 20 ms =2, 30 ms =3. #xray_seq=[0,]*wait_pulses+[1] # multiplier is proportional to wait_time i.e. 10 ms = 1, 20 ms =2, 30 ms =3.
xray_seq=[1,]+[0,]*wait_pulses xray_sequence=[0,]*wait_pulses+[1]
cta.seq[200]=xray_seq*cta_multiplier # x-ray_shutter cta.seq[200]=xray_sequence*cta_multiplier # x-ray_shutter
laser_seq=[1,]*wait_pulses+[1] cta.seq[214] = [1,] + [0,] * (len(xray_sequence * cta_multiplier) -1)
cta.seq[215]=laser_seq*cta_multiplier # laser_shutter trigger_sequence=[1,]*wait_pulses+[1]
droplet_sequence=[0, 1, 0, 0] # sub 8 ms delay = [0, 0, 1, 0] cta.seq[215]=trigger_sequence*(cta_multiplier//2) # laser_shutter
cta.seq[216]=droplet_sequence*(cta_multiplier//2) image_label_sequence = [0,] * wait_pulses + [1] + [0,] * wait_pulses + [0]
cta.seq[214]=[1,]+[0,]*(len(laser_seq*cta_multiplier)-1) cta.seq[216]=image_label_sequence*(cta_multiplier//2)
cta.seq[219] = xray_sequence * cta_multiplier
else: else:
print('not code gen 3') print('not code gen 3')
#cta_multiplier-=14 # no extra rows 1:1
#cta.seq[200]=[0,0,0,0,0,0,0]+[1,]*cta_multiplier + [0,0,0,0,0,0,0] # for +7 row chip x-ray cta.seq[214]=[1,]+[0,]*(cta_multiplier-1) #start motion
#cta.seq[215]=[0,0,0,0,0,0,0]+[1,]*cta_multiplier + [0,0,0,0,0,0,0] # for +7 row chip laser
#cta.seq[214]=[1,0,0,0,0,0,0]+[0,]*cta_multiplier + [0,0,0,0,0,0,0] # for +7 row chip start
# no extra rows
cta.seq[214]=[1,]+[0,]*(cta_multiplier-1)
cta.seq[200]=[1,]*cta_multiplier # x-ray_shutter cta.seq[200]=[1,]*cta_multiplier # x-ray_shutter
#cta.seq[215]=[1,]*cta_multiplier # laser_shutter cta.seq[219]=[1,]*cta_multiplier #trigger detector
#cta.seq[216]=[1,]*cta_multiplier # droplet_ejector all cta.seq[215]=[1,0,]*(cta_multiplier//2) # Trigger 1:1
cta.seq[216]=[1,0,]*(cta_multiplier//2) # droplet_ejector 1:1 cta.seq[216]=[1,0,]*(cta_multiplier//2) # Label image light dark 1:1
#cta.seq[216]=[1,0,0,]*(cta_multiplier//3) # droplet_ejector 1:2
#cta.seq[216]=[1,0,0,0,0,0,]*(cta_multiplier//6) # droplet_ejector 1:5
#cta.seq[216]=[1,0,0,0,0,0,0,0,0,]*(cta_multiplier//9) # droplet_ejector 1:8
#cta.seq[216]=[1,0,0,0,0,0,0,0,0,0,0,0,]*(cta_multiplier//12) # droplet_ejector 1:11
# skip 6 rows add 6 on end -- first 2 and 1 216 self.n_pulses_run = len(cta.seq[200])*repetitions
#cta.seq[214]=[1,0,0,0,0,0,]+[0,]*(cta_multiplier-12)+[0,0,0,0,0,0,] self.bsdata_scalar = self.n_pulses_run/number_of_appertures
#cta.seq[200]=[0,0,0,0,0,0,]+[1,]*(cta_multiplier-12)+[0,0,0,0,0,0,] # x-ray_shutter _log.info(f'The multiplier of the block size is {self.bsdata_scalar}')
#cta.seq[216]=[0,0,0,0,0,0,]+[1,]*(cta_multiplier-12)+[0,0,0,0,0,0,] # droplet_ejector all
#cta.seq[216]=[0,0,0,0,0,0,]+[1,0,]*((cta_multiplier-12)//2)+[0,0,0,0,0,0,] # droplet_ejector 1:1
#cta.seq[216]=[0,0,0,0,0,0,]+[1,0,0,]*((cta_multiplier-12)//3)+[0,0,0,0,0,0] # droplet_ejector 1:2
#cta.seq[216]=[0,0,0,0,0,0,]+[1,0,0,0]*((cta_multiplier-12)//4)+[0,0,0,0,0,0] # droplet_ejector 1:3
#cta.seq[216]=[0,0,0,0,0,0,]+[1,0,0,0,0,0,]*((cta_multiplier-12)//6)+[0,0,0,0,0,0]# droplet_ejector 1:5
#cta.seq[216]=[0,0,0,0,0,0,]+[1,0,0,0,0,0,0,0,0,0,0,0,]*((cta_multiplier-12)//12)+[0,0,0,0,0,0] # droplet_ejector 1:11
cta.cfg.repetitions=repetitions # self._cta.cfg.repetitions = n_pulses_run/cta_multiplier
cta.seq.upload() cta.seq.upload()
self._daq=CTAAcquisition(cta, loc['end_station'], loc['p_group'], default_detectors=detectors, self._daq=CTAAcquisition(cta, loc['end_station'], loc['p_group'], default_detectors=detectors,
default_channels=bs_channels, default_channels=bs_channels,
default_pvs=pv_channels, rate_multiplicator=1, append_user_tag_to_data_dir=True) default_pvs=pv_channels, rate_multiplicator=1, append_user_tag_to_data_dir=True, timeout=30)
else: else:
self._daq=SFAcquisition( self._daq=SFAcquisition(
loc['end_station'], loc['p_group'], loc['end_station'], loc['p_group'],
@@ -202,21 +211,68 @@ class Jungfrau:
app=QApplication.instance() app=QApplication.instance()
cfg=app._cfg cfg=app._cfg
run=cfg.value(AppCfg.DAQ_RUN) run=cfg.value(AppCfg.DAQ_RUN)
loc=cfg.value(AppCfg.DAQ_LOC)
#data_proc=cfg.value(AppCfg.DATA_PROC)
#daq_sample=cfg.value(AppCfg.DAQ_SAMPLE)
#daq_uc=cfg.value(AppCfg.DAQ_UC)
try: try:
self._pulse_id_start=int(self._pv_pulse_id.value) self._pulse_id_start=int(self._pv_pulse_id.value)
except TypeError as e: except TypeError as e:
_log.warning(f'failed to get _pulse_id_start: {e}') _log.warning(f'failed to get _pulse_id_start: {e}')
n_pulses_run = n_pulses + run['padding'] if self.n_pulses_run:
n_pulses_run*=2 # comment me out please when not using 10 ms wait (for stop and go) n_pulses_run=self.n_pulses_run
print('number of triggers ', n_pulses_run, ' is greater than the number of appertures', n_pulses) _log.info(f'self.n_pulses_run {self.n_pulses_run} is equal to n_pulses_run {n_pulses_run}')
block_size = run['block_size'] _log.info(f'number of images to JFJ is {self.images}')
if self.jfj:
self.jfj.acquire(beam_x_pxl = 1613, beam_y_pxl = 1666, detector_distance_mm = 151, photon_energy_keV = 12, sample_name = run['cell_name'], file_prefix = run['prefix'], ntrigger = n_pulses_run)
if type(self._daq) is CTAAcquisition:
self._daq.acquire(run['prefix'], n_pulses=max(n_pulses_run, block_size), n_block_size=block_size, wait=False, cell_name=run['cell_name'])
else: else:
self._daq.acquire(run['prefix'], n_pulses=max(n_pulses_run, block_size), n_repeat=ceil(n_pulses_run/block_size), wait=False, cell_name=run['cell_name']) n_pulses_run = n_pulses + run['padding']
_log.info(f'self.n_pulses_run {self.n_pulses_run} is not equal to n_pulses_run {n_pulses_run}')
#n_pulses_run*=2 # comment me out please when not using 10 ms wait (for stop and go)
images_per_file = run['block_size']
sample_name = run['prefix'] #daq_sample['sample_name'] #protein_name
prefix = run['prefix']
user_tag = f'{sample_name}_{prefix}'
if self.jfj:
daq_uc={"a":70,"b":70,"c":70,"alpha":90,"beta":90,"gamma":90}
unit_cell = {"a":daq_uc['a'],"b":daq_uc['b'], "c":daq_uc['c'],"alpha":daq_uc['alpha'], "beta":daq_uc['beta'], "gamma":daq_uc['gamma']}
transmission_ATT53 = epics.caget("SARFE10-OATT053:UsrRec.TD")
transmission_ATT150 = epics.caget("SAROP31-OATA150:UsrRec.TD")
transmission = transmission_ATT53*transmission_ATT150
detector_distance_mm = round(epics.caget("SAR-EXPMX:MOT_DET_Z.RBV"),2)
run_number = self._daq.client.next_run()
is_scan_step = True
pgroup=loc['p_group']
try:
endstation = get_endstation()
_log.info(f'got endstation through slic:{endstation}')
except:
endstation = loc['end_station'] #'cristallina' #need cdoe form slic to direct this
_log.info(f'got endstation through gui:{endstation}')
jfj_file_prefix = f'sf/{endstation}/data/{pgroup}/raw/run{run_number:04}-{user_tag}/data/acq'
header_appendix ='{'
#for key in data_proc.keys():
# value = data_proc[key]
# pair =f'"{key}":{value},'
# header_appendix+=pair
header_appendix+='}' #some keys are different in JFJoch
self.jfj.acquire(beam_x_pxl = loc['beam_x'], beam_y_pxl = loc['beam_y'], detector_distance_mm = detector_distance_mm, incident_energy_keV = loc['incident_energy_kev'], transmission = transmission,
sample_name = sample_name, run_number = run_number, file_prefix = jfj_file_prefix, experiment_group=pgroup, ntrigger = self.images, images_per_file = images_per_file,
unit_cell=unit_cell, space_group_number='42',#daq_uc['space_group_number'],
header_appendix=header_appendix
)
_log.info('JFJ primed')
else:
is_scan_step=False
block_size = int(run['block_size']*self.bsdata_scalar) #scales block_size for bsdata acquisition only
_log.info(f'The multiplier of the block size is {self.bsdata_scalar}, new block size is {block_size}')
if type(self._daq) is CTAAcquisition:
self._daq.acquire(user_tag, n_pulses=max(n_pulses_run, block_size), n_block_size=block_size, wait=False, cell_name=run['cell_name'], is_scan_step=is_scan_step)
else:
self._daq.acquire(user_tag, n_pulses=max(n_pulses_run, block_size), n_repeat=ceil(n_pulses_run/block_size), wait=False, cell_name=run['cell_name'], is_scan_step=is_scan_step)
cfg.setValue(AppCfg.DAQ_RUN,run) cfg.setValue(AppCfg.DAQ_RUN,run)
is_scan_step=False
def gather_upload(self): def gather_upload(self):
if getattr(self,'_sim',False): if getattr(self,'_sim',False):