Skip to content
Snippets Groups Projects
Commit 58870221 authored by Mauro Trovo's avatar Mauro Trovo :headphones:
Browse files

MT - origin file

parent 838aadb0
Branches master
No related tags found
No related merge requests found
#!/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_())
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment