Commit 8ecef216 authored by Nick Sauerwein's avatar Nick Sauerwein
Browse files

spectrometer setup to be implemented

parent b6f3b2da
......@@ -18,7 +18,7 @@ pos_L: radius of blade set by linear stage [mm]
measurement file (n.a)
'''
default_config = {'pos_R': 329, 'pos_L':-1.6}
default_config = {'pos_R': 20, 'pos_L':0}
class BladePositioning:
def __init__(self, config):
......@@ -32,7 +32,7 @@ class BladePositioning:
return config
@config.setter
def set_config(self, config):
def config(self, config):
s.maaR(config['pos_R'])
s.mpaL(config['pos_L']+cor(s.getposR()))
......
......@@ -61,11 +61,11 @@ def getposL():
return ret
def maaR(angle):
rev=-1
rev=0
#print (angle)
cmd("MAA0,"+str(int(angle*1000000))+","+str(rev)+",60000")
cmd("MAA0,"+str(int(angle*1000000))+","+str(rev)+",0")
while cmd("GS0",output=True)[-2]!=str(3):
#print(cmd("GS0",output=True)[-2])
if cmd("GS0",output=True)[-2] == str(0):
......@@ -83,11 +83,11 @@ def maaR(angle):
def mpaL(pos):
print ('desired position: ',pos)
#print ('desired position: ',pos)
assert (not(pos < -5.3507 or pos > 0.522162))
cmd("MPA1,"+str(int(pos*1e6))+",60000")
cmd("MPA1,"+str(int(pos*1e6))+",0")
# while cmd("GS1",output=True)[-2]!=str(3):
# time.sleep(0.2)
while cmd("GS1",output=True)[-2]!=str(3):
......@@ -129,7 +129,8 @@ def init():
moverelR(-1)
time.sleep(1)
frmR("fwd")
frmR("bwd")
while cmd("GS0",output=True)[-2]!=str(3):
if cmd("GS0",output=True)[-2] == str(0):
print ('reference not found, stage probably to far from reference ')
......@@ -138,13 +139,17 @@ def init():
#print(cmd("GS0",output=True)[-2])
time.sleep(1)
#set limit for rot. Positioner (5,-200)
cmd("SAL0,160000000,-1,5000000,0")
cmd("SAL0,0, 0,"+str(270e6)+",0")
print("R",getposR())
print("rot. ref. done")
print("find lin. ref.")
moverelL(-0.1)
time.sleep(3)
frmL("fwd")
frmL("bwd")
while cmd("GS1",output=True)[-2]!=str(3):
#print(cmd("GS0",output=True)[-2])
time.sleep(1)
......@@ -154,7 +159,7 @@ def init():
print("L",getposL())
print("lin. ref. done")
cmd("SPL1,"+str(-3e4)+","+str(3e6))
#if reboot: init()
#time.sleep(2)
#moverelR(-5)
......
......@@ -29,15 +29,10 @@ class DelayGenerator:
self.jet = self.ddg.Output(self.ddg,3)
self.config = config
@property
def config(self, config):
self.setMode(config['mode'])
self.setJet(config['jet_triggered'])
self.setRate(config['rate'])
self.t_sleep = config['t_sleep']
@config.setter
def get_config(self):
@property
def config(self):
config = {}
config['mode'] = self.getMode()
config['jet_triggered'] = self.getJet()
......@@ -45,7 +40,12 @@ class DelayGenerator:
config['t_sleep'] = self.t_sleep
return config
@config.setter
def config(self, config):
self.setMode(config['mode'])
self.setJet(config['jet_triggered'])
self.setRate(config['rate'])
self.t_sleep = config['t_sleep']
def setMode(self, mode):
if mode == 'single shot':
......
......@@ -53,6 +53,11 @@ class FaradayCup:
import datetime
time = datetime.datetime.now()
measurement = {}
v_calib = np.mean(sig_uvolt[:,100])
sig_uvolt = sig_uvolt - v_calib
charge = np.trapz(sig_uvolt, x = np.array(sig_time)*1e-9)*1e-6/self.R/self.amplification*1e15
measurement = {'time': time,'sig_time': sig_time, 'sig_uvolt': sig_uvolt, 'peak_uvolt': np.min(sig_uvolt),'charge': charge }
return measurement
......
......@@ -56,7 +56,7 @@ class FocusCamera:
return config
@config.setter
def set_config(self,config):
def config(self,config):
self.min_intensity = config['min_intensity']
self.cam.properties['ExposureTimeAbs']=config['ExposureTimeAbs']
......@@ -82,12 +82,12 @@ class FocusCamera:
comment = 'beam detected'
else:
comment = 'No beam detected'
FWHMx = 20
FWHMy = 20
cxmm = None
cymm = None
FWHMx = 100
FWHMy = 100
cxum = None
cyum = None
measurement['comment'], measurement['FWHMx'], measurement['FWHMy'], measurement['cxum'], measurement['cyum'] = (comment, FWHMx, FWHMy, cxmm, cymm)
measurement['comment'], measurement['FWHMx'], measurement['FWHMy'], measurement['cxum'], measurement['cyum'] = (comment, FWHMx, FWHMy, cxum, cyum)
measurement['maxit'] = max_int
return measurement
......@@ -95,7 +95,7 @@ class FocusCamera:
def plot_measure(self, measurement, config = None):
if self.plot_server_im == None:
self.plot_server_im = Plot2DServer({'title':'FocusCamera', 'xlabel':'y [um]', 'ylabel': 'x [um]', 'image': True})
self.plot_server_im = Plot2DServer({'title':'FocusCamera', 'xlabel':'x [um]', 'ylabel': 'y [um]', 'image': True})
im = measurement['im'].astype('float32')
......@@ -110,11 +110,11 @@ class FocusCamera:
FWHMx = measurement['FWHMx']
FWHMy = measurement['FWHMy']
if cxum:
if type(cxum) != type(None):
xminum, xmaxum = np.min(cxum) - nFWHM * FWHMx, np.max(cxum) + nFWHM * FWHMx
yminum, ymaxum = np.min(cyum) - nFWHM * FWHMy, np.max(cyum) + nFWHM * FWHMy
im = im[xminum/self.psize:xmaxum/self.psize, yminum/self.psize:ymaxum/self.psize]
im = im[int(yminum/self.psize):int(ymaxum/self.psize),int(xminum/self.psize):int(xmaxum/self.psize)]
else:
xminum = 0
......@@ -129,7 +129,7 @@ class FocusCamera:
im = binArray(im, 0, n_binning, n_binning, np.mean)
im = binArray(im, 1, n_binning, n_binning, np.mean)
self.plot_server_im.update(np.flipud(im),extent=(yminum,ymaxum, yminum, ymaxum))
self.plot_server_im.update(np.flipud(im),extent=(xminum,xmaxum, yminum, ymaxum))
......
......@@ -37,39 +37,32 @@ def find_beam(im, plot = True, nFWHM = 2, axis = None):
itmaxypx, itmaxxpx = np.unravel_index(im.argmax(), im.shape)
itmax = im[itmaxypx, itmaxxpx]
itmaxxum, itmaxyum = px2mm(itmaxxpx, itmaxypx)
itmaxxum, itmaxyum = px2um(itmaxxpx, itmaxypx)
px_box = 100
im_reduced = im[itmaxypx-px_box:itmaxypx+px_box, itmaxxpx-px_box:itmaxxpx+px_box]
#filter
from skimage.filters import gaussian
im_reduced = gaussian(im_reduced, sigma = 1)
itmax = np.max(im_reduced)
from skimage.measure import find_contours
cs = find_contours(im, itmax/2)
cs = find_contours(im_reduced, itmax/2)
#print ('# of contours: ',len(cs))
clens = [len(con[0]) for con in cs]
arg = np.argmax(clens)
c = cs[arg]
cxpx = c.T[1] #+ itmaxxpx-framepx
cypx = c.T[0] #+ itmaxypx-framepx
cxpx = c.T[1] + itmaxxpx-px_box#+ itmaxxpx-framepx
cypx = c.T[0] + itmaxypx-px_box#+ itmaxypx-framepx
cxum, cyum = px2um(cxpx, cypx)
FWHMx = np.max(cxum) - np.min(cxum)
FWHMy = np.max(cyum) - np.min(cyum)
if plot:
showimage(im, axis = axis)
axis.plot(cxum, cyum, 'g')
FWHMx = np.max(cxum) - np.min(cxum)
FWHMy = np.max(cyum) - np.min(cymm)
axis.set_xlim(np.min(cxum) - nFWHM * FWHMx, np.max(cxum) + nFWHM * FWHMx)
axis.set_ylim(np.min(cyum) - nFWHM * FWHMy, np.max(cyum) + nFWHM * FWHMy)
axis.set_xlabel('x [mm]')
axis.set_ylabel('y [mm]')
axis.set_title('Center: ('+str(itmaxxum)+', '+str(itmaxyum)+'), Intensity: '+str(itmax))
return (itmax, itmaxxum, itmaxyum),(cxum, cyum)
\ No newline at end of file
......@@ -77,7 +77,7 @@ modei = {'Off': False, 'On': True}
class Interferometer:
#mendatory functions
def __init__(self, config, blade = None, delay = None):
def __init__(self, config, BladePositioning, DelayGenerator):
#fixed variables
self.X_nozzle=1300
......@@ -94,8 +94,8 @@ class Interferometer:
self.config = config
self.blade = blade
self.delay = delay
self.blade = BladePositioning
self.delay = DelayGenerator
self.plot_server_im = None
self.plot_server_ph = None
......@@ -170,7 +170,7 @@ class Interferometer:
if self.plot_server_tomo == None:
self.plot_server_tomo = Plot2DServer({'title':'Tomography live', 'xlabel':'z [mm]', 'ylabel': 'x [mm]','image': True})
blade_config0 = self.blade.get_config()
blade_config0 = self.blade.config
global t_begin
t_begin = t.time()
......@@ -217,7 +217,6 @@ class Interferometer:
def plot_measure(self, measurement, config = None):
if self.Tomography:
from PlottingServers import Plot2DServer
if self.plot_server_tomo == None:
self.plot_server_tomo = Plot2DServer({'title':'Tomography live', 'xlabel':'z [mm]', 'ylabel': 'x [mm]','image': True})
......@@ -254,7 +253,6 @@ class Interferometer:
x0 = self.x0
z0 = self.z0
from PlottingServers import Plot2DServer
if self.plot_server_im == None:
self.plot_server_im = Plot2DServer({'title':'Interferometer Image', 'xlabel':'z [mm]', 'ylabel': 'x [mm]','image': True})
......@@ -364,7 +362,7 @@ class Interferometer:
print ('Angle ',angle)
blade_config1['pos_R'] = blade_config0['pos_R'] + angle
self.blade.set_config(blade_config1)
self.blade.config = blade_config1
print ('Time [Drive to angle ',angle,'] = ', t.time() - t_begin)
if p:
p.join()
......@@ -396,7 +394,7 @@ class Interferometer:
np.save("Data/Interferometer/images_angles.npy", {'images_angles': images_angles, 'angles': angles})
self.blade.set_config(blade_config0)
self.blade.config = blade_config0
print ('Time [Drive to angle 0] = ', t.time() - t_begin)
......
......@@ -59,7 +59,7 @@ class Laser:
return 100 * np.cos((phi - self.max_angle)/90*np.pi)
def set_lin_comp(self, pos):
print (self.old_comp_lin, pos)
#print (self.old_comp_lin, pos)
if self.old_comp_lin == pos:
return
caput('F10HU-LMOT705:MOT.VAL', pos)
......
......@@ -10,12 +10,20 @@ config file:
pos_Pay: current position of motor Pay
pos_Paz: current position of motor Paz
home_on_connect: boolean
n_av: number of focus measurements per iteration
maxiter: maximal number of iterations
minint: minimal intensity to search for beam
measurement file (n.a)
'''
default_config = {'pos_Pay': 3.99396444,
'pos_Paz': 5.16051188}
'pos_Paz': 5.16051188,
'home_on_connect':True,
'n_av': 10,
'maxiter':20}
class ParabolicMirror:
def __init__(self, config, FocusCamera, Periscope, Laser):
......@@ -33,8 +41,8 @@ class ParabolicMirror:
except:
print ('Connection to motors failed. Close all programs that'+' use the motors or restart the controllers')
raise
if home:
if config['home_on_connect']:
self.home()
self.config = config
......@@ -44,7 +52,10 @@ class ParabolicMirror:
config = {}
config['pos_Pay'] = float(self.Pay.position())
config['pos_Paz'] = float(self.Paz.position())
config['home_on_connect'] = self.home_on_connect
config['n_av'] = self.n_av
config['maxiter'] = self.maxiter
return config
@config.setter
......@@ -52,7 +63,9 @@ class ParabolicMirror:
self.Pay.goto(config['pos_Pay'])
self.Paz.goto(config['pos_Paz'])
self.n_av = config['n_av']
self.maxiter = config['maxiter']
self.home_on_connect = config['home_on_connect']
def connect_motors(self):
......@@ -70,11 +83,16 @@ class ParabolicMirror:
self.optimize()
def optimize(self, wanted_focus_um = 8, n_av = 1, sleep_time = 0.2, output = True, maxiter = 100):
def optimize(self, wanted_focus_um = 8, sleep_time = 0.2, output = True):
#this variable is necessary to compensate the attenuation of the laser
global intmult
intmult = 1.
maxiter = self.maxiter
n_av = self.n_av
global reduce_int
reduce_int = False
def to_min():
......@@ -84,14 +102,14 @@ class ParabolicMirror:
FWHMys = []
maxints = []
for i in range(n_av):
measurement = focus.measure()
measurement = self.focus.measure()
FWHMxs.append(measurement['FWHMx'])
FWHMys.append(measurement['FWHMy'])
maxints.append(measurement['maxit'])
#if output:
# focus.plot_measure(measurement)
# plt.pause(0.01)
if output:
self.focus.plot_measure(measurement)
del measurement
if output:
print ('FWHMxs: ',FWHMxs)
......@@ -99,7 +117,7 @@ class ParabolicMirror:
print ('maxints: ',maxints)
print ('mean(maxits): ',np.mean(maxints))
res = (np.array(FWHMxs)**2 + np.array(FWHMys)**2)/2#*4096/np.array(maxints)*intmult
res = np.sqrt((np.array(FWHMxs)**2 + np.array(FWHMys)**2)/2)#*4096/np.array(maxints)*intmult
mean, error = np.mean(res), np.std(res, ddof = -1)/np.sqrt(len(res))
global reduce_int
if np.mean(maxints) > 4e3:
......@@ -109,7 +127,7 @@ class ParabolicMirror:
if output:
print ('mean: ',mean,'error: ', error)
if mean*1e3 < wanted_focus_um:
if mean < wanted_focus_um:
if output:
print ('The optimization converged. Final value: ',mean)
return
......@@ -121,15 +139,18 @@ class ParabolicMirror:
def change_parameter(y, z, zc):
print ('Parameters: ',(y, z, zc))
config = {'pos_Pay': y, 'pos_Paz': z}
config = self.config
config['pos_Pay'] = y
config['pos_Paz'] = z
self.config = config
config_per = self.per.config()
config_per = self.per.config
config_per['deltaz_Cz'] = zc
#Cz.mAbs(zc)
per.set_config(config_per)
self.per.config = config_per
return True
def opt_f(x):
......@@ -161,9 +182,9 @@ class ParabolicMirror:
global reduce_int, intmult
if reduce_int:
config_laser = self.laser.config
config_laser['attenuation'] = config_laser['attenuation']/1.2
laser.config = config_laser
intmult *= 1.2
config_laser['attenuation'] = config_laser['attenuation']/1.15
self.laser.config = config_laser
intmult *= 1.15
reduce_int = False
print ('laser attenuated')
......
......@@ -19,6 +19,7 @@ deltaz_Mz: motor position at local origin Mz
deltaz_Cz: motor position at local origin Cz
sync_camera: boolean
home_on_connect: boolean
......@@ -34,21 +35,24 @@ default_config = {'pos_l_x': 0.1,
'pos_g_origin_z': 25./2,
'deltaz_Mz': 0,
'deltaz_Cz': 0,
'sync_camera': False}
'sync_camera': False,
'home_on_connect':True}
class Periscope:
def __init__(self, config):
import time
time.sleep(0.01)
time.sleep(0.2)
try:
self.connect_motors()
print ('Connnection with motors sucessful!')
except:
print ('Connection to motors failed. Close all programs that'+' use the motors or restart the controllers')
raise
if home:
if config['home_on_connect']:
self.home()
self.config = config
@property
......@@ -68,6 +72,7 @@ class Periscope:
config['deltaz_Cz'] = float(self.get_deltaz_Cz())
config['sync_camera'] = self.sync_camera
config['home_on_connect'] = self.home_on_connect
return config
......@@ -88,6 +93,8 @@ class Periscope:
self.deltaz_Mz = config['deltaz_Mz']
self.deltaz_Cz = config['deltaz_Cz']
self.home_on_connect = config['home_on_connect']
self.set_bounds()
self.sync_camera = config['sync_camera']
......@@ -235,14 +242,14 @@ class Periscope:
x,y,z = list(pos_g)
if sync_camera:
print ('c')
#print ('c')
self._mCamAbs(z)
print ('x')
#print ('x')
self._mxAbs(x)
print ('y')
#print ('y')
self._myAbs(y)
print ('z')
#print ('z')
self._mzAbs(z)
......
......@@ -46,7 +46,7 @@ class ScreenCamera:
self.psize=1./127.95*3/1.70 #mm
self.ep=1.74/self.psize
self.camera_serial_number = 21547524
self.camera_serial_number = 22360583
self.connect_camera()
......
import TMCL
import Pyro4
import time
from serial import Serial
import numpy as np
import time
import sys
sys.path.append('directory where spectroanalyser scripts are')
import sys
sys.path.insert(0, '../../scripts/')
import sympy as sym
import numpy as np
import matplotlib.pyplot as plt
sym.init_printing(use_latex='mathjax')
import Physics
import BeamShape
import LinearModel_Accelerator as LMA
import LinearModel_Elements as LME
import VariableSpectrometer as VS
import ChangeOfE0 as COE
'''
config file:
lattice_elements: string of connected lattice elements (i.e. Q1Q2Q3D1). The order of the elements is irrelevant.
because at the experiment we will only place them in the normal order Q1Q2Q3D1
Q1_gradient: gradient of Q1 magnet [T/m]
Q1_angle: angle of b_2 in complex plane (two times the real rotation in the laboratory frame of reference)
Q2_gradient: gradient of Q2 magnet [T/m]
Q2_angle: angle of b_2 in complex plane (two times the real rotation in the laboratory frame of reference)
Q3_gradient: gradient of Q3 magnet [T/m]
Q3_angle: angle of b_2 in complex plane (two times the real rotation in the laboratory frame of reference)
D1_field: field of D1 magnet [mT]
D1_angle: angle of b_1 in complex plane (the real rotation in the laboratory frame of reference)
d_source_Q1: distance between jet and Q1
d_Q1_Q2: distance between Q1 and Q2
d_Q2_Q3: distance between Q2 and Q3
d_Q3_D1: distance between Q3 and D1
d_D1_screen: distance between D1 and screen
E0: reference energy. The energy that will be used to set up the focusing and deflection conditions
deflection: distance that particles at reference energy are shifted on screen due to dipole (the dipole will be set when special function spec_set_dispersion is started)
delfection_angle: [deg] direction in which the electrons should be dispersed
measurement n.a
'''
default_config = {'max_angle': -22.9,
'attenuation': 100,
'comp_lin': 38.020,
'channel': 1}
L_Q1 = 0.08
L_Q2 = 0.08