restructure repo

This commit is contained in:
2024-08-28 13:39:27 +02:00
parent bbbe0694f6
commit 898ce0d131
10 changed files with 296 additions and 12 deletions

BIN
ARESvis.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

195
ARESvis/ARESvis.py Executable file
View File

@@ -0,0 +1,195 @@
#!/usr/bin/env python
# *-----------------------------------------------------------------------*
# | |
# | Copyright (c) 2024 by Paul Scherrer Institute (http://www.psi.ch) |
# | |
# | Author Thierry Zamofing (thierry.zamofing@psi.ch) |
# *-----------------------------------------------------------------------*
"""
SwissFEL Furka ARES visualization
bitmask for simulation:
0x01: EPICS motors
0x02:
0x04:
0x08:
0x10:
0x20:
0x40:
0x80:
"""
import sys, logging
import epics
_log=logging.getLogger(__name__)
from PyQt5.QtWidgets import QApplication, QWidget, QGroupBox, QVBoxLayout, QSlider
from PyQt5.QtGui import QPainter, QColor, QPen
#import PyQt5.QtGui as QtGui
import PyQt5.QtCore as QtCore
import numpy as np
class WndVisualizeARES(QWidget):
_lutColor={0:(255,0,0),1:(0,255,0),2:(255,255,0)}
def __init__(self):
super().__init__()
self._param={'ctr':(200, 320), # location of big chamber
'rCmb':150, # radius of chamber
'rTrg':10, # radius of target
'r2Th':100, # radius 2Theta platfform
'szSeal': (20,50),
'szArm': (80,250),
'aaSeal':70, # RIXS sliding angle
'aaArm':70, # RIXS arm angle
'airPads':0, # air pads (off=0 on=1 undef=2)
'defComp':0, # deformation compensation (off=0 on=1 undef=2)
}
# 2thetha angle SATES30-ARES:MOT_2TRY
# detector angle SATES30-ARES:MOT_DRY
# sliding seal SATES30-RIXS:MOT_RY
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 850, 800)
self.setWindowTitle('ARES visualize')
#label = QLabel('Python', self)
#label.move(50,50)
#b1 = QPushButton("Button1",self)
#b1.move(400,150)
self._wdGrpDraw=w=QGroupBox("ARES chamber",self)
w.move(10,10)
l=QVBoxLayout(w)
sld={}
for key,rng,tk in (('aaSeal',(0,180),5),('aaArm',(0,180),5),('airPads',(0,2),1),('defComp',(0,2),1),):
sl=QSlider(QtCore.Qt.Horizontal,objectName=key)
sl.setFixedWidth(200);sl.setMinimum(rng[0]);sl.setMaximum(rng[1])
sl.setValue(self._param[key])
sl.setTickPosition(QSlider.TicksBelow);sl.setTickInterval(tk)
l.addWidget(sl)
sl.valueChanged.connect(lambda val,key=key: self.sldChanged(key,val))
sld[key]=sl
self.show()
def sldChanged(self,key,val,*args,**kwargs):
p=self._param
#print(key,val)
if key=='aaArm':
p['aaSeal']=v=p['aaSeal']-p['aaArm']+val
wSl=self._wdGrpDraw.findChild(QSlider, 'aaSeal')
wSl.blockSignals(True)
wSl.setValue(int(v))
wSl.blockSignals(False)
sl=QSlider(QtCore.Qt.Horizontal,objectName=key)
p[key]=val
self.update()
def paintEvent(self, e):
p=self._param
ctr=p['ctr']
aaSeal=p['aaSeal']
aaArm=p['aaArm']
rCmb=p['rCmb']
r2Th=p['r2Th']
rTrg=p['rTrg']
xa,ya=p['szArm']
xs,ys=p['szSeal']
ap=p['airPads']
dc=p['defComp']
qp = QPainter()
qp.begin(self)
qp.translate(ctr[0],ctr[1])
tf0=qp.transform()
qp.setPen(QPen(QtCore.Qt.black, 2, QtCore.Qt.SolidLine))
qp.setBrush(QColor(155, 155, 155, 128))
br1=qp.brush()
qp.drawEllipse(-rCmb, -rCmb, 2*rCmb, 2*rCmb) # big chamber
qp.drawEllipse(-r2Th, -r2Th, 2*r2Th, 2*r2Th) # big chamber
qp.drawEllipse(-rTrg, -rTrg, 2*rTrg, 2*rTrg) # target
qp.drawLine(0,-rCmb-50,0,-rTrg) #beam
qp.rotate(-aaSeal)
qp.translate(0,rCmb)
tf1=qp.transform()
xs2=xs//2
xa2=xa//2
ya2=ya//2
d=int(abs(aaSeal-aaArm)*20)
r=min(155+d,255)
gb=max(155-d,0)
qp.setBrush(QColor(r, gb, gb, 255))
qp.drawRect(-xs2, 0, xs, ys) # seal bellow
qp.setBrush(br1)
qp.setTransform(tf0)
qp.rotate(-aaArm)
qp.translate(0,rCmb+ys)
tf2=qp.transform()
qp.drawRect(-xa2, 0, xa, ya) # girder
#qp.drawEllipse(-ya2, 100+150, 20, 20) #pusher left
#qp.drawEllipse( ya2-r, 100+150, 20, 20) #pusher right
#air pad
r,g,b=WndVisualizeARES._lutColor[ap]
rd=13
r3=int(rd*np.sqrt(3))
qp.setBrush(QColor(r, g, b, 255))
qp.drawEllipse(-xa2-rd, ya-4*rd, 2*rd, 2*rd) #left
qp.drawEllipse(-xa2-rd+r3,ya-3*rd, 2*rd, 2*rd) #left
qp.drawEllipse(-xa2-rd+r3,ya-5*rd, 2*rd, 2*rd) #left
qp.drawEllipse( xa2-rd, ya-4*rd, 2*rd, 2*rd) #right
qp.drawEllipse( xa2-rd-r3,ya-3*rd, 2*rd, 2*rd) #right
qp.drawEllipse( xa2-rd-r3,ya-5*rd, 2*rd, 2*rd) #right
qp.drawEllipse( -rd, 3*rd, 2*rd, 2*rd) #grating
qp.drawEllipse( 0, 3*rd-r3, 2*rd, 2*rd) #grating
qp.drawEllipse( -2*rd, 3*rd-r3, 2*rd, 2*rd) #grating
qp.setBrush(br1)
#deformation compensation
r,g,b=WndVisualizeARES._lutColor[dc]
rd=14
qp.setBrush(QColor(r, g, b, 255))
qp.drawEllipse(-xa2, ya2, 2*rd, 2*rd) #air pad left
qp.drawEllipse( xa2-2*rd, ya2, 2*rd, 2*rd) #air pad right
#qp.drawEllipse( -rd, rd, 2*rd, 2*rd) #air pad grating
qp.setBrush(br1)
qp.end()
if __name__ == '__main__':
import argparse
logging.basicConfig(level=logging.DEBUG, format='%(levelname)s:%(module)s:%(lineno)d:%(funcName)s:%(message)s ')
def main():
epilog=__doc__ # +'\nExamples:'+''.join(map(lambda s:cmd+s, exampleCmd))+'\n'
parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--mode', '-m', type=lambda x:int(x, 0), help='mode (see bitmasks) default=0x%(default)x', default=1)
parser.add_argument("--sim", "-s", type=lambda x: int(x,0), help="simulate devices (see bitmasks) default=0x%(default)x", default=0x01)
args=parser.parse_args()
_log.info('Arguments:{}'.format(args.__dict__))
app=QApplication(sys.argv)
app._args=args
#devUS=RIXSdevice('RIXS us', ofs=(750, 200), g=-100, s=-1500, sy=-20, cy=70)
#devDS=RIXSdevice('RIXS ds', ofs=(930, 630))
if args.mode&0x01:
app._wndVis=WndVisualizeARES()
#if args.mode&0x02:
sys.exit(app.exec_())
main()

62
Makefile Normal file
View File

@@ -0,0 +1,62 @@
.PHONY: dbg install
.DEFAULT_GOAL := install
REMOTE=$(USER)@satesf-vcons-01
APP=/sf/furka/applications
BIN=/sf/furka/bin
SRC=$(shell pwd)
dbg:
@echo REMOTE $(REMOTE)
@echo APP $(APP)
@echo BIN $(BIN)
@echo SRC $(SRC)
install:
@echo "- /EsfRixsApps/.git/\n- /EsfRixsApps/scratch/\n- /**/__pycache__/\n- /**.ipynb*" >/tmp/rsync.filt
@cat /tmp/rsync.filt
rsync -vai --filter='. /tmp/rsync.filt' $(SRC) $(REMOTE):$(APP)
-ssh $(REMOTE) 'for A in ARESvis RIXSconfig spectrumProc; do ln -sF $(APP)/EsfRixsApps/$$A/$$A.py $(BIN)/$$A;done'
# @echo MODULE $(MODULE)
# @echo VERSION $(VERSION)
# @echo VERGITCMD "$(VERGITCMD)"
#Examples of usage:
#------------------
#
#DST_IOC=/ioc/modules/$(MODULE)/$(VERSION)/R7.0.7
#DST_ANA=/sf/controls/bin/zamofing_t/lib/python3.7/site-packages/gpasciiCommander
#make install
#make install MINORVER=1
# @echo "+ /Media/\n+ /Media/Videos/\n+ /Media/Videos/*\n- /*\n- /Media/*" >/tmp/rsync.filt
#Versions:
#The generated version is:
# - if not tagged: test
# - if tagged with v*.*: <tag>.0
# - if MINORVER=1 and checked in: v*.*.<# of commits after tag>
#ifdef MINORVER #minot version allowed
#VERGITCMD = git describe --tags --long --match 'v*.*' --dirty 2>/dev/null | sed -e 's/^[^0-9]*//' -e 's/.*-dirty$$/test/' -e 's/-g[0-9a-f]*$$//' -e 's/-/./'
#else
#VERGITCMD = git describe --tags --dirty --match 'v*.*' 2>/dev/null | sed -e 's/^[^0-9]*//' -e 's/.*-dirty$$/$(USER)/' -e 's/.*-g[0-9a-f]*$$/$(USER)/' | sed -r 's/([0-9])$$/\1.0/'
#endif
#MODULE=$(subst PB_,,$(notdir $(shell pwd)))
#VERSION=$(shell ${VERGITCMD})
# ssh $(REMOTE) 'ln -s $(APP)/EsfRixsApps/RIXSconfig/RIXSconfig.py $(BIN)/RIXSconfig'
# ssh $(REMOTE) 'ln -s $(APP)/EsfRixsApps/ARESvis/ARESvis.py $(BIN)/ARESvis'
# ssh $(REMOTE) 'ln -s $(APP)/EsfRixsApps/RIXSconfig/RIXSconfig.py $(BIN)/RIXSconfig'
# ssh $(REMOTE) mkdir -p $(DST_IOC)
# rsync -vain --exclude 'Makefile' `git ls-files` $(REMOTE):$(DST_IOC)
# rm -f `find . -name '*.pyc'`
# ssh $(REMOTE) mkdir -p $(DST_IOC)
# ssh $(REMOTE) chmod -R g+w $(DST_IOC)
# ssh $(REMOTE) ln -sf gpasciiCommander.py $(DST_IOC)/gpasciiCommander
# ssh $(REMOTE) python -m compileall $(DST_IOC)/templates
# ssh $(REMOTE) ln -sfT R3.14.12 /ioc/modules/$(MODULE)/$(VERSION)/R7.0.1
# ssh $(REMOTE) ln -sfT $(VERSION)/R7.0.7 /ioc/modules/$(MODULE)/latest

BIN
RIXSconfig.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 KiB

View File

@@ -6,7 +6,7 @@ class Config:
# 'R':<radius of the grating mirror>
# 'a0':<lines/mm>,'a1':<lines/mm^2>,'a2':<lines/mm^3>,'a3':<lines/mm^4> # polynome for line density of the mirror
# 'eqs'{ #<equation solving parameters>
# 'k': <deflection order (default=1)>,
# 'k': <deflection_lutColor order (default=1)>,
# 'lut': [# lookup table for starting guess values at a given energy for equation solver
# ( <energy (eV)>, <r1(mm)>, <r2(mm)>, <alpha(rad)>),
# ( ... ),

View File

@@ -1,6 +1,25 @@
spectrumProc
============
ESF RIXS applications
=====================
This repository contains RIXS processing tools for Furka
![alt spectrumProc](snapshot1.png "spectrumProc")
RIXSconfig
----------
configure and move the Furka RIXS arm to a desired energy
![alt RIXSconfig](RIXSconfig.png "RIXSconfig")
ARESvis
-------
live visualization of the ARES chamber tools to avoid collisions and beam clipping
![alt ARESvis](ARESvis.png "ARESvis")
spectrumProc
------------
spectrum post processing tool:
![alt spectrumProc](spectrumProc.png "spectrumProc")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

BIN
spectrumProc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

View File

@@ -7,7 +7,10 @@
# *-----------------------------------------------------------------------*
"""
SwissFEL Athos spectrometer
SwissFEL Athos spectrometer data processing
!!! If there is a problem with library or version, try: !!!
!!! /opt/gfa/python-3.8/latest/bin/python /sf/furka/applications/EsfRixsApps/spectrumProc/spectrumProc.py !!!
- select file 'FM_data.pickle'
- select run '226'
@@ -24,7 +27,9 @@ bitmask for simulation:
0x80:
"""
import os.path
import sys, logging, pickle
_log=logging.getLogger(__name__)
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QSlider, QLineEdit,\
QCheckBox, QHBoxLayout, QVBoxLayout, QGroupBox, QGridLayout, QComboBox, QFileDialog
@@ -34,14 +39,15 @@ from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import sys, logging, pickle
import numpy as np
import scipy
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression,RANSACRegressor
try:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression,RANSACRegressor
except ModuleNotFoundError as e:
_log.warning(f'sklearn import failed!\n pip install scipy scikit-learn -U --user')
_log=logging.getLogger(__name__)
def FitCurv_SPC_Cmos(evnts_j_tot, evnts_i_tot, ROI, MAD_n=4, wnd=None):
'''
@@ -270,7 +276,9 @@ if __name__ == '__main__':
parser=argparse.ArgumentParser(epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('--mode', '-m', type=lambda x:int(x, 0), help='mode (see bitmasks) default=0x%(default)x', default=1)
parser.add_argument("--sim", "-s", type=lambda x: int(x,0), help="simulate devices (see bitmasks) default=0x%(default)x", default=0x01)
parser.add_argument("--file", "-f", help="raw data file default=%(default)s", default='FM_data.pickle')
fn=os.path.join(os.path.dirname(os.path.relpath(os.path.realpath(__file__))),'FM_data.pickle')
#fn=os.path.join(os.path.dirname(os.path.realpath(__file__)),'FM_data.pickle')
parser.add_argument("--file", "-f", help="raw data file default=%(default)s", default=fn)
args=parser.parse_args()
_log.info('Arguments:{}'.format(args.__dict__))