diff --git a/gunPhaseScan.py b/gunPhaseScan.py
new file mode 100644
index 0000000000000000000000000000000000000000..338a245df4dfbc6c7f86245be8bad0cc9bfc2590
--- /dev/null
+++ b/gunPhaseScan.py
@@ -0,0 +1,390 @@
+#!/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_())