Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
gun_phasescan
Manage
Activity
Members
Labels
Plan
Issues
0
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Mauro Trovo
gun_phasescan
Commits
58870221
Commit
58870221
authored
4 years ago
by
Mauro Trovo
Browse files
Options
Downloads
Patches
Plain Diff
MT - origin file
parent
838aadb0
Branches
master
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
gunPhaseScan.py
+390
-0
390 additions, 0 deletions
gunPhaseScan.py
with
390 additions
and
0 deletions
gunPhaseScan.py
0 → 100644
+
390
−
0
View file @
58870221
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Gun Phase scan
Created in quarantena 2020
@author: mauro
"""
#import os
import
sys
import
numpy
as
np
import
PyTango
import
h5py
import
time
from
PyQt4.QtCore
import
*
from
PyQt4.QtGui
import
*
from
scipy.interpolate
import
interp1d
from
scipy.optimize
import
minimize_scalar
from
threading
import
Thread
#from matplotlib import pyplot as plt
from
matplotlib.backends.backend_qt4agg
import
FigureCanvasQTAgg
as
FigureCanvas
#from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from
matplotlib.figure
import
Figure
# variabili globali
# phase_offset = 0
treadOut
=
[]
# un dictionary for i device:
t_dev
=
{}
try
:
t_dev
[
'
pil_sh
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/usa/mps/shutter
'
)
# ->Close, Open State
t_dev
[
'
inj_current
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/inj/diagnostics/cm_inj.01
'
)
t_dev
[
'
charge_fb
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/f/feedback/charge_fb.01
'
)
t_dev
[
'
timing
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/f/timing/bunchnumber_f
'
)
#,'BunchNumberFrequency'
t_dev
[
'
llrf_k1
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/kg01/mod/llrf_kg01.01
'
)
#'cav_phase_set'
t_dev
[
'
mod_k1
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/kg01/mod/rfamp
'
)
t_dev
[
'
llrf_ks
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/kgsp/mod/llrf_kgsp.01
'
)
t_dev
[
'
pil_en
'
]
=
PyTango
.
DeviceProxy
(
'
srv-tango-srf-01:20000/pil/energy_meter/eml_pil.01
'
)
except
PyTango
.
DevFailed
:
print
(
'
error defining device, DeviceProxys
'
)
#####################
class
PhaScan
():
def
__init__
(
self
,
inputs
):
"""
dati scan
"""
self
.
inputs
=
inputs
# [startphase, stopphase, stepphase, n_shot]
self
.
phases
=
np
.
linspace
(
inputs
[
0
],
inputs
[
1
],
num
=
(
int
((
inputs
[
1
]
-
inputs
[
0
])
/
inputs
[
2
])
+
1
),
endpoint
=
True
)
self
.
currents
=
np
.
zeros
(
len
(
self
.
phases
))
self
.
curr_errors
=
np
.
zeros
(
len
(
self
.
phases
))
def
getscan
(
self
):
rnmCheck
=
False
# % wave dei valori di fase:
phase_wave
=
[]
for
i
in
range
(
int
(
self
.
inputs
[
3
])):
phase_wave
.
extend
(
self
.
phases
)
phase_wave
.
sort
()
phaseWaveform
=
np
.
fmod
(
phase_wave
,
360
)
# % set number of waveform cycles (WaveLoopMode must be set to 0) a = 1;
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
PhaseWaveformNumCycles
'
,
1
)
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
PhaseWaveformAbsMode
'
,
True
)
# False
# % load waveform
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
PhaseWaveform
'
,
phaseWaveform
)
# % set current waveform as absolute value, a=1;
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
PhaseWaveformAbsMode
'
,
True
)
# False
if
t_dev
[
'
llrf_k1
'
].
read_attribute
(
'
RnmMode
'
).
value
:
rnmCheck
=
True
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
RnmMode
'
,
False
)
# False
# % read current bunch number
b_stemp
=
t_dev
[
'
timing
'
].
read_attribute
(
'
BunchNumber
'
)
bunchstart
=
b_stemp
.
value
+
20
#print(bunchstart)
# % set bunch number start
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
PhaseWaveformBunchNumberStart
'
,
bunchstart
)
t_dev
[
'
llrf_k1
'
].
command_inout
(
'
PhaseWaveformStart
'
)
# aspetto che sia finita la wave frequenza pari
try
:
freq
=
t_dev
[
'
timing
'
].
read_attribute
(
'
BunchNumberFrequency
'
)
# print(freq.value)
frequenza
=
freq
.
value
except
PyTango
.
DevFailed
:
print
(
'
error reading Frequency
'
)
frequenza
=
10
time
.
sleep
(((
len
(
phase_wave
))
/
frequenza
)
+
1
)
indice
=
[
1
,
bunchstart
+
1
,
(
bunchstart
+
1
+
len
(
phase_wave
))]
bunch_shots
=
t_dev
[
'
inj_current
'
].
command_inout
(
'
GetCharge
'
,
indice
)
for
i
in
range
(
len
(
self
.
phases
)):
self
.
currents
[
i
]
=
np
.
mean
(
bunch_shots
[
int
(
self
.
inputs
[
3
])
*
i
:
int
(
self
.
inputs
[
3
])
*
(
i
+
1
)])
self
.
curr_errors
[
i
]
=
np
.
std
(
bunch_shots
[
int
(
self
.
inputs
[
3
])
*
i
:
int
(
self
.
inputs
[
3
])
*
(
i
+
1
)])
t_dev
[
'
llrf_k1
'
].
command_inout
(
'
PhaseWaveformAbort
'
)
if
rnmCheck
:
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
RnmMode
'
,
True
)
output
=
[
self
.
phases
,
self
.
currents
,
self
.
curr_errors
]
return
output
#####################
class
Lancio
(
Thread
):
def
__init__
(
self
,
nome
,
inputs
):
Thread
.
__init__
(
self
)
self
.
nome
=
nome
self
.
input
=
inputs
def
__del__
(
self
):
self
.
exiting
=
False
#self.wait()
def
run
(
self
):
ph_scan
=
PhaScan
(
self
.
input
)
global
treadOut
treadOut
=
ph_scan
.
getscan
()
###############################################################################
class
MainWindow
(
QDialog
):
def
__init__
(
self
,
parent
=
None
):
super
(
MainWindow
,
self
).
__init__
(
parent
)
self
.
setWindowTitle
(
"
Gun phase scan
"
)
self
.
dati_scan
=
[]
self
.
phase_offset
=
0
# input ###############################################################
larghezzal
=
90
self
.
gruppo_input
=
QGroupBox
(
'
Inputs
'
)
#self.gruppo_input.setStyleSheet("border: 1px solid #E77200")
self
.
gruppo_input
.
setStyleSheet
(
"
color : blue
"
)
self
.
label1
=
QLabel
(
"
Start phase
"
)
self
.
label1
.
setMaximumWidth
(
larghezzal
)
self
.
startphase
=
QDoubleSpinBox
()
self
.
startphase
.
setSingleStep
(
5
)
self
.
startphase
.
setMinimum
(
0.0
)
self
.
startphase
.
setMaximum
(
500.0
)
self
.
startphase
.
setValue
(
250
)
self
.
label2
=
QLabel
(
"
Stop phase
"
)
self
.
label2
.
setMaximumWidth
(
larghezzal
)
self
.
stopphase
=
QDoubleSpinBox
()
self
.
stopphase
.
setSingleStep
(
5
)
self
.
stopphase
.
setMinimum
(
0.0
)
self
.
stopphase
.
setMaximum
(
500.0
)
self
.
stopphase
.
setValue
(
400
)
self
.
label3
=
QLabel
(
"
Step
"
)
self
.
label3
.
setMaximumWidth
(
larghezzal
)
self
.
stepphase
=
QDoubleSpinBox
()
self
.
stepphase
.
setSingleStep
(
1
)
self
.
stepphase
.
setMinimum
(
1.0
)
self
.
stepphase
.
setMaximum
(
15.0
)
self
.
stepphase
.
setValue
(
3
)
self
.
label4
=
QLabel
(
"
n. shots
"
)
self
.
label4
.
setMaximumWidth
(
larghezzal
)
self
.
n_shot
=
QDoubleSpinBox
()
self
.
n_shot
.
setSingleStep
(
1
)
self
.
n_shot
.
setMinimum
(
2.0
)
self
.
n_shot
.
setMaximum
(
20.0
)
self
.
n_shot
.
setValue
(
5
)
self
.
combo
=
QComboBox
()
self
.
combo
.
addItem
(
"
No knee - 80 MV/m
"
)
self
.
combo
.
addItem
(
"
Low knee - 80 MV/m
"
)
self
.
combo
.
addItem
(
"
High knee - 80 MV/m
"
)
self
.
combo
.
addItem
(
"
No knee - 100 MV/m
"
)
self
.
combo
.
addItem
(
"
Low knee - 100 MV/m
"
)
self
.
combo
.
addItem
(
"
High knee - 100 MV/m
"
)
self
.
combo
.
addItem
(
"
Low knee - 5 ps
"
)
self
.
combo
.
addItem
(
"
High knee - 5 ps
"
)
self
.
combo
.
setCurrentIndex
(
7
)
# definisco un default
layoutinput
=
QFormLayout
()
layoutinput
.
addRow
(
self
.
label1
,
self
.
startphase
)
layoutinput
.
addRow
(
self
.
label2
,
self
.
stopphase
)
layoutinput
.
addRow
(
self
.
label3
,
self
.
stepphase
)
layoutinput
.
addRow
(
self
.
label4
,
self
.
n_shot
)
layoutinput
.
addRow
(
self
.
combo
)
self
.
gruppo_input
.
setLayout
(
layoutinput
)
# actions ########################################################################################################
self
.
gruppo_action
=
QGroupBox
(
'
Actions
'
)
#self.gruppo_action.setStyleSheet("border: 1px solid #009DC4")
self
.
gruppo_action
.
setStyleSheet
(
"
color : navy
"
)
self
.
tasto_scan
=
QPushButton
(
'
Start SCAN
'
)
self
.
tasto_scan
.
setCheckable
(
True
)
self
.
tasto_scan
.
setStyleSheet
(
"
background-color : aqua
"
)
# self.tasto_scan.clicked.connect(self.btnstate)
self
.
tasto_scan
.
clicked
.
connect
(
self
.
phasescanstart
)
self
.
tasto_save
=
QPushButton
(
'
SAVE Data
'
)
self
.
tasto_save
.
clicked
.
connect
(
self
.
savedata
)
self
.
tasto_save
.
setEnabled
(
False
)
self
.
tasto_fit
=
QPushButton
(
'
FIT Data
'
)
self
.
tasto_fit
.
clicked
.
connect
(
self
.
fitdataset
)
self
.
tasto_fit
.
setEnabled
(
False
)
self
.
delta_phase
=
QDoubleSpinBox
()
self
.
delta_phase
.
setSingleStep
(
0.2
)
self
.
delta_phase
.
setMinimum
(
-
50.0
)
self
.
delta_phase
.
setMaximum
(
-
10.0
)
self
.
delta_phase
.
setValue
(
-
30
)
self
.
tasto_setph
=
QPushButton
(
'
SET Phase
'
)
self
.
tasto_setph
.
clicked
.
connect
(
self
.
phaseK1set
)
self
.
tasto_setph
.
setEnabled
(
False
)
layoutaction
=
QVBoxLayout
()
layoutaction
.
addWidget
(
self
.
tasto_scan
)
layoutaction
.
addWidget
(
self
.
tasto_fit
)
layoutaction
.
addWidget
(
self
.
delta_phase
)
layoutaction
.
addWidget
(
self
.
tasto_setph
)
layoutaction
.
addWidget
(
self
.
tasto_save
)
self
.
gruppo_action
.
setLayout
(
layoutaction
)
# a figure instance to plot on
self
.
figure1
=
Figure
(
figsize
=
(
3.8
,
3.8
))
# this is the Canvas Widget that displays the `figure`
# it takes the `figure` instance as a parameter to __init__
self
.
canvas1
=
FigureCanvas
(
self
.
figure1
)
self
.
ax1
=
self
.
figure1
.
add_subplot
(
211
)
self
.
ax2
=
self
.
figure1
.
add_subplot
(
212
)
### layout generale ####################################
loglobale
=
QGridLayout
()
loglobale
.
addWidget
(
self
.
gruppo_input
,
0
,
0
,
1
,
1
)
loglobale
.
addWidget
(
self
.
gruppo_action
,
1
,
0
,
1
,
1
)
loglobale
.
addWidget
(
self
.
canvas1
,
0
,
1
,
2
,
1
)
self
.
setLayout
(
loglobale
)
self
.
show
()
# definiamo i metodi:
############fuinzione di servizio per il display di messaggio ###########
def
showdialog_e
(
self
,
s_testo
):
msg
=
QMessageBox
()
msg
.
setIcon
(
QMessageBox
.
Warning
)
msg
.
setText
(
s_testo
)
# msg.setInformativeText("This is additional information")
msg
.
setWindowTitle
(
"
Error Message
"
)
# msg.setDetailedText("The details are as follows:")
msg
.
setStandardButtons
(
QMessageBox
.
Ok
|
QMessageBox
.
Cancel
)
# msg.buttonClicked.connect(msgbtn)
msg
.
exec_
()
# print "value of pressed message box button:", retval
def
btnstate
(
self
):
if
self
.
tasto_scan
.
isChecked
():
self
.
tasto_scan
.
setText
(
'
Scan done
'
)
else
:
self
.
tasto_scan
.
setText
(
'
SCAN done
'
)
############fuinzioni che fanno qualcosa ###########
def
phasescanstart
(
self
):
# inserisco il controllo sullo stato del feedback di carica: DA VERIFICARE
status_fb_q
=
t_dev
[
'
charge_fb
'
].
read_attribute
(
'
State
'
)
if
(
status_fb_q
.
value
)
==
0
:
l1
=
"
Please, STOP the Charge feedback before scanning!
"
self
.
showdialog_e
(
l1
)
self
.
tasto_scan
.
toggle
()
return
-
1
#status_pilsh = t_dev['pil_sh'].read_attribute('State') if 'CLOSE' in str(status_pilsh):
status_pilsh
=
t_dev
[
'
pil_sh
'
].
command_inout
(
'
State
'
)
if
'
CLOSE
'
in
str
(
status_pilsh
):
l2
=
"
PIL shutter is closed, OPEN before scanning!
"
self
.
showdialog_e
(
l2
)
self
.
tasto_scan
.
toggle
()
return
-
1
# leggo la fase iniziale:
try
:
phase_start
=
t_dev
[
'
llrf_k1
'
].
read_attribute
(
'
cav_phase_set
'
)
phase_in
=
phase_start
.
value
except
PyTango
.
DevFailed
:
print
(
'
error reading phase in, DeviceProxys
'
)
pass
w_title
=
"
Gun phase scan
"
+
time
.
strftime
(
"
%H:%M
"
)
self
.
setWindowTitle
(
w_title
)
self
.
tasto_scan
.
setText
(
'
Scan running ...
'
)
self
.
show
()
# costruisco l'imput dello scan
inputs
=
[
self
.
startphase
.
value
(),
self
.
stopphase
.
value
(),
self
.
stepphase
.
value
(),
self
.
n_shot
.
value
()]
thread_scan
=
Lancio
(
"
scan1
"
,
inputs
)
thread_scan
.
start
()
# Return whether the thread is alive.
# while thread_scan.is_alive():
while
thread_scan
.
isAlive
():
bunch_shot
=
t_dev
[
'
inj_current
'
].
command_inout
(
'
GetCharge
'
,
[
0
,
200
])
self
.
ax1
.
clear
()
self
.
ax1
.
plot
(
bunch_shot
,
'
b
'
)
# refresh canvas
self
.
canvas1
.
repaint
()
self
.
canvas1
.
draw
()
time
.
sleep
(
0.3
)
self
.
dati_scan
=
treadOut
# ripristino la fase
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
cav_phase_set
'
,
phase_in
)
# plot data
self
.
ax1
.
clear
()
self
.
ax2
.
clear
()
# self.ax1.plot(dati_scan(1), dati_scan(2), '*-b')
self
.
ax1
.
errorbar
(
self
.
dati_scan
[
0
],
self
.
dati_scan
[
1
],
yerr
=
self
.
dati_scan
[
2
],
xerr
=
None
,
fmt
=
'
.-g
'
)
# refresh canvas
self
.
canvas1
.
draw
()
# abilito i tasti successivi
self
.
tasto_save
.
setEnabled
(
True
)
self
.
tasto_fit
.
setEnabled
(
True
)
self
.
tasto_scan
.
setText
(
'
Re Start SCAN
'
)
self
.
tasto_scan
.
toggle
()
return
0
def
fitdataset
(
self
):
x_scan
=
self
.
dati_scan
[
0
]
y_scan
=
self
.
dati_scan
[
1
]
y_scan_norm
=
np
.
divide
(
y_scan
-
min
(
y_scan
),(
max
(
y_scan
)
-
min
(
y_scan
)))
#da provare
# y_scan_norm = np.divide(y_scan, max(y_scan))
# cerco il massimo
range
=
x_scan
[
np
.
argmax
(
y_scan
)]
+
90.
# dati delle simulazioni estratti dal file scans....
f1
=
h5py
.
File
(
'
PhaseScans.hdf5
'
,
'
r
'
)
dset
=
f1
[
'
phase_scans
'
]
x_sim
=
dset
[
0
,:]
y_sim
=
dset
[(
self
.
combo
.
currentIndex
()
+
1
),:]
#creo la funzione di interpolazione necesaria poco dopo:
f_int
=
interp1d
(
x_sim
,
y_sim
,
kind
=
'
cubic
'
,
bounds_error
=
False
,
fill_value
=
0
)
# definisco la funzione che parametrizza la distanza in fase tra le curve:
def
diffDataConOffset
(
shift
):
punti
=
y_scan_norm
*
f_int
(
x_scan
-
shift
)
return
1.
/
np
.
sum
(
punti
)
# a funzione che minimizza:
res
=
minimize_scalar
(
diffDataConOffset
,
bounds
=
(
range
-
30
,
range
+
30
),
method
=
'
bounded
'
)
self
.
phase_offset
=
res
.
x
offest_s
=
"
%.1f
"
%
self
.
phase_offset
# trasformo il numero in stringa per dopo
# parte grafica di output
self
.
ax2
.
clear
()
self
.
ax2
.
plot
((
x_scan
-
res
.
x
),
y_scan_norm
,
'
.g
'
,
x_sim
,
y_sim
,
'
r
'
)
self
.
ax2
.
set_xlabel
(
'
Offset =
'
+
offest_s
+
'
deg
'
)
# refresh canvas
self
.
canvas1
.
draw
()
f1
.
close
()
self
.
tasto_setph
.
setEnabled
(
True
)
def
phaseK1set
(
self
):
phase_value
=
self
.
delta_phase
.
value
()
+
self
.
phase_offset
print
(
phase_value
)
# mi assicuro che il valore sia buono
if
phase_value
>
360
:
phase_value
=
phase_value
-
360
if
phase_value
<
0
:
phase_value
=
phase_value
+
360
t_dev
[
'
llrf_k1
'
].
write_attribute
(
'
cav_phase_set
'
,
phase_value
)
# definisco la cresta di K1
time
.
sleep
(
0.5
)
t_dev
[
'
mod_k1
'
].
command_inout
(
'
ResetKlystronPhase
'
)
def
savedata
(
self
,
dati
):
# recupero la PIL energy:
pil_energy
=
t_dev
[
'
pil_en
'
].
read_attribute
(
'
Corrected_energy
'
)
pil_energy_v
=
pil_energy
.
value
# % compongo la stringa per il salvataggio:
pathf
=
'
/home/fermi/data/ShottkyScan/runXX/
'
# filename = 'ShScan_'+ time.strftime("%Y%m%d_%H%M%S")
filename
=
'
ShScan_
'
+
time
.
strftime
(
"
%Y%m%d_%H%M
"
)
# print 'saving file : ', fn
f_out
=
h5py
.
File
(
'
%s%s.hdf5
'
%
(
pathf
,
filename
),
'
w
'
)
f_out
.
create_dataset
(
'
PILenegy
'
,
data
=
pil_energy_v
)
f_out
.
create_dataset
(
'
Ph Offset
'
,
data
=
self
.
phase_offset
)
f_out
.
create_dataset
(
'
Scan
'
,
data
=
self
.
dati_scan
)
f_out
.
close
()
# return '%s%s.hdf5'%(dn, fn)
#####################
if
__name__
==
'
__main__
'
:
app
=
QApplication
([])
window
=
MainWindow
()
window
.
show
()
sys
.
exit
(
app
.
exec_
())
This diff is collapsed.
Click to expand it.
Preview
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment