def calc_wake(self, gap, beam_offset, struct_length):
     #print('calc_wake gap beam_offset %.2e %.2e' % (gap, beam_offset))
     if abs(beam_offset) > gap/2.:
         raise ValueError('Beam offset is too large! Gap: %.2e Offset: %.2e' % (gap, beam_offset))
     if (gap, beam_offset, struct_length) in self.wake_dict:
         return self.wake_dict[(gap, beam_offset, struct_length)]
     wf_calc = wf_model.WakeFieldCalculator((self.time - self.time.min())*c, self.current, self.energy_eV, struct_length)
     wf_dict = wf_calc.calc_all(gap/2., R12=0., beam_offset=beam_offset, calc_lin_dipole=False, calc_dipole=True, calc_quadrupole=True, calc_long_dipole=True)
     self.wake_dict[(gap, beam_offset, struct_length)] = wf_dict
     return wf_dict
Esempio n. 2
0
    def get_wake_potential_from_profile(self, profile, gap, beam_offset,
                                        n_streaker):

        mask_curr = profile.current != 0
        where = np.argwhere(mask_curr)
        wake_tt0 = profile.time[where[0, 0]:where[-1, 0]]
        wake_tt_range = wake_tt0.max() - wake_tt0.min()
        diff = np.mean(np.diff(wake_tt0))
        try:
            add_on = np.arange(wake_tt0.max(),
                               wake_tt0.max() + wake_tt_range * 0.1,
                               diff) + diff
        except:
            raise ValueError
        wake_tt = np.concatenate([wake_tt0, add_on])
        wf_current = np.concatenate(
            [profile.current[where[0, 0]:where[-1, 0]],
             np.zeros_like(add_on)])
        wake_tt = wake_tt - wake_tt.min()
        wf_xx = wake_tt * c
        #print(wf_current.sum(), wf_xx.min(), wf_xx.max())
        wf_calc = wf_model.WakeFieldCalculator(
            wf_xx,
            wf_current,
            self.energy_eV,
            Ls=self.struct_lengths[n_streaker])
        wf_dict = wf_calc.calc_all(gap / 2.,
                                   1.,
                                   beam_offset,
                                   calc_lin_dipole=False,
                                   calc_dipole=True,
                                   calc_quadrupole=self.quad_wake,
                                   calc_long_dipole=False)
        wake = wf_dict['dipole']['wake_potential']
        if self.quad_wake:
            quad = wf_dict['quadrupole']['wake_potential']
        else:
            quad = 0

        return wake_tt, wake, quad
energy_eV = bl_meas['energy_eV']

plt.close('all')

files = [
    data_dir + '/Eloss_DEH1.fig.mat', data_dir + '/Eloss_DEH2.fig.mat',
    data_dir + '/Eloss_DEH1-2.fig.mat'
]
lengths = [1, 1, 2]
titles = ['Structure 1', 'Structure 2', 'Structures 1+2']

for n_struct, (file_, Ls, title) in enumerate(zip(files, lengths, titles)):
    print(title)
    mat = loadmat(file_)
    wf_calc = wf_model.WakeFieldCalculator(charge_xx,
                                           charge_profile,
                                           energy_eV,
                                           Ls=Ls)

    name_dict = {
        'Energy_spread': {
            'Gaussian': 'Gaussian_fit',
            'FWHM': 'direct_FWHM',
        },
        'Energy_loss': {
            'BPM': 'BPM1',
            'Screen': 'screen',
        },
    }

    data = {}
    for key1, subdict in name_dict.items():
Esempio n. 4
0
    sp.imshow(np.abs(beam_hist.T),
              aspect='auto',
              extent=[s_edges[0], s_edges[-1], x_edges[0], x_edges[-1]],
              origin='lower')

    wake_from2d = wake2d_dict['wake']
    wake_s = wake2d_dict['s_bins']

    hist1d, _ = np.histogram(probe_s, s_edges)
    hist1d = hist1d / hist1d.sum() * bp.charge
    abs_hist1d = np.abs(hist1d)
    sp.plot(s_edges[:-1],
            abs_hist1d / abs_hist1d.max() *
            (x_edges.max() - x_edges.min()) * 0.3 + x_edges.min(),
            color='red')
    wf_calc = wf_model.WakeFieldCalculator(s_edges, hist1d, bp.energy_eV, 1)
    spw = wf_model.wxd(wf_calc.xx, semigap, beam_offset)
    convoluted_wake = wf_calc.wake_potential(spw)

    sp1.plot(wf_calc.xx * 1e6, convoluted_wake / 1e6, label='Thin beam')
    sp1.plot(s_edges * 1e6, wake_from2d / 1e6, label='Large beam')

    sp0.legend(title='Distance from jaw [$\mu$m]')
    sp1.legend()

    sp = subplot(sp_ctr,
                 title='Single particle wake',
                 xlabel='s',
                 ylabel='x',
                 scix=True,
                 sciy=True,
Esempio n. 5
0
    magnet_file = '/afs/psi.ch/intranet/SF/Beamdynamics/Philipp/data/archiver_api_data/2020-07-26.h5'
    bl_meas_file = '/sf/data/measurements/2020/02/03/Bunch_length_meas_2020-02-03_15-59-13.h5'

### Generate Gaussian beam to calculate initial wake potential

tt_dict, wake_dict, current_dict = {}, {}, {}
for sig_t2 in (30e-15, sig_t, 50e-15):
    time_gauss = np.linspace(-tt_halfrange, tt_halfrange, 1000)

    current_gauss = np.exp(-(time_gauss - np.mean(time_gauss))**2 /
                           (2 * sig_t2**2))
    current_gauss[current_gauss < 0.001 * current_gauss.max()] = 0
    current_gauss = current_gauss * 200e-12 / np.sum(current_gauss)
    current_dict[sig_t2] = current_gauss

    wf_calc = wf_model.WakeFieldCalculator((time_gauss - time_gauss.min()) * c,
                                           current_gauss, energy_eV, 1.)
    wf_dict = wf_calc.calc_all(gap / 2.,
                               1.,
                               beam_offset=beam_offset,
                               calc_lin_dipole=False,
                               calc_dipole=True,
                               calc_quadrupole=False,
                               calc_long_dipole=False)

    gaussian_wake_tt = time_gauss
    gaussian_wake = wf_dict['dipole']['wake_potential']

    tt_dict[sig_t2] = time_gauss
    wake_dict[sig_t2] = gaussian_wake

time_gauss = tt_dict[sig_t]
import myplotstyle as ms

plt.close('all')

size = 1e4
total_charge = 200e-12
r12 = 11.5
energy_eV = 4e9
beam_offset = 1e-3

xx_space = np.linspace(0, 60e-6, int(size))
yy_charge = np.ones_like(xx_space) * total_charge / (size - 2)
yy_charge[0] = 0
yy_charge[-1] = 0

wf_obj = wf_model.WakeFieldCalculator(xx_space, yy_charge, energy_eV)

fig = ms.figure('Ideal beam wake field')
subplot = ms.subplot_factory(2, 2)

xlabel = 's [$\mu$m]'

sp_charge = subplot(1,
                    title='Charge_profile (total = %i pC)' %
                    (total_charge * 1e12),
                    xlabel=xlabel,
                    ylabel='Charge (pC)',
                    sciy=True)
sp_charge.plot(xx_space * 1e6, yy_charge * 1e12)

sp_wake = subplot(2,
Esempio n. 7
0
other_dict = loadH5Recursive(other)
x_axis = other_dict['x_axis'].astype(np.float64) * 1e-6
y_axis = other_dict['y_axis'].astype(np.float64) * 1e-6
del other, other_dict

### Generate Gaussian beam to calculate initial wake potential

# approximate 40 fs beam
sig_t = 40e-15
time = np.linspace(0., 400e-15, 1000)

curr = np.exp(-(time - np.mean(time))**2 / (2 * sig_t**2))
curr[curr < 0.001 * curr.max()] = 0

curr = curr * 200e-12 / np.sum(curr)
wf_calc = wf_model.WakeFieldCalculator(time * c, curr, energy_eV, 1.)
wf_dict = wf_calc.calc_all(gap / 2.,
                           r12,
                           beam_offset=(-4.09e-3 - 0.47e-3),
                           calc_lin_dipole=True,
                           calc_dipole=False,
                           calc_quadrupole=False,
                           calc_long_dipole=False)

wake_zz = wf_dict['input']['charge_xx']
convoluted_wake = wf_dict['lin_dipole']['wake_potential'] * -1

ms.figure('Wakefields')
subplot = ms.subplot_factory(2, 2)
sp_ctr = 1
Esempio n. 8
0
#t_arr =
beam_start = np.array(
    [watch['x'], watch['xp'], watch['y'], watch['yp'], interp_tt, p_arr])
beam_before_s1 = np.matmul(s1, beam_start)

#wf_dict_s1 = profile.calc_wake(gaps[0], beam_offsets[0], struct_lengths[0])

#wf_xx = np.linspace(interp_tt.min(), interp_tt.max(), 1000)*1.1*c
#wf_xx -= wf_xx.min()
wf_hist, bin_edges = np.histogram(interp_tt, bins=1000)
wf_hist = wf_hist / np.sum(wf_hist) * charge
wake_tt = (bin_edges[1:] + bin_edges[:-1]) / 2
wake_tt -= wake_tt.min()
wf_xx = wake_tt * c
wf_calc = wf_model.WakeFieldCalculator(wf_xx,
                                       wf_hist,
                                       tracker.energy_eV,
                                       Ls=struct_lengths[0])
wf_dict = wf_calc.calc_all(gaps[0] / 2.,
                           1.,
                           beam_offsets[0],
                           calc_lin_dipole=False,
                           calc_dipole=True,
                           calc_quadrupole=False,
                           calc_long_dipole=False)
wake = wf_dict['dipole']['wake_potential']

#wake = wf_dict_s1['dipole']['wake_potential']
#wake_tt = wf_dict_s1['input']['charge_xx']/c

wake_energy = np.interp(beam_before_s1[4, :], wake_tt, wake)
delta_xp = wake_energy / tracker.energy_eV