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
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():
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,
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,
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
#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