harmonic_numbers, voltage_program, phi_offset) # DEFINE BEAM------------------------------------------------------------------ beam = Beam(general_params, n_macroparticles, n_particles) # DEFINE TRACKER--------------------------------------------------------------- longitudinal_tracker = RingAndRFSection(RF_sct_par, beam) full_tracker = FullRingAndRF([longitudinal_tracker]) # DEFINE SLICES---------------------------------------------------------------- number_slices = 500 slice_beam = Slices(RF_sct_par, beam, number_slices, cut_left=0., cut_right=bucket_length) # Single RF ------------------------------------------------------------------- matched_from_distribution_density(beam, full_tracker, distribution_options, main_harmonic_option='lowest_freq') slice_beam.track() [sync_freq_distribution_left, sync_freq_distribution_right], \ [emittance_array_left, emittance_array_right], \ [delta_time_left, delta_time_right], \ particleDistributionFreq, synchronous_time = synchrotron_frequency_distribution(beam, full_tracker)
def X0_from_bunch_length(bunch_length, bunch_length_fit, X_grid, sorted_X_dE0, n_points_grid, time_potential_low_res, distribution_function_, distribution_type, distribution_exponent, beam, full_ring_and_RF): ''' Function to find the corresponding H0 or J0 for a given bunch length. Used by matched_from_distribution_function() ''' tau = 0.0 # Initial values for iteration X_low = sorted_X_dE0[0] X_hi = sorted_X_dE0[-1] X_min = sorted_X_dE0[0] X_max = sorted_X_dE0[-1] X_accuracy = sorted_X_dE0[1] - sorted_X_dE0[0] / 2.0 bin_size = (time_potential_low_res[1] - time_potential_low_res[0]) # Iteration to find H0/J0 from the bunch length while np.abs(bunch_length-tau) > bin_size: # Takes middle point of the interval [X_low,X_hi] X0 = 0.5 * (X_low + X_hi) if bunch_length_fit is 'full': bunchIndices = np.where(np.sum(X_grid<=X0, axis=0))[0] tau = (time_potential_low_res[bunchIndices][-1] - time_potential_low_res[bunchIndices][0]) else: # Calculating the line density for the parameter X0 density_grid = distribution_function_(X_grid, distribution_type, X0, distribution_exponent) density_grid = density_grid / np.sum(density_grid) line_density_ = np.sum(density_grid, axis=0) # Calculating the bunch length of that line density if (line_density_ > 0).any(): tau = 4.0 * np.sqrt(np.sum((time_potential_low_res - np.sum(line_density_ * time_potential_low_res) / np.sum(line_density_))**2 * line_density_) / np.sum(line_density_)) if bunch_length_fit!=None: slices = Slices( full_ring_and_RF.RingAndRFSection_list[0].rf_params, beam, n_points_grid, cut_left=time_potential_low_res[0] - 0.5*bin_size , cut_right=time_potential_low_res[-1] + 0.5*bin_size) slices.n_macroparticles = line_density_ if bunch_length_fit is 'gauss': slices.bl_gauss = tau slices.bp_gauss = np.sum(line_density_ * time_potential_low_res) / np.sum(line_density_) slices.gaussian_fit() tau = slices.bl_gauss elif bunch_length_fit is 'fwhm': slices.fwhm() tau = slices.bl_fwhm # Update of the interval for the next iteration if tau >= bunch_length: X_hi = X0 else: X_low = X0 if (X_max - X0) < X_accuracy: print('WARNING: The bucket is too small to have the ' + 'desired bunch length! Input is %.2e, the ' + 'generation gave %.2e, the error is %.2e' %(bunch_length, tau, bunch_length-tau)) break if (X0-X_min) < X_accuracy: print('WARNING: The desired bunch length is too small ' + 'to be generated accurately!') # return 0.5 * (X_low + X_hi) return X0
# Define beam and distribution beam = Beam(general_params, N_p, N_b) # Define RF station parameters and corresponding tracker rf_params = RFSectionParameters(general_params, 1, h, V, dphi) long_tracker = RingAndRFSection(rf_params, beam) longitudinal_bigaussian(general_params, rf_params, beam, tau_0 / 4, reinsertion='on', seed=1) # Need slices for the Gaussian fit slice_beam = Slices(rf_params, beam, 100, fit_option='gaussian') # Define what to save in file bunchmonitor = BunchMonitor(general_params, rf_params, beam, '../output_files/TC1_output_data', Slices=slice_beam) format_options = {'dirname': '../output_files/TC1_fig'} plots = Plot(general_params, rf_params, beam, dt_plt, N_t, 0,
harmonic_numbers, voltage_program, phi_offset) beam = Beam(general_params, n_macroparticles, n_particles) ring_RF_section = RingAndRFSection(RF_sct_par, beam) bucket_length = 2.0 * np.pi / RF_sct_par.omega_RF[0,0] # DEFINE BEAM------------------------------------------------------------------ longitudinal_bigaussian(general_params, RF_sct_par, beam, sigma_dt, seed=1) # DEFINE SLICES---------------------------------------------------------------- number_slices = 200 slice_beam = Slices(RF_sct_par, beam, number_slices, cut_left=0, cut_right=bucket_length) # Overwriting the slices by a Gaussian profile (no slicing noise) slice_beam.n_macroparticles = (n_macroparticles * slice_beam.bin_size / (sigma_dt * np.sqrt(2.0 * np.pi)) * np.exp(-0.5 * (slice_beam.bin_centers - bucket_length/2.0)**2.0 / sigma_dt**2.0)) # LOAD IMPEDANCE TABLES-------------------------------------------------------- R_S = 5e3 frequency_R = 10e6 Q = 10 resonator = Resonators(R_S, frequency_R, Q) # INDUCED VOLTAGE FROM IMPEDANCE-----------------------------------------------