diff --git a/Log.md b/Log.md new file mode 100644 index 0000000..9e45599 --- /dev/null +++ b/Log.md @@ -0,0 +1,449 @@ + +16.9.22 remote Deltatau test: +----------------------------- +``` +(s.a. /home/zamofing_t/Documents/prj/SwissFEL/PBTools/pbtools/gather/PBGatherPlot.py + +PPMAC=SAR-CPPM-EXPMX1 +rsync -va ~/Documents/prj/SwissFEL/PBTools/pbtools/gather/gather_server root@$PPMAC:/tmp/ + +ssh root@$PPMAC +LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/gather_server +ssh -L 10001:localhost:22 root@$PPMAC 'uname -a' +ssh -L 10002:localhost:2332 root@$PPMAC 'uname -a' +Deltatau host in config: +localhost:10001:10002 (instead SAR-CPPM-EXPMX1) + +ssh gac-cristall@saresc-cons-03 +pw: ValToira_2021 +``` + +4.10.22 final test: +------------------- +``` +zamofing_t@ganymede:~$ ssh gac-cristall@saresc-cons-03 +cd /sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/ +# conda env list +conda activate crmx38 +python swissmx.py + +ssh gac-cristall@saresc-cons-03 ls /sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX + +git@git.psi.ch:epics_ioc_modules/ESB_MX.git + +git remote add sf-cristallina gac-cristall@saresc-cons-03:/sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX + +git fetch sf-cristallina + +# do local changes and commit stuff +git push sf-cristallina +``` + +22.6.23 debug segmentation fault +-------------------------------- +``` +THE CHRISTALLINA CONTROL ROOM RUNS NORMALLY ON saresc-cons-05 +[saresc-cons-05 ~]$ +ulimit -a +ulimit -c unlimited +python -X faulthandler -X tracemalloc -X dev swissmx.py 2>&1 | tee /tmp/swissmx000.log +reset;tail -c+0 -F /tmp/swissmx000.log + +python -X faulthandler -X tracemalloc -X importtime -X dev swissmx.py --sim 0xff +python -X faulthandler -X tracemalloc -X dev swissmx.py --sim 0xff + +zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX$ +rsync -vai swissmx.py saresc-cons-03:/sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/swissmx_segFault.py + +read: https://docs.python.org/3/library/faulthandler.html + +coredump erzeugen +cat /proc/sys/kernel/core_pattern +sudo echo "/tmp/core" > /proc/sys/kernel/core_pattern + +ulimit -c unlimited +python -c "import ctypes; ctypes.string_at(0)" +python -X faulthandler -c "import ctypes; ctypes.string_at(0)" + +Rene did: +[root@saresc-cons-05 ~]# sysctl -w kernel.core_pattern="/tmp/%e_core_dump.%p" +cat /proc/sys/kernel/core_pattern +/tmp/%e_core_dump.%p + +ll /tmp/python_core_dump.* + +gdb python /tmp/core +bt (for facktrace) + +trying python c code extention: +/home/zamofing_t/Documents/prj/scratch/python/sample_c_extension + +Thread 0x00007fd2e16e8700 (most recent call first): + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata + ... + File "/gfa/.mounts/sf_cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/epics_widgets/MotorTweak.py", line 216 in update_label + ... + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped +``` + +29.6.23 Coredump 18h40 +---------------------- +``` +grep -c '5000/5000' * +swissmx000.log:57 +swissmx001.log:36 +swissmx002.log:35 + +swissmx002.log 35*5000 frames +35*5000/100/60 -> every 29.16min of acquisition a crash + +rsync -vai gac-cristall@saresc-cons-05:/tmp/swissmx* ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/log + +ll /tmp/swissmx* +ll /tmp/python_core_dump.* + +Thread 0x00007fb9b13f7700 (most recent call first): + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 1122 in element_count + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 489 in get + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 981 in nelm + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 579 in wrapper + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 1122 in element_count + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 549 in wrapper + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 871 in current_context + File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped + +conda activate crmx38 +ll /tmp/python_core_dump.* +gdb python /tmp/python_core_dump.21072 +Core was generated by `python -X faulthandler -X tracemalloc -X dev swissmx.py'. +Program terminated with signal 11, Segmentation fault. + +bt +0 write_thread_id.isra.3 (is_current=0, fd=) at /opt/conda/conda-bld/python-split_1648465063888/work/Python/traceback.c:849 +#1 _Py_DumpTracebackThreads () at /opt/conda/conda-bld/python-split_1648465063888/work/Python/traceback.c:914 +#2 0x000055c2b7ef6635 in faulthandler_dump_traceback.isra.2 (fd=fd@entry=2, all_threads=1) at /opt/conda/conda-bld/python-split_1648465063888/work/Modules/faulthandler.c:242 +#3 0x000055c2b7ef67a3 in faulthandler_fatal_error (signum=11) at /opt/conda/conda-bld/python-split_1648465063888/work/Modules/faulthandler.c:348 +#4 +#5 0x00007fb9c7ed4ef4 in QWidgetTextControl::document() const () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#6 0x00007fb9c7e676e1 in ?? () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#7 0x00007fb9c7e69230 in QLabel::paintEvent(QPaintEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#8 0x00007fb9d7fa16d3 in sipQLabel::paintEvent(QPaintEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/QtWidgets.abi3.so +#9 0x00007fb9c7dcc580 in QWidget::event(QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#10 0x00007fb9c7e36203 in QFrame::event(QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#11 0x00007fb9d7fa2d03 in sipQLabel::event(QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/QtWidgets.abi3.so +#12 0x00007fb9c7da20f1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#13 0x00007fb9d8097afe in sipQApplication::notify(QObject*, QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/QtWidgets.abi3.so +#14 0x00007fb9e6cadd62 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Core.so.5 +#15 0x00007fb9c7dc6de6 in QWidgetPrivate::sendPaintEvent(QRegion const&) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#16 0x00007fb9c7dc774e in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, QFlags, QPainter*, QWidgetRepaintManager*) () + from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 +#17 0x00007fb9c7dc8147 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList const&, int, QRegion const&, QPoint const&, QFlags, QPainter*, QWidgetRe +``` + +Localize monitors and callbacks: +``` +grep -Rn 'add_callback' *.py + +swissmx.py:698: self.sigNewCamImg.connect(self.cb_update_img) +swissmx.py:745: def cb_update_img(self): +epics_widgets/MotorTweak.py:88: m.set_callback('RBV', self.emit_signals, {'source_field': 'RBV'}) +epics_widgets/SmaractMotorTweak.py:100: self._pv_readback.add_callback(self.update_label) +swissmx.py:717: cam.run(self.cb_new_frame_pv) +swissmx.py:743: self.sigNewCamImg.emit() +swissmx.py:745: def cb_update_img(self): +swissmx.py:698: self.sigNewCamImg.connect(self.cb_update_img) +camera.py:159: self._pv['pic'] = epics.PV(self._prefix + "FPICTURE", auto_monitor=True, callback=cb) + +-> try to turn of the monitors during ascuisition: +zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX$ +grep -r set_callback * + +https://pyepics.github.io/pyepics/pv.html#automatic-monitoring-of-a-pv + +Try with: +pv.clear_auto_monitor() -> pv.reconnect() + +pv.remove_callback(index=None) -> pv.add_callback(callback=None[, index=None [, with_ctrlvars=True[, **kw]]) +pv.set_callback + +FixTargetFrame -> paint -> _log.debug() + +Turn off jungfrau. +no motion -> wait 1h +constant up-dow motion code -> wait 1h +``` + +23.9.24 spitting/moving repositories +------------------------------------ +``` +https://jira.psi.ch/browse/SFELPHOTON-1337: SwissMX split/ cleanup/move repositories +``` + +---------------------------------------------------------------------- +SCRATCH +======= + +Deploy stuff (22.8.22) quick and dirty (21.9.22 rewworked) +---------------------------------------------------------- +``` +DST=/sf/cristallina/applications/mx/zamofing_t/ + +ssh saresc-cons-03 mkdir $DST +# add '--delete' if needed +rsync -vai ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX saresc-cons-03:$DST -n +rsync -vai ~/Documents/prj/SwissFEL/PBTools saresc-cons-03:$DST -n +ssh saresc-cons-03 saresc-cons-03 chmod -R go+w $DST/ESB_MX/python/SwissMX + +cd /sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/ +/opt/gfa/python-3.8/latest/bin/pip install qtawesome --user +/opt/gfa/python-3.8/latest/bin/pip install opencv-python +/opt/gfa/python-3.8/latest/bin/python swissmx.py + +rsync -vai gac-cristall@saresc-cons-03:~/.config/PSI/SwissMX.conf /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/ + +cd $DST +/opt/gfa/python-3.8/latest/bin/python -m pdb swissmx.py +rsync -vai saresc-cons-03:/tmp/image*.png ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/scratch/ +/home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/scratch/autofocus2 +``` + + + +pyqtgraph examples +------------------ +``` +ipython3 +import pyqtgraph.examples +pyqtgraph.examples.run() + +``` + +EPICS simulator +--------------- +``` +This provides very dummy images and motor(to be done) records + +cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/EpicsSim/iocBoot/iocSwissMxSim +./st.cmd +``` + +simulate camera (with EPICS simulator) +-------------------------------------- +``` +cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX +EPICS_CA_ADDR_LIST=localhost +./simCam.py +``` + +test camera display +------------------- +``` +cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX +EPICS_CA_ADDR_LIST=localhost +./camera.py -u -b SwissMxSim +``` + +test at ESC +----------- +``` +https://git.psi.ch/SwissMX/swissmx_cristallina/-/wikis/Instructions%20on%20how%20to%20use%20software + +P=ESB_MX/python/SwissMX/ +ssh saresc-cons-02 mkdir -p /tmp/zamofing_t/$P +rsync -vai ~/Documents/prj/SwissFEL/epics_ioc_modules/$P saresc-cons-02:/tmp/zamofing_t/$P +cd /tmp/zamofing_t/ESB_MX/python/SwissMX +/opt/gfa/python-3.7/2018.12/bin/python camera.py -u 1 -p SARES30-CAMS156-SMX-OAV + +/opt/gfa/python-3.7/2018.12/bin/python swissmx.py + + +caqtdm -macro 'NAME=SARES30-CAMS156-SMX-OAV,CAMNAME=SARES30-CAMS156-SMX-OAV' /sf/controls/config/qt/Camera/CameraExpert_RF.ui + +``` + +try revive Zac code +------------------- +``` +cd /tmp/; git clone https://github.com/malcolmreynolds/transformations.git +cd /tmp/transformations.git +-> modify __init__.py -> .transformation (add dot) +setup.py install --user + + +cd /tmp/; git clone https://github.com/spyder-ide/qtawesome.git +cd /tmp/qtawesome + +#To have epics channels we must be connected to the ESC network +EPICS_CA_ADDR_LIST='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066' +cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/oldRepos/app/src +python swissmx.py +``` + +pyqtgraph examples +------------------ +``` +import pyqtgraph.examples +pyqtgraph.examples.run() +``` + + + +-0.952 +pp_comm.py_: + @property + def fast_gather(self): + tries to connect to port and to query_types(), if fails starts the fast gather process. + +triggerSync.c: +root@:/opt/ppmac# LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync + +usage: +/tmp/triggerSync pt2ptTime timeOfs mode + +pt2ptTime: time in ms (float value) from point to point == frequency if FEL +timeOfs: time offset in ms (float value) for motion relative to the FEL timing + +The program changes the speed of motion +pshm->Coord[1].DesTimeBase= (default serverPeriod= 0.2?) + +SIMFLAG0 (pshm->Coord[1].Q[10]) -> start trigger +SIMFLAG1 (pshm->Coord[1].Q[11]) -> FEL pulse trigger +//Power PMAC Software Reference Manual.pdf Gate3[i].Chan[j].Status -> page 919 UserFlag +#define FLAG0 (gate3_1->Chan[0].Status&0x800) -> start trigger +#define FLAG1 (gate3_1->Chan[1].Status&0x800) -> FEL pulse trigger + + +mode: + bit0:1: sync mode + bit1:2: simulate start trigger + bit2:4: simulate frame trigger + bit3:8: verbose + +simulate start trigger: +set pshm->Coord[1].Q[10]=1 to simulate a Jungfrau aquire start + +simulate frame trigger +is output to pshm->Coord[1].Q[11] + 1: synchronize real frame and start triggers + 3: synchronize real frame and simulated start triggers + 6: simulated frame and start triggers (no sync) + 7: synchronize simulated frame and start triggers + +in simulate mode: +set pshm->Coord[1].Q[10]=1 to simulate a Jungfrau aquire start +set pshm->Coord[1].Q[10]=2 to stop simulate trigger generation +Coord[1].Q[11] is the simulated frame trigger + +in synchronize mode +Coord[1].Q[0]=-2 : trigsync_func start, Wait for 'arm' trigger +Coord[1].Q[0]=-1 : got 'arm' trigger, wait frame trigger +Coord[1].Q[0]= 0 : got frame trigger 0 +Coord[1].Q[0] is incremented at each trigger +sync task ends when Gather.Enable==0 + + + + +// /tmp/triggerSync 40 11 trigger all 40 ms, simulated start, use real frame triggers, verbose +// /tmp/triggerSync 40 14 trigger all 40 ms, simulated start and frame triggers, no sync, verbose +// /tmp/triggerSync 40 15 trigger all 40 ms, simulated start and frame triggers, with sync, verbose +// /tmp/triggerSync 40 7 trigger all 40 ms, simulated start and frame triggers, with sync, minimal verbose + + +78x78 points =6084pts a 10ms =60 sec. -> 70 sec. +-> we are at 100 Hz !!! + +remote ssh tunnel + start gather_server +--------------------------------------- +``` +PPMAC=SAR-CPPM-EXPMX1 +rsync -va ~/Documents/prj/SwissFEL/PBTools/pbtools/gather/gather_server root@$PPMAC:/tmp/ +lsof -i -n | grep '127.0.0.1:1000' +ssh -L 10001:localhost:22 root@$PPMAC 'uname -a' +ssh -L 10002:localhost:2332 root@$PPMAC 'uname -a' +ssh root@$PPMAC +LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/gather_server +``` +cleanup /tmp/ +------------- +``` +PPMAC=SAR-CPPM-EXPMX1 +ssh root@$PPMAC rm /tmp/gather_server /tmp/triggerSync +ssh root@$PPMAC ls -l /tmp +``` +start debug tools +----------------- +``` +PPMAC=SAR-CPPM-EXPMX1 +PBInspect --host=$PPMAC& +gpasciiCommander --host $PPMAC -i +ssh root@$PPMAC +ssh root@$PPMAC rm /tmp/gather_server /tmp/triggerSync +ssh root@$PPMAC ls -l /tmp +``` +restart IOC +----------- +``` +ssh saresc-cons-03 +PPMAC=SAR-CPPM-EXPMX1 +telnet $PPMAC 50001 +Ctrl-X +dbgf SAR-CPPM-EXPMX1:MOD_VER +caget SAR-CPPM-EXPMX1:MOD_VER +``` +checking versions +----------------- +``` +git: 7a968aac967 +asyn 427.0.2 +motorBase alpha_220518 +asynMotor alpha_220518 +powerPmac alpha_220518 +PB_COMMON 2.0.1 +gpasciiCommander 0.9.0 +ESB_MX 0.0.2 +``` +zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX$ +git loggraph -10 +* 7a968aa 2022-09-20 (HEAD -> master, tag: latest, tag: 0.0.2, psigithub/master) change speeds and directions [Thierry Zamofing] +* 00588f8 2022-09-16 minor changes [Thierry Zamofing] +* d52a6ce 2022-08-30 minor changes [Thierry Zamofing] +* f47e111 2022-05-20 (tag: 0.0.1) add DET_Z motor [Thierry Zamofing] +* 8e5b15e 2022-05-20 wip [Thierry Zamofing] +* 399282c 2019-03-20 enhance triggering [Thierry Zamofing] +* eda8caf 2019-03-19 wip [Thierry Zamofing] +* 0c45705 2019-03-08 optimize [Thierry Zamofing] +* c962ebd 2019-03-06 documentation [Thierry Zamofing] +git reset --hard 399282c +rmake -e LIBVERSION=42.42.42 uninstall install +-> restart IOC +ssh root@$PPMAC rm /tmp/triggerSync +cd python +git dt latest -- shapepath.py +./shapepath.py --host=localhost:10001:10002 +removing test verion +ssh sf-lc7 ls -l /ioc/modules/ESB_MX/ +ssh sf-lc7 rm -rf /ioc/modules/ESB_MX/42.42.42 +IOC locations +------------- +``` +~/Documents/prj/SwissFEL/epics_ioc_boot_sf/ESC_all/ESB_MX_PowerBrick +They are just using the new alphy driver. That should have no impact on the motion config. +``` +test shapepath +-------------- +``` +cd ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX +./shapepath.py --host=localhost:10001:10002 +``` + diff --git a/ModuleFixTarget.py b/ModuleFixTarget.py index 85d2f52..3e706f5 100644 --- a/ModuleFixTarget.py +++ b/ModuleFixTarget.py @@ -16,7 +16,7 @@ This contains a Widget to handle FixTargetFrames and fiducials, calculate final import logging _log=logging.getLogger(__name__) -import json, base64 +import os, json, base64, yaml import numpy as np import pyqtUsrObj as UsrGO import pyqtgraph as pg @@ -47,6 +47,22 @@ class MyJsonEncoder(json.JSONEncoder): return repr(obj) return json.JSONEncoder.default(self, obj) + def iterencode(self, o, _one_shot=False): + list_lvl = 0 + l=super().iterencode(o, _one_shot=_one_shot) + #l=tuple(l);print(''.join(l)) # helpful to debug + for s in l: + if s.startswith('['): + list_lvl += 1 + if list_lvl > 0: + s = s[0]+s[1:].replace('\n', '').strip() + s = s.replace('\n', '').rstrip() + #self.item_separator): + #self.key_separator + if s.endswith(']'): + list_lvl -= 1 + yield s + def MyJsonDecoder(dct): if isinstance(dct, dict): if '__class__' in dct: @@ -161,6 +177,30 @@ class WndFixTarget(QWidget): act.triggered.connect(self.tree_ctx_delete) tree.addAction(act) + act = QAction("update param", self) + act.triggered.connect(self.tree_ctx_update) + tree.addAction(act) + + def get_param(self): + param=self._txtParam.text().replace('(','[').replace(')',']').strip() + if param=='' or param[0]!='{': + param='{'+param+'}' + #mft._cbType.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget()", "Grid()", "SwissMX-path"]) + #bm_pos_eu=self._goBeamMarker._pos_eu + #bm_size_eu=self._goBeamMarker._size_eu + try: + #parse the parameters: as yaml string. + # allows : without space, allows () as [] + # no {} to define a dictionary + # e.g. 'a:ggf,b:5,c:[5,6.1],d(8,9,3)' + + param=param.replace(':', ': ') # allow gen:4 without space + param=yaml.safe_load(param) # "ofs":[10, 5],"width":200,"fidScl":0.5,"fiducial":[[18,7],[25,16],[70, 20]] + except BaseException as e: + _log.error(f'{e}:{param}') + param=dict() + return param + def tree_get_path(self): path=[] it=self._tree.currentItem() @@ -213,6 +253,21 @@ class WndFixTarget(QWidget): r1.translate(r2.center()-r1.center()) vb.setRange(r1) + def tree_ctx_update(self): + app=QApplication.instance() + path=self.tree_get_path() + if len(path)==1: + try: + wnd=app._mainWnd + except AttributeError: + _log.info('_mainWnd not handeled') + else: + grp=wnd._goTracked + go=grp.childItems()[path[0]] + go._param=self.get_param() + data=grp.childItems() + self._tree.setData(data) + def load_file(self, filename=None): app = QApplication.instance() if filename is None: @@ -319,7 +374,10 @@ class WndFixTarget(QWidget): #df = pd.DataFrame(data) #df.to_csv(filename, float_format="%.6f") #import numpy as np - ext=filename.rsplit('.',1)[1].lower() + base,ext=os.path.splitext(filename) + if not ext.lower(): + ext='json' + filename=base+'.'+ext try: wnd=app._mainWnd except AttributeError: @@ -329,7 +387,7 @@ class WndFixTarget(QWidget): grp=wnd._goTracked data=grp.childItems() - if ext=='json': + if ext.lower()=='json': with open(filename, 'w') as f: json.dump(data, f,cls=MyJsonEncoder, indent=2)#separators=(',', ':') else: diff --git a/Readme.md b/Readme.md index a480c74..aa1d428 100644 --- a/Readme.md +++ b/Readme.md @@ -1,39 +1,57 @@ -Repository structure and dependency (update:23.09.24) ------------------------------------------------------ +SwissMX +======= + +SwissMX is a python application to operate the SwissMX system at cristallina:
+![alt text](SwissMX.jpg "Title") + + + + +Repositories and dependencies (update:23.09.24) +----------------------------------------------- + +|repo |`https://git.psi.ch/`|`~/Documents/prj/SwissFEL/`|description| +|:- |:- |:- |:- | +|SwissMX |[grp-sf_cristallina/SwissMX.git](https://git.psi.ch/grp-sf_cristallina/SwissMX) |apps/SwissMX |Main python user interface fro SwissMX| +|PBSwissMX|[grp-sf_cristallina/PBSwissMX.git](https://git.psi.ch/grp-sf_cristallina/PBSwissMX) |apps/PBSwissMX |PowerBrick documents and tool to generate trajectories and motion programs for SwissMX| +|PBTools |[epics_support_apps/PBTools.git](https://git.psi.ch/epics_support_apps/PBTools) |PBTools |packages needed by PBSwissMX for low level communication to PowerBrick| +|ppmac |[epics_support_apps/ppmac.git](https://git.psi.ch/epics_support_apps/ppmac) |PBTools/ppmac |packages needed by PBTools for lowest level communication to PowerBrick| +|SW_MX |[epics_ioc_modules/SW_MX.git](https://git.psi.ch/epics_ioc_modules/SW_MX) |epics_ioc_modules/SW_MX |IOC modules and `generate.py` for all SwissMX motors| + +```mermaid +flowchart BT + +PBSwissMX --> SwissMX +PBTools --> PBSwissMX +ppmac --> PBTools +SW_MX-->PBSwissMX ``` -https://jira.psi.ch/browse/SFELPHOTON-1337 + -psigithub git@git.psi.ch:grp-sf_cristallina/SwissMX.git --> ~/Documents/prj/SwissFEL/apps/SwissMX - Main python user interface fro SwissMX +#### installation location +|repo | installed at +|:- |:- +|SwissMX | /sf/cristallina/applications/SwissMX/ +|PBSwissMX| /sf/cristallina/applications/SwissMX/PBSwissMX/ +|PBTools | /sf/cristallina/applications/SwissMX/PBTools/ +|ppmac | /sf/cristallina/applications/SwissMX/PBTools/ppmac/ +|SW_MX | /ioc/modules/SW_MX/ and ioc directories -psigithub git@git.psi.ch:grp-sf_cristallina/PBSwissMX.git --> ~/Documents/prj/SwissFEL/apps/PBSwissMX - PowerBrick documents and tool to generate trajectories and motion programs for SwissMX +#### related documentation +- additional module `slic` is needed, which is provided by Sven and covers the JungFrau acquisition framefork +- For **motion/frame synchronization** read: [grp-sf_cristallina/PBSwissMX.git:Readme.md](https://git.psi.ch/grp-sf_cristallina/PBSwissMX/-/blob/master/Readme.md) +- For old but still usefull information read the [Log.md](Log.md) file +- [SFELPHOTON-1337](https://jira.psi.ch/browse/SFELPHOTON-1337): ticket about restructuing repositories -psigithub git@git.psi.ch:epics_support_apps/PBTools.git --> ~/Documents/prj/SwissFEL/PBTools - packages needed by PBSwissMX for low level communication to PowerBrick +--- -psigithub git@git.psi.ch:epics_support_apps/ppmac.git --> ~/Documents/prj/SwissFEL/PBTools/ppmac - 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 - -For motion/frame synchronization read: - ~/Documents/prj/SwissFEL/apps/PBSwissMX/Readme.md - -``` - -deployment and tests (update: 18.01.24) +deployment and tests (update: 31.10.24) --------------------------------------- - -#initial full deployment: -git commit-amend && git push psigithub -f && make uninstall init update - -Document to start SwissMX in cristallina environment: -https://docs.google.com/document/d/1yEmV_DbRBKQKVCoovjXriNgSjNEBaz50WA0l3yA5jtg/edit#heading=h.z9io692b8tow +#### push local stuff to git ``` -*************************** -* push local stuff to git * -*************************** zamofing_t@ganymede: cd ~/Documents/prj/SwissFEL/apps/SwissMX &&\ git commit-amend &&\ @@ -42,10 +60,9 @@ git push psigithub -f cd ~/Documents/prj/SwissFEL/apps/PBSwissMX &&\ git commit-amend &&\ git push psigithub -f - -************************************* -* switch to latest test environment * -************************************* +``` +#### switch to latest test environment +``` ssh saresc-cons-03 cd /sf/cristallina/applications/SwissMX &&\ @@ -65,511 +82,134 @@ git stash pop #git pull psigithub --ff-only master chmod -R g+w /sf/cristallina/applications/SwissMX - -******************* -* run application * -******************* - +``` +#### run application +``` *** with official python *** 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: +*** with conda environment *** ssh gac-cristall@saresc-cons-03 (pw:ValToira_2021) cd /sf/cristallina/applications/SwissMX/ # conda env list conda activate crmx38 python swissmx.py --sim 0xc0 ``` +Document to start SwissMX in cristallina environment (maintained by John): +https://docs.google.com/document/d/1yEmV_DbRBKQKVCoovjXriNgSjNEBaz50WA0l3yA5jtg/edit#heading=h.z9io692b8tow -pyqtgraph examples ------------------- +## code generation parameters ``` -ipython3 -import pyqtgraph.examples -pyqtgraph.examples.run() +copied from: PBSwissMX/python/shapepath.py: ShapePath.setup_motion + generates program and saves to fnPrg + the type of generated program is defined by $ + -> the list af all points that will be moved at, is in 'mot_pts' + + (m)= mandatory + (o)= optional + common kwargs: + scale : (o) scaling velocity (default=1. value=0 would stop at each point + cnt : (o) move path multiple times (default=1) + dwell : (o) dwell time at end (default=100ms) + + mode:0 unused + mode:1 pvt motion point list + common kwargs plus: + points : (m) point list + trf : (o) transformation that will be done on 'points', mot_pts=trf*points + mode:2 unused + mode:3 pvt motion point list using inverse fft velocity + common kwargs plus: + points : (m) point list + trf : (o) transformation that will be done on 'points', mot_pts=trf*points + numPad : (o) number of padding points to reduce aliasing (default=16) + mode:4 pvt motion short code using grid parameters + common kwargs plus: + trf : (o) transformation that will be done on 'grid points' + grid: (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0} + mode:5 pvt motion 'stop and go' short code using grid parameters. + Instead of continous motion it moves and waits as given in the parameters + common kwargs plus: + trf : (o) transformation that will be done on 'grid points' + grid: (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0} + tmove: (m) time to move in ms (move start on FEL-trigger + twait: (m) time to wait in ms + (tmove+twait will be rounded to a multiple of fel_per) + mode:6 pvt motion 'hit and return using grid parameters. continous motion on 2n ells to pump then same 2n wells to probe, then go 2 rows down + common kwargs plus: + trf : (o) transformation that will be done on 'grid points' + grid : (m) grid parameters: {orig:(0,0),pitch(10,10),cnt:(10,10),mode:0} + ssz : (m) section size (in wells) + smv : (o) time(in num of shots) to move to next section (horiz/vert) + default is (ssz[0]-1,ssz[1]) + sdelay: (o) shots count of delay. Default is ssz[0]*ssz[1] + +Examples: + mode:1 + mode:3 + mode:4 + mode:5,tmove:20,twait:30 + mode:6,ssz:(4,3) +``` +## graphical object parameters +``` + FixTarget: + 90*40+480*2=4560 + 60*30+360*2=2520 + 2520-240=2280 + 4560-240=4320 + size in mm, dscr.size in user units (um) + "size:(6,3.5), + dscr: { + size:(4560,2520), + fiducial:{type:0,pos:((240,240),(4320,240),(240,2280),(4320,2280))}, + grid:{pos:(480,360),pitch:(90,60),count:(40,30)} + }" + + grid: + size, fiducialSize in mm: + (60-1)*.120 -> 7.08mm + (45-1)*.120 -> 5.28mm + fiducialSize -> 0.1mm + "size:(7.08,5.28),cnt:(60,45),fiducialSize:.01" + + SwissMX(): + "ofs:[.2,.2],width:10,fidScl:.02,fiducial:[[.1,.1],[.1,2.7],[10.3,.1],[10.3, 2.7]]" + SwissFEL(): + "ofs:[.2,.2],width:10,fidScl:.02,fiducial:[[.1,.1],[.1,2.2],[10.3,.1],[10.3,2.2]]" ``` -EPICS simulator ---------------- +## fully parameter examples: ``` -This provides very dummy images and motor(to be done) records + "mode:4,size:(7.08,5.28), cnt:(60,45), fiducialSize:.01" -> add a grid -cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/EpicsSim/iocBoot/iocSwissMxSim -./st.cmd -``` + "mode:6,ssz:(4,3), size:(7.08,5.28), cnt:(60,45), fiducialSize:.01" -> add a grid + "mode:6,ssz:(4,3), size:(3,1.5), cnt:(30,15), fiducialSize:.01" -> add a grid -simulate camera (with EPICS simulator) --------------------------------------- -``` -cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX -EPICS_CA_ADDR_LIST=localhost -./simCam.py -``` - -test camera display -------------------- -``` -cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX -EPICS_CA_ADDR_LIST=localhost -./camera.py -u -b SwissMxSim -``` - -test at ESC ------------ -``` -https://git.psi.ch/SwissMX/swissmx_cristallina/-/wikis/Instructions%20on%20how%20to%20use%20software - -P=ESB_MX/python/SwissMX/ -ssh saresc-cons-02 mkdir -p /tmp/zamofing_t/$P -rsync -vai ~/Documents/prj/SwissFEL/epics_ioc_modules/$P saresc-cons-02:/tmp/zamofing_t/$P -cd /tmp/zamofing_t/ESB_MX/python/SwissMX -/opt/gfa/python-3.7/2018.12/bin/python camera.py -u 1 -p SARES30-CAMS156-SMX-OAV - -/opt/gfa/python-3.7/2018.12/bin/python swissmx.py - - -caqtdm -macro 'NAME=SARES30-CAMS156-SMX-OAV,CAMNAME=SARES30-CAMS156-SMX-OAV' /sf/controls/config/qt/Camera/CameraExpert_RF.ui - -``` - -try revive Zac code -------------------- -``` -cd /tmp/; git clone https://github.com/malcolmreynolds/transformations.git -cd /tmp/transformations.git --> modify __init__.py -> .transformation (add dot) -setup.py install --user - - -cd /tmp/; git clone https://github.com/spyder-ide/qtawesome.git -cd /tmp/qtawesome - -#To have epics channels we must be connected to the ESC network -EPICS_CA_ADDR_LIST='129.129.244.255 sf-saresc-cagw.psi.ch:5062 sf-saresc-cagw.psi.ch:5066' -cd /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/oldRepos/app/src -python swissmx.py -``` - -pyqtgraph examples ------------------- -``` -import pyqtgraph.examples -pyqtgraph.examples.run() -``` - - -Deploy stuff (22.8.22) quick and dirty (21.9.22 rewworked) ----------------------------------------------------------- -``` -DST=/sf/cristallina/applications/mx/zamofing_t/ - -ssh saresc-cons-03 mkdir $DST -# add '--delete' if needed -rsync -vai ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX saresc-cons-03:$DST -n -rsync -vai ~/Documents/prj/SwissFEL/PBTools saresc-cons-03:$DST -n -ssh saresc-cons-03 saresc-cons-03 chmod -R go+w $DST/ESB_MX/python/SwissMX - -cd /sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/ -/opt/gfa/python-3.8/latest/bin/pip install qtawesome --user -/opt/gfa/python-3.8/latest/bin/pip install opencv-python -/opt/gfa/python-3.8/latest/bin/python swissmx.py - -rsync -vai gac-cristall@saresc-cons-03:~/.config/PSI/SwissMX.conf /home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/ - -cd $DST -/opt/gfa/python-3.8/latest/bin/python -m pdb swissmx.py -rsync -vai saresc-cons-03:/tmp/image*.png ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/scratch/ -/home/zamofing_t/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/scratch/autofocus2 -``` - -16.9.22 remote Deltatau test: ------------------------------ -``` -(s.a. /home/zamofing_t/Documents/prj/SwissFEL/PBTools/pbtools/gather/PBGatherPlot.py - -PPMAC=SAR-CPPM-EXPMX1 -rsync -va ~/Documents/prj/SwissFEL/PBTools/pbtools/gather/gather_server root@$PPMAC:/tmp/ - -ssh root@$PPMAC -LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/gather_server -ssh -L 10001:localhost:22 root@$PPMAC 'uname -a' -ssh -L 10002:localhost:2332 root@$PPMAC 'uname -a' -Deltatau host in config: -localhost:10001:10002 (instead SAR-CPPM-EXPMX1) - -ssh gac-cristall@saresc-cons-03 -pw: ValToira_2021 -``` - -4.10.22 final test: -------------------- -``` -zamofing_t@ganymede:~$ ssh gac-cristall@saresc-cons-03 -cd /sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/ -# conda env list -conda activate crmx38 -python swissmx.py - - -ssh gac-cristall@saresc-cons-03 ls /sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX - - -git@git.psi.ch:epics_ioc_modules/ESB_MX.git - - -git remote add sf-cristallina gac-cristall@saresc-cons-03:/sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX - -git fetch sf-cristallina - -# do local changes and commit stuff -git push sf-cristallina - -``` - -22.6.23 debug segmentation fault --------------------------------- -``` -THE CHRISTALLINA CONTROL ROOM RUNS NORMALLY ON saresc-cons-05 - -[saresc-cons-05 ~]$ -ulimit -a -ulimit -c unlimited -python -X faulthandler -X tracemalloc -X dev swissmx.py 2>&1 | tee /tmp/swissmx000.log -reset;tail -c+0 -F /tmp/swissmx000.log - -python -X faulthandler -X tracemalloc -X importtime -X dev swissmx.py --sim 0xff -python -X faulthandler -X tracemalloc -X dev swissmx.py --sim 0xff - -zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX$ -rsync -vai swissmx.py saresc-cons-03:/sf/cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/swissmx_segFault.py - -read: https://docs.python.org/3/library/faulthandler.html - -coredump erzeugen -cat /proc/sys/kernel/core_pattern -sudo echo "/tmp/core" > /proc/sys/kernel/core_pattern - -ulimit -c unlimited -python -c "import ctypes; ctypes.string_at(0)" -python -X faulthandler -c "import ctypes; ctypes.string_at(0)" - -Rene did: -[root@saresc-cons-05 ~]# sysctl -w kernel.core_pattern="/tmp/%e_core_dump.%p" -cat /proc/sys/kernel/core_pattern -/tmp/%e_core_dump.%p - -ll /tmp/python_core_dump.* - - -gdb python /tmp/core -bt (for facktrace) - -trying python c code extention: -/home/zamofing_t/Documents/prj/scratch/python/sample_c_extension - - -Thread 0x00007fd2e16e8700 (most recent call first): - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata - ... - File "/gfa/.mounts/sf_cristallina/applications/mx/zamofing_t/ESB_MX/python/SwissMX/epics_widgets/MotorTweak.py", line 216 in update_label - ... - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped -``` - -Coredump 29.6.23 18h40 ----------------------- -``` -grep -c '5000/5000' * -swissmx000.log:57 -swissmx001.log:36 -swissmx002.log:35 - -swissmx002.log 35*5000 frames -35*5000/100/60 -> every 29.16min of acquisition a crash - - -rsync -vai gac-cristall@saresc-cons-05:/tmp/swissmx* ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/python/SwissMX/log - -ll /tmp/swissmx* -ll /tmp/python_core_dump.* - -Thread 0x00007fb9b13f7700 (most recent call first): - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 1122 in element_count - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 489 in get - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 620 in get_with_metadata - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 981 in nelm - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 579 in wrapper - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 1122 in element_count - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 549 in wrapper - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/ca.py", line 871 in current_context - File "/sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/pyepics-3.4.3-py3.9.egg/epics/pv.py", line 48 in wrapped - -conda activate crmx38 -ll /tmp/python_core_dump.* -gdb python /tmp/python_core_dump.21072 -Core was generated by `python -X faulthandler -X tracemalloc -X dev swissmx.py'. -Program terminated with signal 11, Segmentation fault. - -bt -0 write_thread_id.isra.3 (is_current=0, fd=) at /opt/conda/conda-bld/python-split_1648465063888/work/Python/traceback.c:849 -#1 _Py_DumpTracebackThreads () at /opt/conda/conda-bld/python-split_1648465063888/work/Python/traceback.c:914 -#2 0x000055c2b7ef6635 in faulthandler_dump_traceback.isra.2 (fd=fd@entry=2, all_threads=1) at /opt/conda/conda-bld/python-split_1648465063888/work/Modules/faulthandler.c:242 -#3 0x000055c2b7ef67a3 in faulthandler_fatal_error (signum=11) at /opt/conda/conda-bld/python-split_1648465063888/work/Modules/faulthandler.c:348 -#4 -#5 0x00007fb9c7ed4ef4 in QWidgetTextControl::document() const () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#6 0x00007fb9c7e676e1 in ?? () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#7 0x00007fb9c7e69230 in QLabel::paintEvent(QPaintEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#8 0x00007fb9d7fa16d3 in sipQLabel::paintEvent(QPaintEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/QtWidgets.abi3.so -#9 0x00007fb9c7dcc580 in QWidget::event(QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#10 0x00007fb9c7e36203 in QFrame::event(QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#11 0x00007fb9d7fa2d03 in sipQLabel::event(QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/QtWidgets.abi3.so -#12 0x00007fb9c7da20f1 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#13 0x00007fb9d8097afe in sipQApplication::notify(QObject*, QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/QtWidgets.abi3.so -#14 0x00007fb9e6cadd62 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Core.so.5 -#15 0x00007fb9c7dc6de6 in QWidgetPrivate::sendPaintEvent(QRegion const&) () from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#16 0x00007fb9c7dc774e in QWidgetPrivate::drawWidget(QPaintDevice*, QRegion const&, QPoint const&, QFlags, QPainter*, QWidgetRepaintManager*) () - from /sf/cristallina/applications/conda/envs/crmx38/lib/python3.8/site-packages/PyQt5/../../../libQt5Widgets.so.5 -#17 0x00007fb9c7dc8147 in QWidgetPrivate::paintSiblingsRecursive(QPaintDevice*, QList const&, int, QRegion const&, QPoint const&, QFlags, QPainter*, QWidgetRe + "mode:6,ssz:(6,8), + dscr: { + size:(4560,2520), + fiducial:{type:0,pos:((240,240),(4320,240),(240,2280),(4320,2280))}, + grid:{pos:(480,360),pitch:(90,60),count:(40,30)} + }" -> add a FixTarget ``` -Localize mionitors and callbacks: + +## testing hit and return: ``` - -grep -Rn 'add_callback' *.py - - -swissmx.py:698: self.sigNewCamImg.connect(self.cb_update_img) -swissmx.py:745: def cb_update_img(self): -epics_widgets/MotorTweak.py:88: m.set_callback('RBV', self.emit_signals, {'source_field': 'RBV'}) -epics_widgets/SmaractMotorTweak.py:100: self._pv_readback.add_callback(self.update_label) -swissmx.py:717: cam.run(self.cb_new_frame_pv) -swissmx.py:743: self.sigNewCamImg.emit() -swissmx.py:745: def cb_update_img(self): -swissmx.py:698: self.sigNewCamImg.connect(self.cb_update_img) -camera.py:159: self._pv['pic'] = epics.PV(self._prefix + "FPICTURE", auto_monitor=True, callback=cb) - - --> try to turn of the monitors during ascuisition: -zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX$ -grep -r set_callback * - -https://pyepics.github.io/pyepics/pv.html#automatic-monitoring-of-a-pv - - -Try with: -pv.clear_auto_monitor() -> pv.reconnect() - -pv.remove_callback(index=None) -> pv.add_callback(callback=None[, index=None [, with_ctrlvars=True[, **kw]]) -pv.set_callback - -FixTargetFrame -> paint -> _log.debug() - - -Turn off jungfrau. -no motion -> wait 1h -constant up-dow motion code -> wait 1h +-> add a FixTarget + "mode:6,ssz:(6,8), + dscr: { + size:(4560,2520), + fiducial:{type:0,pos:((240,240),(4320,240),(240,2280),(4320,2280))}, + grid:{pos:(480,360),pitch:(90,60),count:(40,30)} + }" -> add a FixTarget ``` - - -sync and triggering -------------------- -``` -EVR output powerBrick register $(USR_FLAG_ID) -FrontUnivOut4 Gate3[1].Chan[0].UserFlag 5 acquisition start -FrontUnivOut5 Gate3[1].Chan[1].UserFlag 6 frame trigger -FrontUnivOut6 Gate3[1].Chan[2].UserFlag 7 unused - --> Deltatau flags are inverted: FrontUnivOut6(Force Low) -> Gate3[1].Chan[2].UserFlag==1 - -FrontUnivOut4 <- Pulser 0 <- active low <- event 254 (not used any more) -FrontUnivOut5 <- Pulser 1 <- active low <- event 215 (cristallina frame trigger) -FrontUnivOut6 <- Force Low - -MXMotion.py -> setup_sync() - elif sync_mode in(1,2): - #frequence jitter 50Hz Swissgrid: - #https://www.swissgrid.ch/de/home/operation/grid-data/current-data.html# - flag0='Coord[{crdId}].Q[10]'.format(crdId=crdId) if sync_flag&1 else 'Gate3[1].Chan[0].UserFlag' - flag1='Coord[{crdId}].Q[11]'.format(crdId=crdId) if sync_flag&2 else 'Gate3[1].Chan[1].UserFlag' - --> looks at Q10/Q11 for start and sync (in simulation) --> looks at User-Flags from the EVR for start and sync (in real) - -s.a. ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX/Readme.md -> EVR -``` - -23.9.24 spitting/moving repositories ------------------------------------- -``` -https://jira.psi.ch/browse/SFELPHOTON-1337: SwissMX split/ cleanup/move repositories -``` - ------------------------------------ SCRATCH ----------------------------------- - --0.952 -pp_comm.py_: - @property - def fast_gather(self): - tries to connect to port and to query_types(), if fails starts the fast gather process. - -triggerSync.c: -root@:/opt/ppmac# LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/triggerSync - -usage: -/tmp/triggerSync pt2ptTime timeOfs mode - -pt2ptTime: time in ms (float value) from point to point == frequency if FEL -timeOfs: time offset in ms (float value) for motion relative to the FEL timing - -The program changes the speed of motion -pshm->Coord[1].DesTimeBase= (default serverPeriod= 0.2?) - -SIMFLAG0 (pshm->Coord[1].Q[10]) -> start trigger -SIMFLAG1 (pshm->Coord[1].Q[11]) -> FEL pulse trigger -//Power PMAC Software Reference Manual.pdf Gate3[i].Chan[j].Status -> page 919 UserFlag -#define FLAG0 (gate3_1->Chan[0].Status&0x800) -> start trigger -#define FLAG1 (gate3_1->Chan[1].Status&0x800) -> FEL pulse trigger - - -mode: - bit0:1: sync mode - bit1:2: simulate start trigger - bit2:4: simulate frame trigger - bit3:8: verbose - -simulate start trigger: -set pshm->Coord[1].Q[10]=1 to simulate a Jungfrau aquire start - -simulate frame trigger -is output to pshm->Coord[1].Q[11] - 1: synchronize real frame and start triggers - 3: synchronize real frame and simulated start triggers - 6: simulated frame and start triggers (no sync) - 7: synchronize simulated frame and start triggers - -in simulate mode: -set pshm->Coord[1].Q[10]=1 to simulate a Jungfrau aquire start -set pshm->Coord[1].Q[10]=2 to stop simulate trigger generation -Coord[1].Q[11] is the simulated frame trigger - -in synchronize mode -Coord[1].Q[0]=-2 : trigsync_func start, Wait for 'arm' trigger -Coord[1].Q[0]=-1 : got 'arm' trigger, wait frame trigger -Coord[1].Q[0]= 0 : got frame trigger 0 -Coord[1].Q[0] is incremented at each trigger -sync task ends when Gather.Enable==0 - - - - -// /tmp/triggerSync 40 11 trigger all 40 ms, simulated start, use real frame triggers, verbose -// /tmp/triggerSync 40 14 trigger all 40 ms, simulated start and frame triggers, no sync, verbose -// /tmp/triggerSync 40 15 trigger all 40 ms, simulated start and frame triggers, with sync, verbose -// /tmp/triggerSync 40 7 trigger all 40 ms, simulated start and frame triggers, with sync, minimal verbose - - -78x78 points =6084pts a 10ms =60 sec. -> 70 sec. --> we are at 100 Hz !!! - -remote ssh tunnel + start gather_server ---------------------------------------- -``` -PPMAC=SAR-CPPM-EXPMX1 -rsync -va ~/Documents/prj/SwissFEL/PBTools/pbtools/gather/gather_server root@$PPMAC:/tmp/ -lsof -i -n | grep '127.0.0.1:1000' -ssh -L 10001:localhost:22 root@$PPMAC 'uname -a' -ssh -L 10002:localhost:2332 root@$PPMAC 'uname -a' -ssh root@$PPMAC -LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/gather_server -``` -cleanup /tmp/ -------------- -``` -PPMAC=SAR-CPPM-EXPMX1 -ssh root@$PPMAC rm /tmp/gather_server /tmp/triggerSync -ssh root@$PPMAC ls -l /tmp -``` -start debug tools ------------------ -``` -PPMAC=SAR-CPPM-EXPMX1 -PBInspect --host=$PPMAC& -gpasciiCommander --host $PPMAC -i -ssh root@$PPMAC -ssh root@$PPMAC rm /tmp/gather_server /tmp/triggerSync -ssh root@$PPMAC ls -l /tmp -``` -restart IOC ------------ -``` -ssh saresc-cons-03 -PPMAC=SAR-CPPM-EXPMX1 -telnet $PPMAC 50001 -Ctrl-X -dbgf SAR-CPPM-EXPMX1:MOD_VER -caget SAR-CPPM-EXPMX1:MOD_VER -``` -checking versions ------------------ -``` -git: 7a968aac967 -asyn 427.0.2 -motorBase alpha_220518 -asynMotor alpha_220518 -powerPmac alpha_220518 -PB_COMMON 2.0.1 -gpasciiCommander 0.9.0 -ESB_MX 0.0.2 -``` -zamofing_t@ganymede:~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX$ -git loggraph -10 -* 7a968aa 2022-09-20 (HEAD -> master, tag: latest, tag: 0.0.2, psigithub/master) change speeds and directions [Thierry Zamofing] -* 00588f8 2022-09-16 minor changes [Thierry Zamofing] -* d52a6ce 2022-08-30 minor changes [Thierry Zamofing] -* f47e111 2022-05-20 (tag: 0.0.1) add DET_Z motor [Thierry Zamofing] -* 8e5b15e 2022-05-20 wip [Thierry Zamofing] -* 399282c 2019-03-20 enhance triggering [Thierry Zamofing] -* eda8caf 2019-03-19 wip [Thierry Zamofing] -* 0c45705 2019-03-08 optimize [Thierry Zamofing] -* c962ebd 2019-03-06 documentation [Thierry Zamofing] -git reset --hard 399282c -rmake -e LIBVERSION=42.42.42 uninstall install --> restart IOC -ssh root@$PPMAC rm /tmp/triggerSync -cd python -git dt latest -- shapepath.py -./shapepath.py --host=localhost:10001:10002 -removing test verion -ssh sf-lc7 ls -l /ioc/modules/ESB_MX/ -ssh sf-lc7 rm -rf /ioc/modules/ESB_MX/42.42.42 -IOC locations -------------- -``` -~/Documents/prj/SwissFEL/epics_ioc_boot_sf/ESC_all/ESB_MX_PowerBrick -They are just using the new alphy driver. That should have no impact on the motion config. -``` -test shapepath --------------- -``` -cd ~/Documents/prj/SwissFEL/epics_ioc_modules/ESB_MX -./shapepath.py --host=localhost:10001:10002 -``` - diff --git a/SwissMX.jpg b/SwissMX.jpg new file mode 100644 index 0000000..6c48ece Binary files /dev/null and b/SwissMX.jpg differ diff --git a/pyqtUsrObj.py b/pyqtUsrObj.py index 3c17aa0..d99afd4 100644 --- a/pyqtUsrObj.py +++ b/pyqtUsrObj.py @@ -251,25 +251,55 @@ class Grid(UsrROI): def get_scan_param(self): 'returns scan parameters for scanning with deltatau. the format is as used for shapepath' - scan=1 # snake motion Y fast, X slow (default) - cnt=np.array(self._cnt,np.int32) - sz=np.array(self.size()) - pitch=sz/cnt - xx, yy=np.meshgrid(range(cnt[0]), range(cnt[1])) - - - if scan==0: # snake motion X fast, Y slow - for i in range(1,cnt[1],2): - xx[i]=xx[i][::-1] - else: # scan==1 # snake motion Y fast, X slow (default) - xx=xx.T - yy=yy.T - for i in range(1, cnt[0], 2): - yy[i]=yy[i][::-1] - pts=np.array([xx.reshape(-1), yy.reshape(-1)], dtype=np.float64).transpose()*pitch - param={'points':pts} + cnt=np.array(self._cnt, np.int32) + grid={'pos':tuple(self.pos()), 'pitch':tuple(np.array(self.size())/cnt), 'count':self._cnt} + use_trf=self._param.get('use_trf', True) # do not use coordinate transformation + mode=self._param.get('mode',1) + num_pts=np.array(self._cnt, np.int32).prod() + param={'num_pts':num_pts} param.update(self._param) - assert(param.get('code_gen',0)==0) # this provides fully x,y motor coordinates + + # TODO: simplify !!! + t=self.transform() #obj_info(t) + p=np.array(self.pos()) + s=1#self.size()/self._dscr['size'] + trf=np.array(((t.m11(),t.m12()),(t.m21(),t.m22()),(0,0))) + trf[2,:]=p # shift origin + trf[:2,:]=(trf[:2,:].T*s).T # same as np.asmatrix(np.diag(s))*trf[:2,:], trf[:2,:]*=s not working, scale before rot / shear + + pos=np.array((0,0)) #np.array(grid['pos']) # in um + pitch=np.array(grid['pitch']) # in um + trf2=np.asmatrix(np.identity(3)) + trf2[:, :2]=trf + trf2*=np.asmatrix(((1000, 0, 0), (0, 1000, 0), (0, 0, 1))) + trf3=np.asmatrix(((pitch[0], 0, 0), (0, pitch[1], 0), (pos[0], pos[1], 1))) + trf=(trf3*trf2)[:, :2] + + if mode in (1,3): # needs all points, not grid + scan=1 # snake motion Y fast, X slow (default) + xx, yy=np.meshgrid(range(cnt[0]), range(cnt[1])) + if scan==0: # snake motion X fast, Y slow + for i in range(1,cnt[1],2): + xx[i]=xx[i][::-1] + else: # scan==1 # snake motion Y fast, X slow (default) + xx=xx.T + yy=yy.T + for i in range(1, cnt[0], 2): + yy[i]=yy[i][::-1] + + pts=np.array([xx.reshape(-1), yy.reshape(-1)], dtype=np.float64).transpose() #*pitch + + if not use_trf: + pts=(np.hstack((pts, np.ones((pts.shape[0], 1))))*trf).A + param['trf']=trf + param['points']=pts + else: + if use_trf: + param.update({'grid':grid, 'trf':trf}) + else: + g=grid.copy() #has not be tested ! + g['pos']=tuple((np.array((0,0,1))*trf).A.reshape(-1).tolist()) + param.update({'grid':p, 'trf':trf}) return param @@ -371,11 +401,9 @@ class Path(UsrROI): s=self.size()/self.szOrig trf=np.array(((t.m11(),t.m12()),(t.m21(),t.m22()),(0,0))) trf[2,:]=p # shift origin - #trf[:2, 0]*=s[0];trf[:2, 1]*=s[1] #scaling (before rotation shear) - trf[:2,:]=(trf[:2,:].T*s).T # same as np.asmatrix(np.diag(s))*trf[:2,:], trf[:2,:]*=s not working, scale before rot / shear - + trf[:2,:]=(trf[:2,:].T*s).T # trf*'gridpos in um' -> motor pos in mm - param={'points':self._path,'trf':trf} + param={'num_pts':len(self._path),'trf':trf,'points':self._path} param.update(self._param) return param @@ -518,21 +546,13 @@ class FixTargetFrame(UsrROI): def get_scan_param(self): 'returns scan parameters for scanning with deltatau. the format is as used for shapepath' - scan=1 # snake motion Y fast, X slow (default) grid=self._dscr['grid'] - self._dscr['size'] - cnt =np.array(grid['count'],np.int32) - xx, yy=np.meshgrid(range(cnt[0]), range(cnt[1])) - if scan==0: # snake motion X fast, Y slow - for i in range(1,cnt[1],2): - xx[i]=xx[i][::-1] - else: # scan==1 # snake motion Y fast, X slow (default) - xx=xx.T - yy=yy.T - for i in range(1, cnt[0], 2): - yy[i]=yy[i][::-1] - - pts=np.array([xx.reshape(-1), yy.reshape(-1)], dtype=np.float64).transpose() #*pitch + use_trf=self._param.get('use_trf', True) # do not use coordinate transformation + mode=self._param.get('mode',1) + cnt=np.array(grid['count'], np.int32) + num_pts=cnt.prod() + param={'num_pts':num_pts} + param.update(self._param) # TODO: simplify !!! t=self.transform() #obj_info(t) @@ -549,9 +569,32 @@ class FixTargetFrame(UsrROI): trf2*=np.asmatrix(((1000, 0, 0), (0, 1000, 0), (0, 0, 1))) trf3=np.asmatrix(((pitch[0], 0, 0), (0, pitch[1], 0), (pos[0], pos[1], 1))) trf=(trf3*trf2)[:, :2] - param={'grid':grid, 'points':pts, 'trf':trf} - param.update(self._param) + if mode in (1,3): # needs all points, not grid + scan=1 # snake motion Y fast, X slow (default) + xx, yy=np.meshgrid(range(cnt[0]), range(cnt[1])) + if scan==0: # snake motion X fast, Y slow + for i in range(1,cnt[1],2): + xx[i]=xx[i][::-1] + else: # scan==1 # snake motion Y fast, X slow (default) + xx=xx.T + yy=yy.T + for i in range(1, cnt[0], 2): + yy[i]=yy[i][::-1] + + pts=np.array([xx.reshape(-1), yy.reshape(-1)], dtype=np.float64).transpose() #*pitch + + if not use_trf: + pts=(np.hstack((pts, np.ones((pts.shape[0], 1))))*trf).A + param['trf']=trf + param['points']=pts + else: + if use_trf: + param.update({'grid':grid, 'trf':trf}) + else: + g=grid.copy() #has not be tested ! + g['pos']=tuple((np.array((0,0,1))*trf).A.reshape(-1).tolist()) + param.update({'grid':p, 'trf':trf}) return param diff --git a/swissmx.py b/swissmx.py index 7eabb46..370d362 100755 --- a/swissmx.py +++ b/swissmx.py @@ -100,7 +100,7 @@ class timestamp(): ts=timestamp() ts.log('Import part 1/8:') import sys, os -import json, re +import yaml import signal, subprocess import matplotlib as mpl import matplotlib.pyplot as plt @@ -1516,7 +1516,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow): #self._inspect = self._grid_inspect_area #self._inspect.setPlainText("") - fast_x=self.tweakers["fast_x"]; + fast_x=self.tweakers["fast_x"] fast_y=self.tweakers["fast_y"] fx=fast_x.get_val() fy=fast_y.get_val() @@ -1527,7 +1527,7 @@ class WndSwissMx(QMainWindow, Ui_MainWindow): if type(go)==UsrGO.Fiducial: continue t=type(go) - if t not in(UsrGO.FixTargetFrame,UsrGO.Path): + if t not in(UsrGO.FixTargetFrame,UsrGO.Path,UsrGO.Grid): _log.warning(f'{t} not supported for FixTargetFrame ->skipped:{go}') continue try: @@ -1535,11 +1535,6 @@ class WndSwissMx(QMainWindow, Ui_MainWindow): except AttributeError as e: _log.warning(f'no scan parameters for object->skipped:{go}') continue - trf=np.asmatrix(param['trf']) - p=param['points'] - p=(np.hstack((p,np.ones((p.shape[0],1))))*trf).A - param['pts_trf']=p # transformed points in um motor coordinates - param['num_pts']=p.shape[0] vb=self.vb grp=self._goTracked mft=self._moduleFixTarget @@ -1986,6 +1981,53 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch) self._tabs_daq_methods.setCurrentWidget(mft) #set this as the active tabs mft._cbType.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget(test)", "Grid()", "SwissMX()", "SwissFEL()"]) + #print(psi_device.shapepath.ShapePath.setup_motion.__doc__) + mft._txtParam.setToolTip('''\ +additional parameter as yaml for object settings and motion generation: +full example for grid() object and motion settings: + size:[3.6,2.664],cnt:[30,22],fiducialSize:0.05,mode:6,scale:.5,ssz:[7,4],smv:[6,4],sdelay:9 +further examples: + object settings: + for Grid(): size:[4,3],cnt:[30,22],fiducialSize:0.1 + motion param: + for continous: cnt:2,scale:.3,dwell:100 + for stop-and-go: tmove:10,twait:20 + for hit-and-return: ssz:(4,6) + +motion generation: + For details read: psi_device.shapepath.ShapePath.setup_motion.__doc__ + mode: select one of following modes: 1,3,4,5,6 + mode settings: + all: cnt:1 + scale:1. + dwell:10 + 5: tmove:10 + twait:20 + 6: ssz:(7,4) + smv:(6,4) (delault defined) + sdelay:9 (delault defined) + +object settings: + Fiducial: + no param + FixTarget(12.5x12.5), FixTarget(23.0x23.0), FixTarget(test): + no param + Grid(): + size:[30,20] + cnt:[30,22] + fiducialSize:0.1 + SwissMX(): + ofs:[.2,.2] + width:10 + fidScl:.02 + fiducial:[[.1,.1],[.1,2.7],[10.3,.1],[10.3, 2.7]] + SwissFEL(): + ofs:[.2,.2] + width:10 + fidScl:.02 + fiducial:[[.1,.1],[.1,2.2],[10.3,.1],[10.3,2.2]] +''') + mft._btnAdd.clicked.connect(self.module_fix_target_add_obj) mft._btnDelAll.clicked.connect(self.module_fix_target_del_all_obj) mft._btnFit.clicked.connect(self.module_fix_target_fit_fiducial) @@ -2097,67 +2139,23 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch) bm_pos=self._goBeamMarker.pos() bm_sz=self._goBeamMarker.size() idx=mft._cbType.currentIndex() - param=mft._txtParam.text() - - #mft._cbType.addItems(["Fiducial", "FixTarget(12.5x12.5)", "FixTarget(23.0x23.0)", "FixTarget()", "Grid()", "SwissMX-path"]) - #bm_pos_eu=self._goBeamMarker._pos_eu - #bm_size_eu=self._goBeamMarker._size_eu - try: - #parse the parameters: 'key:value [,key:value]' - # as key value separator : and = are allowed - #examples: - #Fiducial: - # no param - #FixTarget(12.5x12.5), FixTarget(23.0x23.0), FixTarget(test): - # code_gen:2 - # code_gen=3 | tmove=10 | twait=30 - #Grid(): - # size:(30, 20) - # cnt:(30, 22) - # fiducialSize:0.1 - #SwissMX(): - # ofs:(.2, .2) - # width:10 - # fidScl:.02 - # fiducial:((.1, .1), (.1, 2.7), (10.3, .1), (10.3, 2.7)) - #SwissFEL(): - # ofs:(.2, .2) - # width:10 - # fidScl:.02 - # fiducial:((.1, .1), (.1, 2.2), (10.3, .1), (10.3, 2.2)) - - pLst=param.split('|') - pStr=list() - for p in pLst: - if not p: continue - m=re.match('\s*(.*?)\s*[=:]\s*(.*)\s*', p) - k, v=m.groups() - v=v.replace('(', '[').replace(')', ']') - pStr.append(f'"{k}":{v}') - pStr='{'+','.join(pStr)+'}' - param=json.loads(pStr) # "ofs":[10, 5],"width":200,"fidScl":0.5,"fiducial":[[18,7],[25,16],[70, 20]] - except json.decoder.JSONDecodeError as e: - _log.error(f'{e}:{param}') - param=dict() + param=mft.get_param() if idx==0: #go=UsrGO.Fiducial(bm_pos+bm_sz/2-(20, 20), (40, 40),(fx,fy,bz)) l=.120 go=UsrGO.Fiducial((fx-l/2,fy-l/2), (l, l),bz) go.sigRegionChangeFinished.connect(self.cb_fiducial_update_z) elif idx==1: - v=geo.pos2pix((12.5, 0)) - l=np.linalg.norm(v) - l=12.5 - #ctr=bm_pos+bm_sz/2 + #v=geo.pos2pix((12.5, 0));l=np.linalg.norm(v);l=12.5 + sz=param.pop('size',(12.5, 12.5)) go=UsrGO.FixTargetFrame((fx-l/2,fy-l/2), (l, l), tpl='12.5x12.5',**param) elif idx==2: - v=geo.pos2pix((23, 0)) - l=np.linalg.norm(v) - l=23 + #v=geo.pos2pix((23, 0));l=np.linalg.norm(v)#l=23 + sz=param.pop('size',(23, 23)) go=UsrGO.FixTargetFrame((fx-l/2,fy-l/2), (l, l), tpl='23.0x23.0',**param) elif idx==3: - w,h=(.120*12, .120*8) - go=UsrGO.FixTargetFrame((fx-w/2,fy-h/2), (w, h), tpl='test',**param) + sz=param.pop('size',(.120*12, .120*8)) + go=UsrGO.FixTargetFrame((fx-sz[0]/2,fy-sz[1]/2), sz, tpl='test',**param) elif idx==4: w,h=size=param.pop('size',(30, 20)) cnt=param.pop('cnt',(30, 22)) @@ -2271,18 +2269,10 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch) def daq_collect(self, **kwargs):# points, visualizer_method, visualizer_params): ''' kwargs: - code_gen: 0 pvt motion using ptsTrf - 1 pvt motion using trf and points - 2 pvt motion, compact grid code - 3 pvt motion, compact grid code move and wait - tmove: time to move - twait: time to wait - - grid: grid dictionary with orig, pitch, count trf: transformation matrix points: list of points without transformation - pts_trf: list of points with transformation + pts_trf: list of points with transformation ''' app = QApplication.instance() cfg = app._cfg @@ -2322,28 +2312,24 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch) #dlg.setAutoClose(True) #dlg.show() dlg.setLabelText("Setup Gather/Sync");dlg+=5 - code_gen=kwargs.get('code_gen',0) + mode=kwargs.pop('mode',1) sp.setup_sync(verbose=sp.verbose&0x40, timeOfs=dt_misc['time_ofs'], timeCor=dt_misc['time_cor']) dlg.setLabelText("Download motion program");dlg+=5 - if code_gen==0: - sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10, points=kwargs['pts_trf']) - elif code_gen==1: - sp.setup_motion(fnPrg=fn+'.prg', mode=3, scale=1., dwell=10, points=kwargs['points'],trf=kwargs['trf']) - elif code_gen==2: - sp.setup_motion(fnPrg=fn+'.prg', mode=4, scale=1., dwell=10, grid=kwargs['grid'], trf=kwargs['trf']) - elif code_gen==3: - sp.setup_motion(fnPrg=fn+'.prg', mode=5, dwell=10, tmove=kwargs['tmove'] ,twait=kwargs['twait'], grid=kwargs['grid'],trf=kwargs['trf']) + + use_trf=kwargs.get('use_trf', True) # do not use coordinate transformation + if not use_trf: + trf=kwargs.pop('trf') + try: + sp.setup_motion(fnPrg=fn+'.prg', mode=mode, **kwargs) + except BaseException as e: + _log.error(repr(e));return sp.setup_gather() + if not use_trf: + kwargs['trf']=trf try: p=geo._fitPlane - # TODO: Cleanup - if code_gen==0: - # X has inverted sign ! - # Z is in um -> therefore the offset must be multiplied with 1000 ! Z motor has opposite sign ! - #cz=f'{+p[0]:+.18g}X{-p[1]:+.18g}Y{-p[2]*1000:+.18g}' - t=p*np.array((1,1,1000)) - cz=f'{t[0]:+.18g}X{t[1]:+.18g}Y{t[2]:+.18g}' - else: + #TODO: cleanup + if use_trf: trf=kwargs['trf'] # grid-coord -> motor-um #(0,0,1)*trf # trf*'gridpos in um' -> motor pos in mm @@ -2354,25 +2340,31 @@ Author Thierry Zamofing (thierry.zamofing@psi.ch) #(0, 0, 1)*trf2*trf3 -> z in um of gridpos(0,0) t=(trf2*trf3)[:,0].A.ravel() cz=f'{t[0]:+.18g}X{t[1]:+.18g}Y{t[2]:+.18g}' + else: + # X has inverted sign ! + # Z is in um -> therefore the offset must be multiplied with 1000 ! Z motor has opposite sign ! + #cz=f'{+p[0]:+.18g}X{-p[1]:+.18g}Y{-p[2]*1000:+.18g}' + t=p*np.array((1,1,1000)) + cz=f'{t[0]:+.18g}X{t[1]:+.18g}Y{t[2]:+.18g}' except AttributeError: cz='0' _log.warning('no plane fitting done. z does not move') trf=kwargs['trf'] - if code_gen==0: - fx='X';fy='Y' + if use_trf: + fx=f'{trf[0, 0]:+.18g}X{trf[1, 0]:+.18g}Y{trf[2, 0]:+.18g}' + fy=f'{trf[0, 1]:+.18g}X{trf[1, 1]:+.18g}Y{trf[2, 1]:+.18g}' else: - fx=f'{trf[0,0]:+.18g}X{trf[1,0]:+.18g}Y{trf[2,0]:+.18g}' - fy=f'{trf[0,1]:+.18g}X{trf[1,1]:+.18g}Y{trf[2,1]:+.18g}' + fx='X';fy='Y' if _log.level==logging.DEBUG: try: t except NameError: t=(np.nan,np.nan,np.nan) fn='/tmp/coord.log' _log.debug(f'write all coordinates to {fn}') - if code_gen==0: - xy1=np.hstack((kwargs["pts_trf"],np.ones((kwargs["pts_trf"].shape[0],1)))) - else: + if use_trf: xy1=np.hstack((kwargs["points"],np.ones((kwargs["points"].shape[0],1)))) + else: + xy1=np.hstack((kwargs["pts_trf"],np.ones((kwargs["pts_trf"].shape[0],1)))) pcz=np.matrix(((t[0],t[1],t[2])))*xy1.T x_y_fx_fy_cz=np.vstack((kwargs["points"].T, kwargs["pts_trf"].T, pcz)).A with open('/tmp/coord.log','w') as fh: