def bunching(p_array, lambda_mod, smooth_sigma=None): """ Function calculates bunching factor for wavelength lambda_mod $b(\lambda) = \frac{1}{N_0}\left| \langle e^{- i\frac{ 2 \pi}{\lambda} s} N(s)\rangle \right|$ :param p_array: ParticleArray :param lambda_mod: wavelength :param smooth_sigma: smoothing parameter :return: bunching factor """ if smooth_sigma is None: smooth_sigma = min(np.std(p_array.tau()) * 0.01, lambda_mod * 0.1) B = s_to_cur(p_array.tau(), sigma=smooth_sigma, q0=np.sum(p_array.q_array), v=speed_of_light) b = np.abs( simps( B[:, 1] / speed_of_light * np.exp(-1j * 2 * np.pi / lambda_mod * B[:, 0]), B[:, 0])) / np.sum( p_array.q_array) return b
def plot_wake(self, p_array, lam_K1, itr_ra, s1, st): """ Method to plot CSR wakes on each step and save pictures in the working folder. Might be time-consuming. :param p_array: :param lam_K1: :param itr_ra: :param s1: :param st: :return: """ self.napply += 1 fig = self.plt.figure(figsize=(10, 8)) ax1 = self.plt.subplot(311) ax1.plot(self.csr_traj[0, :], self.csr_traj[1, :] * 1000, "r", self.csr_traj[0, itr_ra], self.csr_traj[1, itr_ra] * 1000, "bo") self.plt.ylabel("X [mm]") ax2 = self.plt.subplot(312) # # CSR wake in keV/m - preferable and not depend on step # ax2.plot(np.linspace(s1, s1+st*len(lam_K1), len(lam_K1))*1000, lam_K1/delta_s/1000.) # plt.ylabel("dE, keV/m") # CSR wake in keV - amplitude changes with step ax2.plot( np.linspace(s1, s1 + st * len(lam_K1), len(lam_K1)) * 1000, lam_K1 * 1e-3) self.plt.setp(ax2.get_xticklabels(), visible=False) self.plt.ylim((-50, 50)) self.plt.ylabel("Wake [keV]") # ax3 = self.plt.subplot(413) # n_points = len(lam_K1) # #wake = np.interp(np.linspace(s1, s1+st*n_points, n_points), np.linspace(s1, s1+st*len(lam_K1), len(lam_K1)), lam_K1) # self.total_wake += lam_K1 # #plt.xlim(s1 * 1000, (s1 + st * len(lam_K1)) * 1000) # ax3.plot(np.linspace(s1, s1+st*n_points, n_points)*1000, self.total_wake*1e-6) # self.plt.ylabel("Total Wake [MeV]") # self.plt.setp(ax3.get_xticklabels(), visible=False) # self.plt.ylim((-10, 10)) ax3 = self.plt.subplot(313, sharex=ax2) self.B = s_to_cur(p_array.tau(), sigma=np.std(p_array.tau()) * 0.05, q0=np.sum(p_array.q_array), v=speed_of_light) ax3.plot(-self.B[:, 0] * 1000, self.B[:, 1], lw=2) ax3.set_ylabel("I [A]") ax3.set_xlabel("s [mm]") self.plt.subplots_adjust(hspace=0.2) dig = str(self.napply) name = "0" * (4 - len(dig)) + dig self.plt.savefig(name + '.png')
def apply(self, p_array, dz): """ wakes in V/pC :param p_array: :param dz: :return: """ if dz < 1e-10: logger.debug(" LSC applied, dz < 1e-10, dz = " + str(dz)) return logger.debug(" LSC applied, dz =" + str(dz)) mean_b = np.mean(p_array.tau()) sigma_tau = np.std(p_array.tau()) slice_min = mean_b - sigma_tau / 2.5 slice_max = mean_b + sigma_tau / 2.5 indx = np.where( np.logical_and(np.greater_equal(p_array.tau(), slice_min), np.less(p_array.tau(), slice_max))) if self.step_profile: rb = min( np.max(p_array.x()[indx]) - np.min(p_array.x()[indx]), np.max(p_array.y()[indx]) - np.min(p_array.y()[indx])) / 2 sigma = rb else: sigma = (np.std(p_array.x()[indx]) + np.std(p_array.y()[indx])) / 2. # sigma = min(np.std(p_array.x()[indx]), np.std(p_array.y()[indx])) q = np.sum(p_array.q_array) gamma = p_array.E / m_e_GeV v = np.sqrt(1 - 1 / gamma**2) * speed_of_light B = s_to_cur(p_array.tau(), sigma_tau * self.smooth_param, q, v) bunch = B[:, 1] / (q * speed_of_light) x = B[:, 0] W = -self.wake_lsc(x, bunch, gamma, sigma, dz) * q indx = np.argsort(p_array.tau(), kind="quicksort") tau_sort = p_array.tau()[indx] dE = np.interp(tau_sort, x, W) pc_ref = np.sqrt(p_array.E**2 / m_e_GeV**2 - 1) * m_e_GeV delta_p = dE * 1e-9 / pc_ref p_array.rparticles[5][indx] += delta_p
def slice_bunching(tau, charge, lambda_mod, smooth_sigma=None): """ Function calculates bunching factor for wavelength lambda_mod $b(\lambda) = \frac{1}{N_0}\left| \langle e^{- i\frac{ 2 \pi}{\lambda} s} N(s)\rangle \right|$ :param p_array: ParticleArray :param lambda_mod: wavelength :param smooth_sigma: smoothing parameter :return: bunching factor """ if smooth_sigma is None: smooth_sigma = lambda_mod / 10. B = s_to_cur(tau, sigma=smooth_sigma, q0=charge, v=speed_of_light) b = np.abs( simps( B[:, 1] / speed_of_light * np.exp(-1j * 2 * np.pi / lambda_mod * B[:, 0]), B[:, 0])) / charge return b
def apply(self, p_array, dz): """ wakes in V/pC :param p_array: :param dz: :return: """ if dz < 1e-10: logger.debug(" LSC applied, dz < 1e-10, dz = " + str(dz)) return logger.debug(" LSC applied, dz =" + str(dz)) mean_b = np.mean(p_array.tau()) sigma_tau = np.std(p_array.tau()) slice_min = mean_b - sigma_tau / 2.5 slice_max = mean_b + sigma_tau / 2.5 indx = np.where(np.logical_and(np.greater_equal(p_array.tau(), slice_min), np.less(p_array.tau(), slice_max))) if self.step_profile: rb = min(np.max(p_array.x()[indx]) - np.min(p_array.x()[indx]), np.max(p_array.y()[indx]) - np.min(p_array.y()[indx]))/2 sigma = rb else: sigma = (np.std(p_array.x()[indx]) + np.std(p_array.y()[indx]))/2. # sigma = min(np.std(p_array.x()[indx]), np.std(p_array.y()[indx])) q = np.sum(p_array.q_array) gamma = p_array.E / m_e_GeV v = np.sqrt(1 - 1 / gamma ** 2) * speed_of_light B = s_to_cur(p_array.tau(), sigma_tau * self.smooth_param, q, v) bunch = B[:, 1] / (q * speed_of_light) x = B[:, 0] W = - self.wake_lsc(x, bunch, gamma, sigma, dz) * q indx = np.argsort(p_array.tau(), kind="quicksort") tau_sort = p_array.tau()[indx] dE = np.interp(tau_sort, x, W) pc_ref = np.sqrt(p_array.E ** 2 / m_e_GeV ** 2 - 1) * m_e_GeV delta_p = dE * 1e-9 / pc_ref p_array.rparticles[5][indx] += delta_p #fig, axs = plt.subplots(3, 1, sharex=True) ##ax = plt.subplot(211) #axs[0].plot(-B[:, 0]*1e3, B[:, 1]) #axs[0].set_ylabel("I, [A]") #axs[1].plot(-p_array.tau()[::10]*1e3, p_array.p()[::10], ".") #axs[1].set_ylim(-0.01, 0.01) #axs[1].set_ylabel("dE/E") ##plt.subplot(212) #axs[2].plot(-x*1e3, W, label="s = "+str(p_array.s) + " m") #axs[2].set_ylabel("W, [V]") #axs[2].set_xlabel("s, [mm]") #plt.legend() #plt.show() ##plt.ylim(-0.5e6, 0.5e6) #dig = str(self.napply) #name = "0"*(4 - len(dig)) + dig #plt.savefig(name) #plt.clf() #self.napply += 1 ##plt.show()