PBSwissMX ========= This repository is used by the SwissMX application.
A complete list of SwissMX repositories dependencies is shown in [grp-sf_cristallina/SwissMX.git](https://git.psi.ch/grp-sf_cristallina/SwissMX). PBSwissMX contains python application and executables to: - generate trajectories and motion programs for SwissMX (`shapepath.py` and `helicalscan.py`[obsolete]) - motion synchronization executables (`triggerSync`) for Deltatau - analyse recorded trajectories on SwissMX (`ShapePathAnalyser`) - motor tuning tools (`MXTuning`) - documentation about the tuning results (`MXfastStageDoc`) motion start/framesynchronization (update31.10.24) --------------------------------------------------- **For more details about triggerSync read: [src/triggerSync/Readme.md](src/triggerSync/Readme.md)** #### Important used vaiables: ``` Coord[1].Q[0] : sync points indicator: (at whick point is the motion program) val: desc set in code -3: waiting at start position motion code generated in MXMotion.py:setup_sync(mode=?) -2: got start trigger triggerSync.c:trigsync_func(mode&1) else motion code generated in MXMotion.py:setup_sync(mode=?) 0: after MXMotion.py:setup_sync call triggerSync.c:trigsync_func(mode&1) idx: index of position during run triggerSync.c:trigsync_func(mode&1) -1: motion is finished MXMotion.py:setup_sync(mode=?) Gather.Enable : mode of gathering data 1: prepared (calculate Gather.MaxLines) MotionBase.py:setup_gather() 2: finite motion code: during data gathering 0: disabled motion code: when gather finished Gather.Samples : number af gathered data samples MXMotion.py:setup_sync(): sync_mode : default=2 0 : no sync at all 1 : synchronize start 2 : synchronize start and adapt motion speed sync_flag : default=0 bit 0=1 : simulated start trigger bit 1=2 : simulated frame trigger triggerSync.c mode: bit0:1: sync mode bit1:2: simulate start trigger bit2:4: simulate frame trigger bit3:8: verbose ``` ### start/frame event system ``` Start event: sim: Coord[1].Q[10] EVR: Gate3[1].Chan[0].UserFlag == (gate3_1->Chan[0].Status&0x800) == FrontUnivOut4, EPICS MACRO: $(USR_FLAG_ID)=5 -> Pulser0 -> (active Low, 5000us delay 0us) Map: 214 -> event 214 is 'ESC multipurpose event. In this case used as: start motion' Frame event: sim: Coord[1].Q[11] EVR: Gate3[1].Chan[1].UserFlag == (gate3_1->Chan[1].Status&0x800) == FrontUnivOut5, EPICS MACRO: $(USR_FLAG_ID)=5 -> Pulser1 -> (active Low, 5000us delay 750us) Map: 40 -> event 40 = 'ESA_detector 100 Hz' >>> should be 77='ESC detector' unused EVR input?: EVR: Gate3[1].Chan[2].UserFlag == (gate3_1->Chan[2].Status&0x800) == FrontUnivOut6, EPICS MACRO: $(USR_FLAG_ID)=7 !!! Deltatau flags are inverted: FrontUnivOut6(Force Low) -> Gate3[1].Chan[2].UserFlag==1 ``` |event |simulated |real | |- |- |- | |start |Coord[.].Q[10] | Gate3[1].Chan[0].UserFlag | |frame |Coord[.].Q[11] | Gate3[1].Chan[1].UserFlag | **frequence jitter 50Hz Swissgrid:** https://www.swissgrid.ch/de/home/operation/grid-data/current-data.html ### partial python class diagram of PBSwissMX ```mermaid classDiagram MotionBase <|-- ShapePath MotionBase <|-- HelicalScan class MotionBase { @MXMotion.py + setup_sync(self, crdId, prgId, verbose, timeOfs, timeCor) + homing(self) + run(self, crdId) + wait_armed(self, crdId) + progress(self) + trigger(self, wait) } class ShapePath { @shapepath.py %%- __init__(self, args) None + setup_gather(self,acq_per=None,numPts=None) + setup_coord_trf(self,fx='X',fy='Y',cz='0') + setup_motion(self,prgId=2,fnPrg=None,mode=0,**kwargs) + gather_upload(self,fnRec=None) } class HelicalScan { @helicalscan.py [obsolete] + setup_gather(self,acq_per=1) + setup_coord_trf(self,fnCrdTrf='/tmp/coordTrf.cfg') + setup_motion(self,prgId=2,fnPrg=None,mode=0,**kwargs) + gather_upload(self,fnRec=None) } class GenPath { @shapepath.py + swissmx(self, flipx, flipy, ofs, width) + swissfel(self, flipx, flipy, ofs, width) %%+ rand(self, n, scale, ofs) + grid(self, w, h, pitch, rnd, ofs) %%+ spiral(self, rStart, rInc, numSeg, numCir, phase, ofs) %%+ closed_shifted(self, pitch, shift, mult) %%+ sort(self, mode, grp_sz) } ``` ### Simplified Python sequence Source for the instance "start/frame event system" can be: - python code - timing system (EVR) - motion code - triggerSync executable running on Deltatau ```mermaid sequenceDiagram participant es as start/frame
event system participant py as Python participant pb as PowerBrick Note over py: .setup_sync()
prepare code snipplets activate py opt needs triggerSync Note over es,pb: triggerSync is needed in case of:
simulated start/frame triggers
and/or adjust DesTimeBase py -) pb: sftp / ssh Note over pb: sftp triggerSync
run triggerSync pb ->> es: run triggerSync end Note over py: .setup_coord_trf() py -) pb: download code Note over pb: setup coordinate transformation Note over py: .setup_motion() py -) pb: generate code
download code Note over pb: setup motion program Note over py: .setup_gather() py -) pb: download code
set gather vars Note over pb: set addresses to gather
Gather.Enable=1 Note over py: .homing() py -)+ pb: download code
run homing PLC Note over py: wait(Motor[1].HomeComplete) deactivate py Note over pb: runs homing PLC [if needed]
enable plc 1 pb ->>- py: Motor[1].HomeComplete activate py Note over py: .run() py -)+ pb: run motion program Note over pb: runs motion program 2 in coordSystem 1
&1br2 Note over pb: move to first point
DesTimeBase=0 (wait motion)
Q[0]=-3 (motion program waiting at start position) pb ->>- es: Q[0]=-3 Note over es: Q[0]=-2 (event system armed)
[in motion code or
triggerSync exe] Note over py: .wait_armed()
wait(Q[0]==-2) # wait until motors are at first position deactivate py es ->>+ py: Q[0]=-2 Note over es: wait for start trigger Note over py: .trigger() alt sim start trig Note over py: Q[10]=1 [send a simulated start trigger
after given time] py ->> es: Q[10]=1 else real start trig es->> es: Gate3[1].Chan[0].UserFlag==1 end Note over es: DesTimeBase=Sys.ServoPeriod
[in motion code or
triggerSync exe] es->>+pb: continue motion opt adjust time base Note over es: in thread trigger_sync_func()
of triggerSync exe es->>es: adjust DesTimeBase end Note over pb: pvt10abs
move to all points loop 10 ms Note over pb: move to next point end opt triggerSync running pb ->> es: Gather.Enable=0 Note over es: exit triggerSync exe end Note over py: while .progress()
wait(Gather.Enable==0) deactivate py Note over pb: end motion program pb ->>- py: Gather.Enable=0 activate py Note over py: .gather_upload() deactivate py ``` 12.2.25: debugging motion code ----------------------------------------------------------- ``` &1b2r go to <&>coordsystem <1> eginning of program <2> and un s step one line q quit program a abort motion program bpset set breakpoints list plc2,10,3 list 3 lines strating from line 10 list pc show program counter &1b2r open prog 3 linearabs X2Y1 dwell10 X0Y3 dwell10 X3Y3 dwell10 X3Y0 dwell10 X0Y0 close &1b3 cpx linearabs X1Y1 //return coordinate transcormation of all axes (in coordinate system 1) &1 #1..8-> &1p // returns coordinate positions in 'wells' (in coordinate system 1) X1.000208333333334 Y1.000104166666666 #1..2p //show were the program is: list pc list pc, // with line numbers Coord[1].ProgRunning Coord[1].ProgActive Coord[1].ProgProceeding Coord[1].Program.Lsize Coord[1].Program.Number Coord[1].Program.Size Coord[1].Program.Store ``` ------------------------------- Work log ======== ??10.24: testing shapepath.py in different modes (tunneling) ----------------------------------------------------------- ``` zamofing_t@ganymede:~$ >>> kill previous tunnels 127.0.0.1:100?? ps -f `lsof -i -n | grep '127.0.0.1:100.. (LISTEN)' | awk '{print $2}'` kill `lsof -i -n | grep '127.0.0.1:100.. (LISTEN)' | awk '{print $2}'` #lsof -i -n | grep '127.0.0.1:100.. (LISTEN)' | tee /tmp/0.log | awk '{print $2}' | tee /tmp/1.log && grep -n '' /tmp/*.log >>> open cameras in chrome ssh -L 10010:cristallina-cam-top:80 saresc-vcons-01 'uname -a' google-chrome --app-url 127.0.0.1:10010 google-chrome --app-url http://cristallina-cam-north.psi.ch/camera/index.html#/video >>> prepare debug environment cmdt.py -p EXPMX -tpb # select SAR-CPPM-EXPMX1 >>> prepare shapepath and ssh tunneling cd ~/Documents/prj/SwissFEL/apps/PBSwissMX/python/ subl shapepath.py ./shapepath.py -h PPMAC=SAR-CPPM-EXPMX1 ssh -L 10001:localhost:22 root@$PPMAC 'uname -a' ssh -L 10002:localhost:2332 root@$PPMAC 'uname -a' gather_server triggerSync are copied with sftp. This does not work with tunneling: gather_server: ~/Documents/prj/SwissFEL/PBTools/build/lib/pbtools/misc/pp_comm.py:889 triggerSync: ~/Documents/prj/SwissFEL/apps/PBSwissMX/python/MXMotion.py:122 rsync -vai ~/Documents/prj/SwissFEL/PBTools/pbtools/gather/gather_server root@$PPMAC:/tmp/ rsync -vai ~/Documents/prj/SwissFEL/apps/PBSwissMX/src/triggerSync/triggerSync root@$PPMAC:/tmp/ gather_server needs to be started explicitly in tunneling: ssh root@$PPMAC LD_LIBRARY_PATH=/opt/ppmac/libppmac/ /tmp/gather_server triggerSync is started if required at each acquisition and exits when done. mode: 0 unused 1 pvt motion 2 unused 3 pvt motion using inverse fft velocity 4 pvt motion short code using grid parameters 5 pvt motion short code using grid parameters. Instead of continous motion it moves and waits as give in the parameter time sync: 0 real start and frame trigger with sync 1 direct start 2 simulated start and frame trigger no sync 3 simulated start and frame trigger with sync 4 simulated start real frame trigger no sync 5 simulated start real frame trigger with sync # set start EVT to value 0 (=Force Hi) caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 9 ./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s0 # works # set start EVT to value 1 (=Force Lo) caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Scale-SP 8 # reset EVT default value (Pulser 0) caput SAR-EXPMX-EVR0:FrontUnivOut4-Src-Pulse-SP 0 ./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s1 # works ./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s2 # works ./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s3 # works ./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s4 # works ./shapepath.py --host=localhost:10001:10002 -v 0x59 -m4 -s5 # works Debugging were the coordinate program counter is: &1 list pc,10 ``` ??.10.24: mermaid tricks and links --------------------------------- - https://mermaid.live/ - https://app.zenuml.com/ - https://www.mermaidchart.com/ - https://help.whimsical.com/article/732-sequence-diagrams - https://www.visual-paradigm.com/guide/uml-unified-modeling-language/what-is-sequence-diagram/ - https://www.geeksforgeeks.org/unified-modeling-language-uml-sequence-diagrams/ ``` pip install pymermaider --user pymermaider ~/Documents/prj/SwissFEL/apps/PBSwissMX/python -o /tmp subl /tmp/python.md ```