示例#1
0
    def run_simple(self):

        self.ring = Ring(self.C, self.alpha_0, self.Ek, Proton(), self.N_t,
                         synchronous_data_type='kinetic energy',
                         alpha_1=None, alpha_2=None)

        self.beam = Beam(self.ring, self.N_p, self.N_b)

        self.rf = RFStation(self.ring, 1, 0, np.pi)

        original_distribution_dt = np.zeros(self.beam.n_macroparticles)
        original_distribution_dE = np.linspace(
            -0.1*self.beam.energy,
            0.1*self.beam.energy,
            self.beam.n_macroparticles)

        self.beam.dt[:] = np.array(original_distribution_dt)
        self.beam.dE[:] = np.array(original_distribution_dE)

        self.long_tracker = RingAndRFTracker(
            self.rf, self.beam, solver='simple')

        for i in range(self.ring.n_turns):
            self.long_tracker.track()

        original_distribution_dt += self.ring.n_turns * linear_drift(
            original_distribution_dE, self.ring.eta_0[0, 0],
            self.ring.beta[0, 0], self.ring.energy[0, 0], self.ring.t_rev[0])

        return self.beam.dt, original_distribution_dt, original_distribution_dE
示例#2
0
    def setUp(self):
        self.general_params = Ring(np.ones(self.n_sections) * self.C/self.n_sections,
                                   np.tile(self.momentum_compaction,
                                           (1, self.n_sections)).T,
                                   np.tile(self.sync_momentum,
                                           (self.n_sections, self.n_turns+1)),
                                   self.particle_type, self.n_turns, n_sections=self.n_sections)
        self.RF_sct_par = []
        self.RF_sct_par_cpp = []
        for i in np.arange(self.n_sections)+1:
            self.RF_sct_par.append(RFStation(self.general_params,
                                             [self.harmonic_numbers], [
                                                 self.voltage_program/self.n_sections],
                                             [self.phi_offset], self.n_rf_systems, section_index=i))
            self.RF_sct_par_cpp.append(RFStation(self.general_params,
                                                 [self.harmonic_numbers], [
                                                     self.voltage_program/self.n_sections],
                                                 [self.phi_offset], self.n_rf_systems, section_index=i))

        # DEFINE BEAM------------------------------------------------------------------

        self.beam = Beam(self.general_params,
                         self.n_macroparticles, self.n_particles)
        self.beam_cpp = Beam(self.general_params,
                             self.n_macroparticles, self.n_particles)

        # DEFINE SLICES----------------------------------------------------------------

        number_slices = 500

        cut_options = CutOptions(
            cut_left=0., cut_right=self.bucket_length, n_slices=number_slices)
        self.slice_beam = Profile(self.beam, CutOptions=cut_options)

        self.slice_beam_cpp = Profile(self.beam_cpp, CutOptions=cut_options)

        # DEFINE TRACKER---------------------------------------------------------------
        self.longitudinal_tracker = []
        self.longitudinal_tracker_cpp = []
        for i in range(self.n_sections):
            self.longitudinal_tracker.append(RingAndRFTracker(
                self.RF_sct_par[i], self.beam, Profile=self.slice_beam))
            self.longitudinal_tracker_cpp.append(RingAndRFTracker(
                self.RF_sct_par_cpp[i], self.beam_cpp, Profile=self.slice_beam_cpp))

        full_tracker = FullRingAndRF(self.longitudinal_tracker)
        full_tracker_cpp = FullRingAndRF(self.longitudinal_tracker_cpp)

        # BEAM GENERATION--------------------------------------------------------------

        matched_from_distribution_function(self.beam, full_tracker, emittance=self.emittance,
                                           distribution_type=self.distribution_type,
                                           distribution_variable=self.distribution_variable, seed=1000)
        
        matched_from_distribution_function(self.beam_cpp, full_tracker_cpp, emittance=self.emittance,
                                           distribution_type=self.distribution_type,
                                           distribution_variable=self.distribution_variable, seed=1000)

        self.slice_beam.track()
        self.slice_beam_cpp.track()
示例#3
0
class TestRfVoltageCalc(unittest.TestCase):
    # Simulation parameters -------------------------------------------------------
    # Bunch parameters
    N_b = 1e9           # Intensity
    N_p = 50000         # Macro-particles
    tau_0 = 0.4e-9          # Initial bunch length, 4 sigma [s]
    # Machine and RF parameters
    C = 26658.883        # Machine circumference [m]
    p_i = 450e9         # Synchronous momentum [eV/c]
    p_f = 460.005e9      # Synchronous momentum, final
    h = 35640            # Harmonic number
    V = 6e6                # RF voltage [V]
    dphi = 0             # Phase modulation/offset
    gamma_t = 55.759505  # Transition gamma
    alpha = 1./gamma_t/gamma_t        # First order mom. comp. factor
    # Tracking details
    N_t = 2000           # Number of turns to track

    # Run before every test
    def setUp(self):
        self.ring = Ring(self.C, self.alpha, np.linspace(
            self.p_i, self.p_f, self.N_t + 1), Proton(), self.N_t)
        self.beam = Beam(self.ring, self.N_p, self.N_b)
        self.rf = RFStation(
            self.ring, [self.h], self.V * np.linspace(1, 1.1, self.N_t+1), [self.dphi])
        bigaussian(self.ring, self.rf, self.beam,
                   self.tau_0/4, reinsertion=True, seed=1)
        self.profile = Profile(self.beam, CutOptions(n_slices=100, cut_left=0, cut_right=self.rf.t_rf[0, 0]),
                               FitOptions(fit_option='gaussian'))
        self.long_tracker = RingAndRFTracker(
            self.rf, self.beam, Profile=self.profile)

    # Run after every test

    def tearDown(self):
        pass

    def test_rf_voltage_calc_1(self):
        self.long_tracker.rf_voltage_calculation()
        orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(
            self.long_tracker.rf_voltage, orig_rf_voltage, decimal=8)

    def test_rf_voltage_calc_2(self):
        for i in range(100):
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(
            self.long_tracker.rf_voltage, orig_rf_voltage, decimal=8)

    def test_rf_voltage_calc_3(self):
        for i in range(100):
            self.profile.track()
            self.long_tracker.track()
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(
            self.long_tracker.rf_voltage, orig_rf_voltage, decimal=8)
示例#4
0
    def test_losses_energy_cut(self):

        longitudinal_tracker = RingAndRFTracker(self.rf_params, self.beam)
        full_tracker = FullRingAndRF([longitudinal_tracker])

        try:
            matched_from_distribution_function(self.beam,
                                               full_tracker,
                                               distribution_exponent=1.5,
                                               distribution_type='binomial',
                                               bunch_length=1.65e-9,
                                               bunch_length_fit='fwhm',
                                               distribution_variable='Hamiltonian')
        except TypeError as te:
            self.skipTest("Skipped because of known bug in deepcopy. Exception message %s"
                          % str(te))

        self.beam.losses_energy_cut(-3e8, 3e8)
        self.assertEqual(len(self.beam.id[self.beam.id == 0]), 0,
                         msg='Beam: Failed losses_energy_cut, first')

        self.beam.dE += 10e8
        self.beam.losses_energy_cut(-3e8, 3e8)
        self.assertEqual(len(self.beam.id[self.beam.id == 0]),
                         self.beam.n_macroparticles,
                         msg='Beam: Failed losses_energy_cut, second')
示例#5
0
    def setUp(self):

        initial_time = 0
        final_time = 1E-3

        # Machine and RF parameters
        radius = 25
        gamma_transition = 4.4  # [1]
        C = 2 * np.pi * radius  # [m]
        momentum_compaction = 1 / gamma_transition**2  # [1]
        particle_type = 'proton'

        self.ring = Ring(C, momentum_compaction, \
                                   ([0, 1E-3], [3.13E8, 3.13E8]), Proton())

        self.rf_params = RFStation(self.ring, [1], [1E3], [np.pi], 1)
        self.beam = Beam(self.ring, 1, 0)
        self.profile = Profile(self.beam)

        self.long_tracker = RingAndRFTracker(self.rf_params, self.beam)
        self.full_ring = FullRingAndRF([self.long_tracker])

        self.n_turns = self.ring.n_turns

        self.map_ = [self.full_ring.track, self.profile.track]

        self.trackIt = TrackIteration(self.map_)
示例#6
0
    def test_exact_order1and2_vs_expectation(self):

        self.ring = Ring(self.C,
                         self.alpha_0,
                         self.Ek,
                         Proton(),
                         self.N_t,
                         synchronous_data_type='kinetic energy',
                         alpha_1=self.alpha_1,
                         alpha_2=self.alpha_2)

        self.beam = Beam(self.ring, self.N_p, self.N_b)

        self.rf = RFStation(self.ring, 1, 0, np.pi)

        original_distribution_dt = np.zeros(self.beam.n_macroparticles)
        original_distribution_dE = np.linspace(-0.1 * self.beam.energy,
                                               0.1 * self.beam.energy,
                                               self.beam.n_macroparticles)

        self.beam.dt[:] = np.array(original_distribution_dt)
        self.beam.dE[:] = np.array(original_distribution_dE)

        self.long_tracker = RingAndRFTracker(self.rf,
                                             self.beam,
                                             solver='exact')

        # Forcing usage of legacy
        self.long_tracker.solver = 'exact'
        self.long_tracker.solver = self.long_tracker.solver.encode(
            encoding='utf_8')

        for i in range(self.ring.n_turns):
            self.long_tracker.track()

        original_distribution_dt += self.ring.n_turns * expected_drift(
            original_distribution_dE, self.ring.alpha_0[0, 0],
            self.ring.alpha_1[0, 0], self.ring.alpha_2[0, 0],
            self.ring.energy[0, 0], self.ring.t_rev[0],
            self.ring.ring_circumference, self.ring.Particle.mass)

        np.testing.assert_allclose(self.beam.dt,
                                   original_distribution_dt,
                                   rtol=relative_tolerance,
                                   atol=absolute_tolerance)
示例#7
0
 def setUp(self):
     self.ring = Ring(self.C, self.alpha,
                      np.linspace(self.p_i, self.p_f, self.N_t + 1),
                      Proton(), self.N_t)
     self.beam = Beam(self.ring, self.N_p, self.N_b)
     self.rf = RFStation(self.ring, [self.h],
                         self.V * np.linspace(1, 1.1, self.N_t + 1),
                         [self.dphi])
     bigaussian(self.ring,
                self.rf,
                self.beam,
                self.tau_0 / 4,
                reinsertion=True,
                seed=1)
     self.profile = Profile(
         self.beam,
         CutOptions(n_slices=100, cut_left=0, cut_right=self.rf.t_rf[0, 0]),
         FitOptions(fit_option='gaussian'))
     self.long_tracker = RingAndRFTracker(self.rf,
                                          self.beam,
                                          Profile=self.profile)
示例#8
0
 def setUp(self):
     self.ring = Ring(self.C, self.alpha, np.linspace(
         self.p_i, self.p_f, self.N_t + 1), Proton(), self.N_t)
     self.beam = Beam(self.ring, self.N_p, self.N_b)
     self.rf = RFStation(
         self.ring, [self.h], self.V * np.linspace(1, 1.1, self.N_t+1), [self.dphi])
     bigaussian(self.ring, self.rf, self.beam,
                self.tau_0/4, reinsertion=True, seed=1)
     self.profile = Profile(self.beam, CutOptions(n_slices=100, cut_left=0, cut_right=self.rf.t_rf[0, 0]),
                            FitOptions(fit_option='gaussian'))
     self.long_tracker = RingAndRFTracker(
         self.rf, self.beam, Profile=self.profile)
示例#9
0
    def test_phi_modulation(self):

        timebase = np.linspace(0, 0.2, 10000)
        freq = 2E3
        amp = np.pi
        offset = 0
        harmonic = self.h
        phiMod = PMod(timebase, freq, amp, offset, harmonic)

        self.rf = RFStation(
            self.ring, [self.h], self.V * np.linspace(1, 1.1, self.N_t+1), \
            [self.dphi], phi_modulation = phiMod)

        self.long_tracker = RingAndRFTracker(self.rf,
                                             self.beam,
                                             Profile=self.profile)

        for i in range(self.N_t):
            self.long_tracker.track()
            self.assertEqual( \
                self.long_tracker.phi_rf[:, self.long_tracker.counter[0]-1], \
                self.rf.phi_modulation[0][0][i], msg = \
                """Phi modulation not added correctly in tracker""")
示例#10
0
    def run_exact_order1and2(self):

        self.ring = Ring(self.C, self.alpha_0, self.Ek, Proton(), self.N_t,
                         synchronous_data_type='kinetic energy',
                         alpha_1=self.alpha_1, alpha_2=self.alpha_2)

        self.beam = Beam(self.ring, self.N_p, self.N_b)

        self.rf = RFStation(self.ring, 1, 0, np.pi)

        original_distribution_dt = np.zeros(self.beam.n_macroparticles)
        original_distribution_dE = np.linspace(
            -0.1*self.beam.energy,
            0.1*self.beam.energy,
            self.beam.n_macroparticles)

        self.beam.dt[:] = np.array(original_distribution_dt)
        self.beam.dE[:] = np.array(original_distribution_dE)

        self.long_tracker = RingAndRFTracker(
            self.rf, self.beam, solver='exact')

        # Forcing usage of legacy
        self.long_tracker.solver = 'exact'
        self.long_tracker.solver = self.long_tracker.solver.encode(
            encoding='utf_8')

        for i in range(self.ring.n_turns):
            self.long_tracker.track()

        original_distribution_dt += self.ring.n_turns * exact_drift(
            original_distribution_dE, self.ring.alpha_0[0, 0],
            self.ring.alpha_1[0, 0], self.ring.alpha_2[0, 0],
            self.ring.beta[0, 0], self.ring.energy[0, 0], self.ring.t_rev[0])

        return self.beam.dt, original_distribution_dt, original_distribution_dE
示例#11
0
        gain2nd = 5e9
        PLdict['machine'] = 'SPS_RL'
        PLdict['RL_gain'] = gain2nd
    elif PL_2ndLoop == 'F_Loop':
        gain2nd = 0.9e-1
        PLdict['machine'] = 'SPS_F'
        PLdict['FL_gain'] = gain2nd
    phaseLoop = BeamFeedback(ring, rf_station, profile, PLdict)
    beamPosPrev = t_batch_begin + 0.5 * t_rf

# SPS --- Tracker Setup ----------------------------------------

mpiprint('Setting up tracker')
tracker = RingAndRFTracker(rf_station,
                           beam,
                           Profile=profile,
                           TotalInducedVoltage=inducedVoltage,
                           interpolation=True)
fulltracker = FullRingAndRF([tracker])

mpiprint('Creating SPS bunch from PS bunch')
# create 72 bunches from PS bunch

beginIndex = 0
endIndex = 0
PS_beam = Beam(ring, n_particles, 0.0)
PS_n_bunches = 1
for copy in range(n_bunches):
    # create binomial distribution;
    # use different seed for different bunches to avoid cloned bunches
    matched_from_distribution_function(PS_beam,
# Simulation setup ------------------------------------------------------------
print("Setting up the simulation...")
print("")


# Define general parameters containing data for both RF stations
general_params = Ring([0.3*C, 0.7*C], [[alpha], [alpha]], 
                                   [p_s*np.ones(N_t+1), p_s*np.ones(N_t+1)], 
                                   Proton(), N_t, n_sections = 2)


# Define RF station parameters and corresponding tracker
beam = Beam(general_params, N_p, N_b)
rf_params_1 = RFStation(general_params, [h], [V1], [dphi],
                                  section_index=1)
long_tracker_1 = RingAndRFTracker(rf_params_1, beam)

rf_params_2 = RFStation(general_params, [h], [V2], [dphi],
                                  section_index=2)
long_tracker_2 = RingAndRFTracker(rf_params_2, beam)

# Define full voltage over one turn and a corresponding "overall" set of 
#parameters, which is used for the separatrix (in plotting and losses)
Vtot = total_voltage([rf_params_1, rf_params_2])
rf_params_tot = RFStation(general_params, [h], [Vtot], [dphi])
beam_dummy = Beam(general_params, 1, N_b)
long_tracker_tot = RingAndRFTracker(rf_params_tot, beam_dummy)

print("General and RF parameters set...")

示例#13
0
                       fmin_s0=0,
                       fmax_s0=1.1,
                       seed1=1234,
                       seed2=7564,
                       initial_amplitude=1.11100000e-07,
                       folder_plots=this_directory +
                       '../output_files/EX_03_fig')
RFnoise.generate()
rf_params.phi_noise = np.array(RFnoise.dphi, ndmin=2)

print("   Sigma of RF noise is %.4e" % np.std(RFnoise.dphi))
print("   Time step of RF noise is %.4e" % RFnoise.t[1])
print("")

beam = Beam(general_params, N_p, N_b)
long_tracker = RingAndRFTracker(rf_params, beam)

print("General and RF parameters set...")

# Define beam and distribution

# Generate new distribution
bigaussian(general_params,
           rf_params,
           beam,
           tau_0 / 4,
           reinsertion=True,
           seed=1)

print("Beam set and distribution generated...")
示例#14
0
                      [phi_offset_1], n_rf_systems)

my_beam = Beam(general_params, n_macroparticles, n_particles)


cut_options = CutOptions(cut_left= 0, cut_right=2*np.pi, n_slices=200, 
                         RFSectionParameters=rf_params, cuts_unit = 'rad')
slices_ring = Profile(my_beam, cut_options)

#Phase loop
configuration = {'machine': 'PSB', 'PL_gain': 1./25.e-6, 'period': 10.e-6}
phase_loop = BeamFeedback(general_params, rf_params, slices_ring, configuration)


#Long tracker
long_tracker = RingAndRFTracker(rf_params, my_beam, periodicity='Off',
                                BeamFeedback=phase_loop)

full_ring = FullRingAndRF([long_tracker])


distribution_type = 'gaussian'
bunch_length = 200.0e-9
distribution_variable = 'Action'

matched_from_distribution_function(my_beam, full_ring, 
                                   bunch_length=bunch_length,
                                   distribution_type=distribution_type, 
                                   distribution_variable=distribution_variable, seed=1222)
                                   
my_beam.dE += 90.0e3
slices_ring.track()
示例#15
0
class TestRfVoltageCalcWCavityFB(unittest.TestCase):
    # Simulation parameters -------------------------------------------------------
    # Bunch parameters
    N_b = 1e9  # Intensity
    N_p = 50000  # Macro-particles
    tau_0 = 0.4e-9  # Initial bunch length, 4 sigma [s]
    # Machine and RF parameters
    C = 26658.883  # Machine circumference [m]
    p_i = 450e9  # Synchronous momentum [eV/c]
    p_f = 460.005e9  # Synchronous momentum, final
    h = 35640  # Harmonic number
    V = 6e6  # RF voltage [V]
    dphi = 0  # Phase modulation/offset
    gamma_t = 55.759505  # Transition gamma
    alpha = 1. / gamma_t / gamma_t  # First order mom. comp. factor
    # Tracking details
    N_t = 2000  # Number of turns to track

    # Run before every test
    def setUp(self):
        self.ring = Ring(self.C, self.alpha,
                         np.linspace(self.p_i, self.p_f, self.N_t + 1),
                         Proton(), self.N_t)
        self.beam = Beam(self.ring, self.N_p, self.N_b)
        self.rf = RFStation(self.ring, [self.h],
                            self.V * np.linspace(1, 1.1, self.N_t + 1),
                            [self.dphi])
        bigaussian(self.ring,
                   self.rf,
                   self.beam,
                   self.tau_0 / 4,
                   reinsertion=True,
                   seed=1)
        self.profile = Profile(
            self.beam,
            CutOptions(n_slices=100, cut_left=0, cut_right=self.rf.t_rf[0, 0]),
            FitOptions(fit_option='gaussian'))

        self.long_tracker = RingAndRFTracker(self.rf,
                                             self.beam,
                                             Profile=self.profile)

    # Run after every test

    def tearDown(self):
        pass

    def test_rf_voltage_calc_1(self):
        self.long_tracker.cavityFB = CavityFB(1.1, 1.2)
        self.long_tracker.rf_voltage_calculation()
        orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_rf_voltage_calc_2(self):
        self.long_tracker.cavityFB = CavityFB(1.1, 1.2)
        for i in range(100):
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_rf_voltage_calc_3(self):
        self.long_tracker.cavityFB = CavityFB(1.1, 1.2)
        for i in range(100):
            self.profile.track()
            self.long_tracker.track()
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_rf_voltage_calc_4(self):
        self.long_tracker.cavityFB = CavityFB(
            np.linspace(1, 1.5, self.profile.n_slices),
            np.linspace(0.1, 0.5, self.profile.n_slices))
        self.long_tracker.rf_voltage_calculation()
        orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_rf_voltage_calc_5(self):
        self.long_tracker.cavityFB = CavityFB(
            np.linspace(1, 1.5, self.profile.n_slices),
            np.linspace(0.1, 0.5, self.profile.n_slices))
        for i in range(100):
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_rf_voltage_calc_6(self):
        self.long_tracker.cavityFB = CavityFB(
            np.linspace(1, 1.5, self.profile.n_slices),
            np.linspace(0.1, 0.5, self.profile.n_slices))
        for i in range(100):
            self.profile.track()
            self.long_tracker.track()
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_phi_modulation(self):

        timebase = np.linspace(0, 0.2, 10000)
        freq = 2E3
        amp = np.pi
        offset = 0
        harmonic = self.h
        phiMod = PMod(timebase, freq, amp, offset, harmonic)

        self.rf = RFStation(
            self.ring, [self.h], self.V * np.linspace(1, 1.1, self.N_t+1), \
            [self.dphi], phi_modulation = phiMod)

        self.long_tracker = RingAndRFTracker(self.rf,
                                             self.beam,
                                             Profile=self.profile)

        for i in range(self.N_t):
            self.long_tracker.track()
            self.assertEqual( \
                self.long_tracker.phi_rf[:, self.long_tracker.counter[0]-1], \
                self.rf.phi_modulation[0][0][i], msg = \
                """Phi modulation not added correctly in tracker""")
示例#16
0
ring = Ring(C, alpha, np.linspace(p_i, p_f, n_turns + 1), Proton(), n_turns)

# Define beam and distribution
beam = Beam(ring, n_particles, N_b)

# Define RF station parameters and corresponding tracker
rf = RFStation(ring, [h], [V], [dphi])

bigaussian(ring, rf, beam, tau_0 / 4, reinsertion=True, seed=seed)

# Need slices for the Gaussian fit
# TODO add the gaussian fit
profile = Profile(beam, CutOptions(n_slices=n_slices))
# FitOptions(fit_option='gaussian'))

long_tracker = RingAndRFTracker(rf, beam)

# beam.split_random()
beam.split()

if args['monitor'] > 0 and worker.isMaster:
    if args.get('monitorfile', None):
        filename = args['monitorfile']
    else:
        filename = 'monitorfiles/ex01-t{}-p{}-b{}-sl{}-approx{}-prec{}-r{}-m{}-se{}-w{}'.format(
            n_iterations, n_particles, n_bunches, n_slices, approx,
            args['precision'], n_turns_reduce, args['monitor'], seed,
            worker.workers)
    slicesMonitor = SlicesMonitor(filename=filename,
                                  n_turns=np.ceil(n_iterations /
                                                  args['monitor']),
示例#17
0
beam = Beam(general_params, n_macroparticles, n_particles)

# DEFINE SLICES----------------------------------------------------------------

number_slices = 500

cut_options = CutOptions(cut_left=0.,
                         cut_right=bucket_length,
                         n_slices=number_slices)
slice_beam = Profile(beam, CutOptions=cut_options)

# DEFINE TRACKER---------------------------------------------------------------
longitudinal_tracker = []
for i in range(n_sections):
    longitudinal_tracker.append(
        RingAndRFTracker(RF_sct_par[i], beam, Profile=slice_beam))

full_tracker = FullRingAndRF(longitudinal_tracker)

# BEAM GENERATION--------------------------------------------------------------

matched_from_distribution_function(beam,
                                   full_tracker,
                                   emittance=emittance,
                                   distribution_type=distribution_type,
                                   distribution_variable=distribution_variable,
                                   seed=1000)

slice_beam.track()

# Synchrotron radiation objects without quantum excitation
示例#18
0
bucket_length = C / c / harmonic_numbers[0]

# DEFINE RING------------------------------------------------------------------

general_params = Ring(C, momentum_compaction, sync_momentum, Electron(),
                      n_turns)

RF_sct_par = RFStation(general_params, harmonic_numbers, voltage_program,
                       phi_offset, n_rf_systems)

# DEFINE BEAM------------------------------------------------------------------

beam = Beam(general_params, n_macroparticles, n_particles)

# DEFINE TRACKER---------------------------------------------------------------
longitudinal_tracker = RingAndRFTracker(RF_sct_par, beam)

full_tracker = FullRingAndRF([longitudinal_tracker])

# DEFINE SLICES----------------------------------------------------------------

n_slices = 500

n_bunches = 80
bunch_spacing = 1600  # buckets
filling_pattern = np.zeros(bunch_spacing * n_bunches)
filling_pattern[::bunch_spacing] = 1

# BEAM GENERATION--------------------------------------------------------------

matched_from_distribution_function(beam,
示例#19
0
# Cavities parameters
n_rf_systems = 1
harmonic_numbers = 1
voltage_program = 8e3  #[V]
phi_offset = np.pi

# DEFINE RING------------------------------------------------------------------

general_params = Ring(C, momentum_compaction, sync_momentum, Proton(), n_turns)

RF_sct_par = RFStation(general_params, [harmonic_numbers], [voltage_program],
                       [phi_offset], n_rf_systems)

my_beam = Beam(general_params, n_macroparticles, n_particles)

ring_RF_section = RingAndRFTracker(RF_sct_par, my_beam)

# DEFINE BEAM------------------------------------------------------------------
bigaussian(general_params, RF_sct_par, my_beam, sigma_dt, seed=1)

# DEFINE SLICES----------------------------------------------------------------
slice_beam = Profile(
    my_beam,
    CutOptions(cut_left=-5.72984173562e-7,
               cut_right=5.72984173562e-7,
               n_slices=100))

# MONITOR----------------------------------------------------------------------

bunchmonitor = BunchMonitor(general_params,
                            RF_sct_par,
示例#20
0
slices_ring = Profile(my_beam, cut_options)

#Phase loop
#configuration = {'machine': 'PSB', 'PL_gain': 0., 'RL_gain': [34.8,16391],
#                 'PL_period': 10.e-6, 'RL_period': 7}
configuration = {
    'machine': 'PSB',
    'PL_gain': 0,
    'RL_gain': [1.e7, 1.e11],
    'period': 10.e-6
}
phase_loop = BeamFeedback(general_params, rf_params, slices_ring,
                          configuration)

#Long tracker
long_tracker = RingAndRFTracker(rf_params, my_beam, BeamFeedback=phase_loop)

full_ring = FullRingAndRF([long_tracker])

distribution_type = 'gaussian'
bunch_length = 200.0e-9
distribution_variable = 'Action'

matched_from_distribution_function(my_beam,
                                   full_ring,
                                   bunch_length=bunch_length,
                                   distribution_type=distribution_type,
                                   distribution_variable=distribution_variable,
                                   seed=1223)

slices_ring.track()
示例#21
0
    def setUp(self):
        C = 2*np.pi*1100.009        # Ring circumference [m]
        gamma_t = 18.0              # Gamma at transition
        alpha = 1/gamma_t**2        # Momentum compaction factor
        p_s = 25.92e9               # Synchronous momentum at injection [eV]
        h = 4620                    # 200 MHz system harmonic
        phi = 0.                    # 200 MHz RF phase

        # With this setting, amplitude in the two four-section, five-section
        # cavities must converge, respectively, to
        # 2.0 MV = 4.5 MV * 4/18 * 2
        # 2.5 MV = 4.5 MV * 5/18 * 2
        V = 4.5e6                   # 200 MHz RF voltage

        N_t = 1                     # Number of turns to track

        self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t)
        self.rf = RFStation(self.ring, h, V, phi)

        N_m = 1e6                   # Number of macro-particles for tracking
        N_b = 72*1.0e11             # Bunch intensity [ppb]

        # Gaussian beam profile
        self.beam = Beam(self.ring, N_m, N_b)
        sigma = 1.0e-9
        bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234,
                   reinsertion=False)

        n_shift = 1550  # how many rf-buckets to shift beam
        self.beam.dt += n_shift * self.rf.t_rf[0,0]

        self.profile = Profile(
            self.beam, CutOptions=CutOptions(
                cut_left=(n_shift-1.5)*self.rf.t_rf[0,0],
                cut_right=(n_shift+2.5)*self.rf.t_rf[0,0],
                n_slices=4*64))
        self.profile.track()

        # Cavities
        l_cav = 43*0.374
        v_g = 0.0946
        tau = l_cav/(v_g*c)*(1 + v_g)
        f_cav = 200.222e6
        n_cav = 2   # factor 2 because of two four/five-sections cavities
        short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8,
                                           f_cav, 2*np.pi*tau)
        shortInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                 [short_cavity])
        l_cav = 54*0.374
        tau = l_cav/(v_g*c)*(1 + v_g)
        long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav,
                                          2*np.pi*tau)
        longInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                [long_cavity])
        self.induced_voltage = TotalInducedVoltage(
            self.beam, self.profile, [shortInducedVoltage, longInducedVoltage])
        self.induced_voltage.induced_voltage_sum()

        self.cavity_tracker = RingAndRFTracker(
            self.rf, self.beam, Profile=self.profile, interpolation=True,
            TotalInducedVoltage=self.induced_voltage)

        self.OTFB = SPSCavityFeedback(
            self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16,
            turns=50, Commissioning=CavityFeedbackCommissioning())

        self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam,
                                             Profile=self.profile,
                                             TotalInducedVoltage=None,
                                             CavityFeedback=self.OTFB,
                                             interpolation=True)
示例#22
0
class TestCavityFeedback(unittest.TestCase):

    def setUp(self):
        C = 2*np.pi*1100.009        # Ring circumference [m]
        gamma_t = 18.0              # Gamma at transition
        alpha = 1/gamma_t**2        # Momentum compaction factor
        p_s = 25.92e9               # Synchronous momentum at injection [eV]
        h = 4620                    # 200 MHz system harmonic
        phi = 0.                    # 200 MHz RF phase

        # With this setting, amplitude in the two four-section, five-section
        # cavities must converge, respectively, to
        # 2.0 MV = 4.5 MV * 4/18 * 2
        # 2.5 MV = 4.5 MV * 5/18 * 2
        V = 4.5e6                   # 200 MHz RF voltage

        N_t = 1                     # Number of turns to track

        self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t)
        self.rf = RFStation(self.ring, h, V, phi)

        N_m = 1e6                   # Number of macro-particles for tracking
        N_b = 72*1.0e11             # Bunch intensity [ppb]

        # Gaussian beam profile
        self.beam = Beam(self.ring, N_m, N_b)
        sigma = 1.0e-9
        bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234,
                   reinsertion=False)

        n_shift = 1550  # how many rf-buckets to shift beam
        self.beam.dt += n_shift * self.rf.t_rf[0,0]

        self.profile = Profile(
            self.beam, CutOptions=CutOptions(
                cut_left=(n_shift-1.5)*self.rf.t_rf[0,0],
                cut_right=(n_shift+2.5)*self.rf.t_rf[0,0],
                n_slices=4*64))
        self.profile.track()

        # Cavities
        l_cav = 43*0.374
        v_g = 0.0946
        tau = l_cav/(v_g*c)*(1 + v_g)
        f_cav = 200.222e6
        n_cav = 2   # factor 2 because of two four/five-sections cavities
        short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8,
                                           f_cav, 2*np.pi*tau)
        shortInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                 [short_cavity])
        l_cav = 54*0.374
        tau = l_cav/(v_g*c)*(1 + v_g)
        long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav,
                                          2*np.pi*tau)
        longInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                [long_cavity])
        self.induced_voltage = TotalInducedVoltage(
            self.beam, self.profile, [shortInducedVoltage, longInducedVoltage])
        self.induced_voltage.induced_voltage_sum()

        self.cavity_tracker = RingAndRFTracker(
            self.rf, self.beam, Profile=self.profile, interpolation=True,
            TotalInducedVoltage=self.induced_voltage)

        self.OTFB = SPSCavityFeedback(
            self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16,
            turns=50, Commissioning=CavityFeedbackCommissioning())

        self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam,
                                             Profile=self.profile,
                                             TotalInducedVoltage=None,
                                             CavityFeedback=self.OTFB,
                                             interpolation=True)
        
    def test_FB_pre_tracking(self):

        digit_round = 3

        Vind4_mean = np.around(
                np.mean(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6,
                digit_round)
        Vind4_std = np.around(
                np.std(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6,
                digit_round)
        Vind4_mean_exp = np.around(1.99886351363, digit_round)
        Vind4_std_exp = np.around(2.148426e-6, digit_round)

        Vind5_mean = np.around(
                np.mean(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6,
                digit_round)
        Vind5_std = np.around(
                np.std(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6,
                digit_round)
        Vind5_mean_exp = np.around(2.49906605189, digit_round)
        Vind5_std_exp = np.around(2.221665e-6, digit_round)

        self.assertEqual(Vind4_mean, Vind4_mean_exp,
            msg='In TestCavityFeedback test_FB_pretracking: '
            +'mean value of four-section cavity differs')
        self.assertEqual(Vind4_std, Vind4_std_exp,
            msg='In TestCavityFeedback test_FB_pretracking: standard '
            +'deviation of four-section cavity differs')

        self.assertEqual(Vind5_mean, Vind5_mean_exp,
            msg='In TestCavityFeedback test_FB_pretracking: '
            +'mean value of five-section cavity differs')
        self.assertEqual(Vind5_std, Vind5_std_exp,
            msg='In TestCavityFeedback test_FB_pretracking: standard '+
            'deviation of five-section cavity differs')
        
    def test_FB_pre_tracking_IQ_v1(self):
        digit_round = 2
        
        # interpolate from coarse mesh to fine mesh
        V_fine_tot_4 = np.interp(
                self.profile.bin_centers, self.OTFB.OTFB_4.rf_centers,
                self.OTFB.OTFB_4.V_coarse_ind_gen)
        V_fine_tot_5 = np.interp(
                self.profile.bin_centers, self.OTFB.OTFB_5.rf_centers,
                self.OTFB.OTFB_5.V_coarse_ind_gen)
        
        V_tot_4 = np.around(V_fine_tot_4/1e6, digit_round)
        V_tot_5 = np.around(V_fine_tot_5/1e6, digit_round)
        
        V_sum = np.around(self.OTFB.V_sum/1e6, digit_round)
        
        # expected generator voltage is only in Q
        V_tot_4_exp = 2.0j*np.ones(256)
        V_tot_5_exp = 2.5j*np.ones(256)
        V_sum_exp = 4.5j*np.ones(256)
        
        self.assertListEqual(V_tot_4.tolist(), V_tot_4_exp.tolist(),
            msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage '
            +'in four-section cavity differs')
        
        self.assertListEqual(V_tot_5.tolist(), V_tot_5_exp.tolist(),
            msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage '
            +'in five-section cavity differs')
        
        self.assertListEqual(V_sum.tolist(), V_sum_exp.tolist(),
            msg='In TestCavityFeedback test_FB_pretracking_IQ: voltage sum '
            +' differs')
        
    def test_rf_voltage(self):
        
        digit_round = 8
        
        # compute voltage
        self.cavity_tracker.rf_voltage_calculation()

        # compute voltage after OTFB pre-tracking
        self.OTFB_tracker.rf_voltage_calculation()

        # Since there is a systematic offset between the voltages,
        # compare the maxium of the ratio
        max_ratio = np.max(self.cavity_tracker.rf_voltage
                           / self.OTFB_tracker.rf_voltage)
        max_ratio = np.around(max_ratio, digit_round)
        
        max_ratio_exp = np.around(1.0008217052569774, digit_round)
        self.assertAlmostEqual(max_ratio, max_ratio_exp,
                               places=digit_round,
                         msg='In TestCavityFeedback test_rf_voltage: '
                         + 'RF-voltages differ')

    def test_beam_loading(self):

        digit_round = 10
        
        # Compute voltage with beam loading
        self.cavity_tracker.rf_voltage_calculation()
        cavity_tracker_total_voltage = self.cavity_tracker.rf_voltage \
            + self.cavity_tracker.totalInducedVoltage.induced_voltage

        self.OTFB.track()
        self.OTFB_tracker.rf_voltage_calculation()
        OTFB_tracker_total_voltage = self.OTFB_tracker.rf_voltage

        max_ratio = np.around(np.max(cavity_tracker_total_voltage
                                 / OTFB_tracker_total_voltage), digit_round)
        max_ration_exp = np.around(1.0051759770680779, digit_round)

        self.assertEqual(max_ratio, max_ration_exp,
                         msg='In TestCavityFeedback test_beam_loading: '
                         + 'total voltages differ')
        
    def test_Vsum_IQ(self):
        digit_round = 4
        
        self.OTFB.track()
        
        V_sum = np.around(self.OTFB.V_sum/1e6, digit_round)
        
        V_sum_exp = np.around(np.array([-7.40650823e+01+4497812.99202967j,
        -7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j,
        -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j,-7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j,-7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202967j,-7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202967j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -7.40650822e+01+4497812.99202968j,-7.40650822e+01+4497812.99202968j,
        -6.02318851e+01+4497817.94162674j,-1.98390915e+01+4497835.4539936j ,
         1.93158486e+01+4497855.56826354j,4.37055412e+01+4497871.87009121j,
         7.72626261e+01+4497900.35036866j,1.08879867e+02+4497930.96118169j,
         1.36226374e+02+4497965.43834138j,1.83914308e+02+4498039.43198652j,
         2.58060957e+02+4498182.7842137j ,3.46527521e+02+4498400.20917783j,
         4.26706222e+02+4498667.15544146j,4.94661306e+02+4499027.56784064j,
         5.43482338e+02+4499582.92538958j,5.37601327e+02+4500375.11759629j,
         4.18116316e+02+4501483.68340875j,1.06781854e+02+4502992.29896325j,
        -5.18346745e+02+4504994.88486696j,-1.49458714e+03+4507337.42385509j,
        -3.01163886e+03+4510119.3419273j ,-5.32851179e+03+4513546.45481774j,
        -8.74569640e+03+4517649.58201841j,-1.36711235e+04+4522515.97696859j,
        -2.06268308e+04+4528145.57335092j,-3.07188747e+04+4534772.43779405j,
        -4.42705242e+04+4541938.02912512j,-6.14651616e+04+4548954.45228089j,
        -8.23300421e+04+4555211.22162217j,-1.09421551e+05+4560368.34346543j,
        -1.43885886e+05+4563628.1865127j ,-1.85808399e+05+4563383.852869j  ,
        -2.36208282e+05+4558209.23829535j,-2.94836934e+05+4546270.53281669j,
        -3.63317854e+05+4525133.07455768j,-4.41779074e+05+4492246.31582297j,
        -5.28977031e+05+4445197.26263046j,-6.24427353e+05+4380854.18329653j,
        -7.28570463e+05+4294604.34393273j,-8.41413067e+05+4180725.12037253j,
        -9.58666802e+05+4036850.21934613j,-1.07489637e+06+3861588.24443417j,
        -1.18692079e+06+3650150.96222293j,-1.28868132e+06+3402561.33925834j,
        -1.37503355e+06+3113868.12951949j,-1.44047679e+06+2779413.13521708j,
        -1.47644078e+06+2402815.35953829j,-1.47522678e+06+1985042.23744602j,
        -1.42897968e+06+1528424.34271266j,-1.32931255e+06+1034805.30411738j,
        -1.16912937e+06 +511261.80102318j,-9.43345126e+05  -30406.39494472j,
        -6.44543913e+05 -585971.64269612j,-2.67898382e+05-1147041.0353738j ,
         1.87647422e+05-1699739.23544117j,7.19585769e+05-2229855.79356738j,
         1.32653137e+06-2725965.80099238j,2.00691053e+06-3178849.17084715j,
         2.75728744e+06-3578075.86057957j,3.56230981e+06-3910440.14562456j,
         4.40408617e+06-4164575.91355405j,5.28572695e+06-4338227.19020188j,
         6.19719564e+06-4426787.10912655j,7.11277008e+06-4425807.66220696j,
         8.01692653e+06-4335730.38899002j,8.89765817e+06-4159572.80505286j,
         9.74683705e+06-3900763.99853979j,1.05559999e+07-3564480.67012727j,
         1.13018718e+07-3165395.29765105j,1.19781005e+07-2712267.95526922j,
         1.25833208e+07-2214895.26359232j,1.31112101e+07-1685734.89623327j,
         1.35640429e+07-1132761.26804116j,1.39371556e+07 -573495.98893318j,
         1.42323033e+07  -19883.35687916j,1.44559502e+07 +521811.95451886j,
         1.46134106e+07+1043190.45283868j,1.47105373e+07+1534116.02749795j,
         1.47549265e+07+1994083.71851812j,1.47545428e+07+2416602.70892133j,
         1.47166958e+07+2794242.30539414j,1.46493955e+07+3129779.93382244j,
         1.45593030e+07+3424466.23125072j,1.44539743e+07+3677716.51226699j,
         1.43401341e+07+3889644.33404043j,1.42224899e+07+4064982.31004726j,
         1.41063737e+07+4205965.72167177j,1.39946111e+07+4317244.42689922j,
         1.38886184e+07+4403883.23649077j,1.37894739e+07+4469861.27187975j,
         1.36989283e+07+4518194.75268176j,1.36191316e+07+4551305.81768837j,
         1.35495619e+07+4572524.22309931j,1.34903101e+07+4584597.89085099j,
         1.34406305e+07+4589814.4489974j ,1.33976876e+07+4590220.82697034j,
         1.33615022e+07+4587255.76269093j,1.33327026e+07+4582254.09185628j,
         1.33096130e+07+4576070.77968165j,1.32911752e+07+4569436.1321998j ,
         1.32768524e+07+4562928.08977976j,1.32656893e+07+4556810.85976046j,
         1.32570926e+07+4551309.42853408j,1.32504722e+07+4546502.73564931j,
         1.32453253e+07+4542354.45990368j,1.32414716e+07+4539159.11692844j,
         1.32386032e+07+4536873.63706821j,1.32362022e+07+4534949.63932622j,
         1.32341515e+07+4533397.43716764j,1.32323621e+07+4532141.64712087j,
         1.32307439e+07+4531156.20064611j,1.32292493e+07+4530633.17835778j,
         1.32277994e+07+4530492.96280951j,1.32263821e+07+4530446.25647796j,
         1.32249901e+07+4530405.83108728j,1.32236081e+07+4530431.11420123j,
         1.32222495e+07+4530467.44843446j,1.32208432e+07+4530611.48233323j,
         1.32193886e+07+4530847.10244979j,1.32179361e+07+4531084.60180009j,
         1.32164993e+07+4531317.55923836j,1.32150516e+07+4531560.32993118j,
         1.32135685e+07+4531829.29611484j,1.32120853e+07+4532098.20168656j,
         1.32106022e+07+4532367.04664624j,1.32091191e+07+4532635.83099376j,
         1.32076359e+07+4532904.55472902j,1.32061675e+07+4533173.93875581j,
         1.32046990e+07+4533443.26260922j,1.32032158e+07+4533711.80494598j,
         1.32017326e+07+4533980.28666989j,1.32002495e+07+4534248.70778084j,
         1.31987663e+07+4534517.06827872j,1.31972831e+07+4534785.36816343j,
         1.31957999e+07+4535053.60743485j,1.31943167e+07+4535321.78609287j,
         1.31928335e+07+4535589.90413737j,1.31913503e+07+4535857.96156826j,
         1.31898671e+07+4536125.95838542j,1.31883839e+07+4536393.89458873j,
         1.31869007e+07+4536661.77017809j,1.31854174e+07+4536929.58515338j,
         1.31839342e+07+4537197.33951451j,1.31824510e+07+4537465.03326134j,
         1.31809677e+07+4537732.66639378j,1.31794845e+07+4538000.23891172j,
         1.31780012e+07+4538267.75081504j,1.31765179e+07+4538535.20210364j,
         1.31750347e+07+4538802.5927774j ,1.31735514e+07+4539069.92283622j,
         1.31720681e+07+4539337.19227997j,1.31705848e+07+4539604.40110857j,
         1.31691016e+07+4539871.54932188j,1.31676183e+07+4540138.63691982j,
         1.31661350e+07+4540405.66390225j,1.31646517e+07+4540672.63026908j,
         1.31631684e+07+4540939.53602019j,1.31616850e+07+4541206.38115549j,
         1.31602017e+07+4541473.16567484j,1.31587184e+07+4541739.88957815j,
         1.31572351e+07+4542006.55286531j,1.31557517e+07+4542273.1555362j ,
         1.31542684e+07+4542539.69759073j,1.31527850e+07+4542806.17902876j,
         1.31513017e+07+4543072.59985021j,1.31498183e+07+4543338.96005496j,
         1.31483350e+07+4543605.2596429j ,1.31468516e+07+4543871.49861392j,
         1.31453682e+07+4544137.6769679j ,1.31438848e+07+4544403.79470476j,
         1.31424014e+07+4544669.85182436j,1.31409181e+07+4544935.84832662j,
         1.31394347e+07+4545201.7842114j ,1.31379513e+07+4545467.65947862j,
         1.31364679e+07+4545733.47412815j,1.31349844e+07+4545999.22815989j,
         1.31335010e+07+4546264.92157373j,1.31320176e+07+4546530.55436956j,
         1.31305342e+07+4546796.12654728j,1.31290507e+07+4547061.63810677j,
         1.31275673e+07+4547327.08904792j,1.31260839e+07+4547592.47937064j,
         1.31246004e+07+4547857.8090748j ,1.31231170e+07+4548123.0781603j ,
         1.31216335e+07+4548388.28662704j,1.31201500e+07+4548653.4344749j ,
         1.31186666e+07+4548918.52170378j,1.31171831e+07+4549183.54831356j,
         1.31156996e+07+4549448.51430414j,1.31142161e+07+4549713.41967541j,
         1.31127326e+07+4549978.26442727j])/1e6, digit_round)

        self.assertListEqual(V_sum.tolist(), V_sum_exp.tolist(),
            msg='In TestCavityFeedback test_Vsum_IQ: total voltage '
            +'is different from expected values!')
示例#23
0
class TestRfVoltageCalc(unittest.TestCase):
    # Simulation parameters -------------------------------------------------------
    # Bunch parameters
    N_b = 1e9  # Intensity
    N_p = 50000  # Macro-particles
    tau_0 = 0.4e-9  # Initial bunch length, 4 sigma [s]
    # Machine and RF parameters
    C = 26658.883  # Machine circumference [m]
    p_i = 450e9  # Synchronous momentum [eV/c]
    p_f = 460.005e9  # Synchronous momentum, final
    h = 35640  # Harmonic number
    V = 6e6  # RF voltage [V]
    dphi = 0  # Phase modulation/offset
    gamma_t = 55.759505  # Transition gamma
    alpha = 1. / gamma_t / gamma_t  # First order mom. comp. factor
    # Tracking details
    N_t = 2000  # Number of turns to track

    # Run before every test
    def setUp(self):
        self.ring = Ring(self.C, self.alpha,
                         np.linspace(self.p_i, self.p_f, self.N_t + 1),
                         Proton(), self.N_t)
        self.beam = Beam(self.ring, self.N_p, self.N_b)
        self.rf = RFStation(self.ring, [self.h],
                            self.V * np.linspace(1, 1.1, self.N_t + 1),
                            [self.dphi])
        bigaussian(self.ring,
                   self.rf,
                   self.beam,
                   self.tau_0 / 4,
                   reinsertion=True,
                   seed=1)
        self.profile = Profile(
            self.beam,
            CutOptions(n_slices=100, cut_left=0, cut_right=self.rf.t_rf[0, 0]),
            FitOptions(fit_option='gaussian'))
        self.long_tracker = RingAndRFTracker(self.rf,
                                             self.beam,
                                             Profile=self.profile)

    # Run after every test

    def tearDown(self):
        pass

    def test_rf_voltage_calc_1(self):
        self.long_tracker.rf_voltage_calculation()
        orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_rf_voltage_calc_2(self):
        for i in range(100):
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)

    def test_rf_voltage_calc_3(self):
        for i in range(100):
            self.profile.track()
            self.long_tracker.track()
            self.long_tracker.rf_voltage_calculation()
            orig_rf_voltage = orig_rf_volt_comp(self.long_tracker)
        np.testing.assert_almost_equal(self.long_tracker.rf_voltage,
                                       orig_rf_voltage,
                                       decimal=8)
示例#24
0
charge_test = general_params.Particle.charge  # e*Z

# Define RF station parameters and corresponding tracker
rf_params = RFStation(general_params, [h], [V], [dphi])
print("Initial bucket length is %.3e s" %
      (2. * np.pi / rf_params.omega_rf[0, 0]))
print("Final bucket length is %.3e s" %
      (2. * np.pi / rf_params.omega_rf[0, N_t]))

phi_s_test = rf_params.phi_s  #: *Synchronous phase
omega_RF_d_test = rf_params.omega_rf_d  #: *Design RF frequency of the RF systems in the station [GHz]*
omega_RF_test = rf_params.omega_rf  #: *Initial, actual RF frequency of the RF systems in the station [GHz]*
phi_RF_test = rf_params.omega_rf  #: *Initial, actual RF phase of each harmonic system*
E_increment_test = rf_params.delta_E  #Energy increment (acceleration/deceleration) between two turns,

long_tracker = RingAndRFTracker(rf_params, beam)

eta_0_test = rf_params.eta_0  #: *Slippage factor (0th order) for the given RF section*
eta_1_test = rf_params.eta_1  #: *Slippage factor (1st order) for the given RF section*
eta_2_test = rf_params.eta_2  #: *Slippage factor (2nd order) for the given RF section*
alpha_order_test = rf_params.alpha_order

bigaussian(general_params,
           rf_params,
           beam,
           tau_0 / 4,
           reinsertion='on',
           seed=1)

# Need slices for the Gaussian fit
slice_beam = Profile(beam, CutOptions(n_slices=100))
示例#25
0
# Cavities parameters
n_rf_systems = 1
harmonic_numbers = 1
voltage_program = 8e3  #[V]
phi_offset = np.pi

# DEFINE RING------------------------------------------------------------------

general_params = Ring(C, momentum_compaction, sync_momentum, Proton(), n_turns)

RF_sct_par = RFStation(general_params, [harmonic_numbers], [voltage_program],
                       [phi_offset], n_rf_systems)

my_beam = Beam(general_params, n_macroparticles, n_particles)

ring_RF_section = RingAndRFTracker(RF_sct_par, my_beam)

# DEFINE BEAM------------------------------------------------------------------
bigaussian(general_params, RF_sct_par, my_beam, sigma_dt, seed=1)

# DEFINE SLICES----------------------------------------------------------------
slice_beam = Profile(
    my_beam,
    CutOptions(cut_left=-5.72984173562e-7,
               cut_right=5.72984173562e-7,
               n_slices=100))

# MONITOR----------------------------------------------------------------------

bunchmonitor = BunchMonitor(general_params,
                            RF_sct_par,
示例#26
0
    ImpedanceTableListRest,
    frequency_step,
    RFParams=rf_params,
    multi_turn_wake=True,
    front_wake_length=front_wake_length)

# PS_longitudinal_intensity = TotalInducedVoltage(
#     beam, profile, [PS_intensity_freq_10MHz, PS_intensity_freq_Rest, PS_inductive])

PS_longitudinal_intensity = TotalInducedVoltage(
    beam, profile, [PS_intensity_freq_Rest, PS_inductive])

# RF tracker
tracker = RingAndRFTracker(rf_params,
                           beam,
                           interpolation=True,
                           Profile=profile,
                           TotalInducedVoltage=PS_longitudinal_intensity)
full_tracker = FullRingAndRF([tracker])

# Beam generation
distribution_options = {
    'type': 'parabolic_amplitude',
    'density_variable': 'Hamiltonian',
    'bunch_length': bunch_length
}

match_beam_from_distribution(beam,
                             full_tracker,
                             ring,
                             distribution_options,
示例#27
0
class TestCavityFeedback(unittest.TestCase):

    def setUp(self):
        C = 2*np.pi*1100.009        # Ring circumference [m]
        gamma_t = 18.0              # Gamma at transition
        alpha = 1/gamma_t**2        # Momentum compaction factor
        p_s = 25.92e9               # Synchronous momentum at injection [eV]
        h = 4620                    # 200 MHz system harmonic
        phi = 0.                    # 200 MHz RF phase

        # With this setting, amplitude in the two four-section, five-section
        # cavities must converge, respectively, to
        # 2.0 MV = 4.5 MV * 4/18 * 2
        # 2.5 MV = 4.5 MV * 5/18 * 2
        V = 4.5e6                   # 200 MHz RF voltage

        N_t = 1                     # Number of turns to track

        self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t)
        self.rf = RFStation(self.ring, h, V, phi)

        N_m = 1e6                   # Number of macro-particles for tracking
        N_b = 72*1.0e11             # Bunch intensity [ppb]

        # Gaussian beam profile
        self.beam = Beam(self.ring, N_m, N_b)
        sigma = 1.0e-9
        bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234,
                   reinsertion=False)

        n_shift = 1550  # how many rf-buckets to shift beam
        self.beam.dt += n_shift * self.rf.t_rf[0, 0]

        self.profile = Profile(
            self.beam, CutOptions=CutOptions(
                cut_left=(n_shift-1.5)*self.rf.t_rf[0, 0],
                cut_right=(n_shift+2.5)*self.rf.t_rf[0, 0],
                n_slices=4*64))
        self.profile.track()

        # Cavities
        l_cav = 43*0.374
        v_g = 0.0946
        tau = l_cav/(v_g*c)*(1 + v_g)
        f_cav = 200.222e6
        n_cav = 2   # factor 2 because of two four/five-sections cavities
        short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8,
                                           f_cav, 2*np.pi*tau)
        shortInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                 [short_cavity])
        l_cav = 54*0.374
        tau = l_cav/(v_g*c)*(1 + v_g)
        long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav,
                                          2*np.pi*tau)
        longInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                [long_cavity])
        self.induced_voltage = TotalInducedVoltage(
            self.beam, self.profile, [shortInducedVoltage, longInducedVoltage])
        self.induced_voltage.induced_voltage_sum()

        self.cavity_tracker = RingAndRFTracker(
            self.rf, self.beam, Profile=self.profile, interpolation=True,
            TotalInducedVoltage=self.induced_voltage)

        self.OTFB = SPSCavityFeedback(
            self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16,
            turns=50, Commissioning=CavityFeedbackCommissioning())

        self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam,
                                             Profile=self.profile,
                                             TotalInducedVoltage=None,
                                             CavityFeedback=self.OTFB,
                                             interpolation=True)

    def test_FB_pre_tracking(self):

        digit_round = 3

        Vind4_mean = np.mean(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6
        Vind4_std = np.std(np.absolute(self.OTFB.OTFB_4.V_coarse_tot))/1e6
        Vind4_mean_exp = 1.99886351363
        Vind4_std_exp = 2.148426e-6

        Vind5_mean = np.mean(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6

        Vind5_std = np.std(np.absolute(self.OTFB.OTFB_5.V_coarse_tot))/1e6

        Vind5_mean_exp = 2.49906605189
        Vind5_std_exp = 2.221665e-6

        self.assertAlmostEqual(Vind4_mean, Vind4_mean_exp,
                               places=digit_round,
                               msg='In TestCavityFeedback test_FB_pretracking: ' +
                               'mean value of four-section cavity differs')
        self.assertAlmostEqual(Vind4_std, Vind4_std_exp,
                               places=digit_round,
                               msg='In TestCavityFeedback test_FB_pretracking: standard ' +
                               'deviation of four-section cavity differs')

        self.assertAlmostEqual(Vind5_mean, Vind5_mean_exp,
                               places=digit_round,
                               msg='In TestCavityFeedback test_FB_pretracking: ' +
                               'mean value of five-section cavity differs')
        self.assertAlmostEqual(Vind5_std, Vind5_std_exp,
                               places=digit_round,
                               msg='In TestCavityFeedback test_FB_pretracking: standard '
                               + 'deviation of five-section cavity differs')

    def test_FB_pre_tracking_IQ_v1(self):
        rtol = 1e-3         # relative tolerance
        atol = 0            # absolute tolerance
        # interpolate from coarse mesh to fine mesh
        V_fine_tot_4 = np.interp(
            self.profile.bin_centers, self.OTFB.OTFB_4.rf_centers,
            self.OTFB.OTFB_4.V_coarse_ind_gen)
        V_fine_tot_5 = np.interp(
            self.profile.bin_centers, self.OTFB.OTFB_5.rf_centers,
            self.OTFB.OTFB_5.V_coarse_ind_gen)

        V_tot_4 = V_fine_tot_4/1e6
        V_tot_5 = V_fine_tot_5/1e6

        V_sum = self.OTFB.V_sum/1e6

        # expected generator voltage is only in Q
        V_tot_4_exp = 2.0j*np.ones(256)
        V_tot_5_exp = 2.5j*np.ones(256)
        V_sum_exp = 4.5j*np.ones(256)

        np.testing.assert_allclose(V_tot_4, V_tot_4_exp,
                                   rtol=rtol, atol=atol,
                                   err_msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage ' +
                                   'in four-section cavity differs')

        np.testing.assert_allclose(V_tot_5, V_tot_5_exp,
                                   rtol=rtol, atol=atol,
                                   err_msg='In TestCavityFeedback test_FB_pretracking_IQ: total voltage ' +
                                   'in five-section cavity differs')

        np.testing.assert_allclose(V_sum, V_sum_exp,
                                   rtol=rtol, atol=atol,
                                   err_msg='In TestCavityFeedback test_FB_pretracking_IQ: voltage sum ' +
                                   ' differs')

    def test_rf_voltage(self):

        digit_round = 9

        # compute voltage
        self.cavity_tracker.rf_voltage_calculation()

        # compute voltage after OTFB pre-tracking
        self.OTFB_tracker.rf_voltage_calculation()

        # Since there is a systematic offset between the voltages,
        # compare the maxium of the ratio
        max_ratio = np.max(self.cavity_tracker.rf_voltage
                           / self.OTFB_tracker.rf_voltage)
        max_ratio = max_ratio

        max_ratio_exp = 1.0008217052569774
        self.assertAlmostEqual(max_ratio, max_ratio_exp,
                               places=digit_round,
                               msg='In TestCavityFeedback test_rf_voltage: '
                               + 'RF-voltages differ')

    def test_beam_loading(self):
        digit_round = 9

        # Compute voltage with beam loading
        self.cavity_tracker.rf_voltage_calculation()
        cavity_tracker_total_voltage = self.cavity_tracker.rf_voltage \
            + self.cavity_tracker.totalInducedVoltage.induced_voltage

        self.OTFB.track()
        self.OTFB_tracker.rf_voltage_calculation()
        OTFB_tracker_total_voltage = self.OTFB_tracker.rf_voltage

        max_ratio = np.max(cavity_tracker_total_voltage /
                           OTFB_tracker_total_voltage)
        max_ration_exp = 1.0051759770680779

        self.assertAlmostEqual(max_ratio, max_ration_exp, places=digit_round,
                               msg='In TestCavityFeedback test_beam_loading: '
                               + 'total voltages differ')

    def test_Vsum_IQ(self):
        rtol = 1e-7         # relative tolerance
        atol = 0              # absolute tolerance

        self.OTFB.track()

        V_sum = self.OTFB.V_sum/1e6

        V_sum_exp = np.array([-7.40650823e+01+4497812.99202967j,
                              -7.40650823e+01+4497812.99202967j, -7.40650823e+01+4497812.99202967j,
                              -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650823e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202967j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202967j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -7.40650822e+01+4497812.99202968j, -7.40650822e+01+4497812.99202968j,
                              -6.02318851e+01+4497817.94162674j, -1.98390915e+01+4497835.4539936j,
                              1.93158486e+01+4497855.56826354j, 4.37055412e+01+4497871.87009121j,
                              7.72626261e+01+4497900.35036866j, 1.08879867e+02+4497930.96118169j,
                              1.36226374e+02+4497965.43834138j, 1.83914308e+02+4498039.43198652j,
                              2.58060957e+02+4498182.7842137j, 3.46527521e+02+4498400.20917783j,
                              4.26706222e+02+4498667.15544146j, 4.94661306e+02+4499027.56784064j,
                              5.43482338e+02+4499582.92538958j, 5.37601327e+02+4500375.11759629j,
                              4.18116316e+02+4501483.68340875j, 1.06781854e+02+4502992.29896325j,
                              -5.18346745e+02+4504994.88486696j, -1.49458714e+03+4507337.42385509j,
                              -3.01163886e+03+4510119.3419273j, -5.32851179e+03+4513546.45481774j,
                              -8.74569640e+03+4517649.58201841j, -1.36711235e+04+4522515.97696859j,
                              -2.06268308e+04+4528145.57335092j, -3.07188747e+04+4534772.43779405j,
                              -4.42705242e+04+4541938.02912512j, -6.14651616e+04+4548954.45228089j,
                              -8.23300421e+04+4555211.22162217j, -1.09421551e+05+4560368.34346543j,
                              -1.43885886e+05+4563628.1865127j, -1.85808399e+05+4563383.852869j,
                              -2.36208282e+05+4558209.23829535j, -2.94836934e+05+4546270.53281669j,
                              -3.63317854e+05+4525133.07455768j, -4.41779074e+05+4492246.31582297j,
                              -5.28977031e+05+4445197.26263046j, -6.24427353e+05+4380854.18329653j,
                              -7.28570463e+05+4294604.34393273j, -8.41413067e+05+4180725.12037253j,
                              -9.58666802e+05+4036850.21934613j, -1.07489637e+06+3861588.24443417j,
                              -1.18692079e+06+3650150.96222293j, -1.28868132e+06+3402561.33925834j,
                              -1.37503355e+06+3113868.12951949j, -1.44047679e+06+2779413.13521708j,
                              -1.47644078e+06+2402815.35953829j, -1.47522678e+06+1985042.23744602j,
                              -1.42897968e+06+1528424.34271266j, -1.32931255e+06+1034805.30411738j,
                              -1.16912937e+06 + 511261.80102318j, -9.43345126e+05 - 30406.39494472j,
                              -6.44543913e+05 - 585971.64269612j, -2.67898382e+05-1147041.0353738j,
                              1.87647422e+05-1699739.23544117j, 7.19585769e+05-2229855.79356738j,
                              1.32653137e+06-2725965.80099238j, 2.00691053e+06-3178849.17084715j,
                              2.75728744e+06-3578075.86057957j, 3.56230981e+06-3910440.14562456j,
                              4.40408617e+06-4164575.91355405j, 5.28572695e+06-4338227.19020188j,
                              6.19719564e+06-4426787.10912655j, 7.11277008e+06-4425807.66220696j,
                              8.01692653e+06-4335730.38899002j, 8.89765817e+06-4159572.80505286j,
                              9.74683705e+06-3900763.99853979j, 1.05559999e+07-3564480.67012727j,
                              1.13018718e+07-3165395.29765105j, 1.19781005e+07-2712267.95526922j,
                              1.25833208e+07-2214895.26359232j, 1.31112101e+07-1685734.89623327j,
                              1.35640429e+07-1132761.26804116j, 1.39371556e+07 - 573495.98893318j,
                              1.42323033e+07 - 19883.35687916j, 1.44559502e+07 + 521811.95451886j,
                              1.46134106e+07+1043190.45283868j, 1.47105373e+07+1534116.02749795j,
                              1.47549265e+07+1994083.71851812j, 1.47545428e+07+2416602.70892133j,
                              1.47166958e+07+2794242.30539414j, 1.46493955e+07+3129779.93382244j,
                              1.45593030e+07+3424466.23125072j, 1.44539743e+07+3677716.51226699j,
                              1.43401341e+07+3889644.33404043j, 1.42224899e+07+4064982.31004726j,
                              1.41063737e+07+4205965.72167177j, 1.39946111e+07+4317244.42689922j,
                              1.38886184e+07+4403883.23649077j, 1.37894739e+07+4469861.27187975j,
                              1.36989283e+07+4518194.75268176j, 1.36191316e+07+4551305.81768837j,
                              1.35495619e+07+4572524.22309931j, 1.34903101e+07+4584597.89085099j,
                              1.34406305e+07+4589814.4489974j, 1.33976876e+07+4590220.82697034j,
                              1.33615022e+07+4587255.76269093j, 1.33327026e+07+4582254.09185628j,
                              1.33096130e+07+4576070.77968165j, 1.32911752e+07+4569436.1321998j,
                              1.32768524e+07+4562928.08977976j, 1.32656893e+07+4556810.85976046j,
                              1.32570926e+07+4551309.42853408j, 1.32504722e+07+4546502.73564931j,
                              1.32453253e+07+4542354.45990368j, 1.32414716e+07+4539159.11692844j,
                              1.32386032e+07+4536873.63706821j, 1.32362022e+07+4534949.63932622j,
                              1.32341515e+07+4533397.43716764j, 1.32323621e+07+4532141.64712087j,
                              1.32307439e+07+4531156.20064611j, 1.32292493e+07+4530633.17835778j,
                              1.32277994e+07+4530492.96280951j, 1.32263821e+07+4530446.25647796j,
                              1.32249901e+07+4530405.83108728j, 1.32236081e+07+4530431.11420123j,
                              1.32222495e+07+4530467.44843446j, 1.32208432e+07+4530611.48233323j,
                              1.32193886e+07+4530847.10244979j, 1.32179361e+07+4531084.60180009j,
                              1.32164993e+07+4531317.55923836j, 1.32150516e+07+4531560.32993118j,
                              1.32135685e+07+4531829.29611484j, 1.32120853e+07+4532098.20168656j,
                              1.32106022e+07+4532367.04664624j, 1.32091191e+07+4532635.83099376j,
                              1.32076359e+07+4532904.55472902j, 1.32061675e+07+4533173.93875581j,
                              1.32046990e+07+4533443.26260922j, 1.32032158e+07+4533711.80494598j,
                              1.32017326e+07+4533980.28666989j, 1.32002495e+07+4534248.70778084j,
                              1.31987663e+07+4534517.06827872j, 1.31972831e+07+4534785.36816343j,
                              1.31957999e+07+4535053.60743485j, 1.31943167e+07+4535321.78609287j,
                              1.31928335e+07+4535589.90413737j, 1.31913503e+07+4535857.96156826j,
                              1.31898671e+07+4536125.95838542j, 1.31883839e+07+4536393.89458873j,
                              1.31869007e+07+4536661.77017809j, 1.31854174e+07+4536929.58515338j,
                              1.31839342e+07+4537197.33951451j, 1.31824510e+07+4537465.03326134j,
                              1.31809677e+07+4537732.66639378j, 1.31794845e+07+4538000.23891172j,
                              1.31780012e+07+4538267.75081504j, 1.31765179e+07+4538535.20210364j,
                              1.31750347e+07+4538802.5927774j, 1.31735514e+07+4539069.92283622j,
                              1.31720681e+07+4539337.19227997j, 1.31705848e+07+4539604.40110857j,
                              1.31691016e+07+4539871.54932188j, 1.31676183e+07+4540138.63691982j,
                              1.31661350e+07+4540405.66390225j, 1.31646517e+07+4540672.63026908j,
                              1.31631684e+07+4540939.53602019j, 1.31616850e+07+4541206.38115549j,
                              1.31602017e+07+4541473.16567484j, 1.31587184e+07+4541739.88957815j,
                              1.31572351e+07+4542006.55286531j, 1.31557517e+07+4542273.1555362j,
                              1.31542684e+07+4542539.69759073j, 1.31527850e+07+4542806.17902876j,
                              1.31513017e+07+4543072.59985021j, 1.31498183e+07+4543338.96005496j,
                              1.31483350e+07+4543605.2596429j, 1.31468516e+07+4543871.49861392j,
                              1.31453682e+07+4544137.6769679j, 1.31438848e+07+4544403.79470476j,
                              1.31424014e+07+4544669.85182436j, 1.31409181e+07+4544935.84832662j,
                              1.31394347e+07+4545201.7842114j, 1.31379513e+07+4545467.65947862j,
                              1.31364679e+07+4545733.47412815j, 1.31349844e+07+4545999.22815989j,
                              1.31335010e+07+4546264.92157373j, 1.31320176e+07+4546530.55436956j,
                              1.31305342e+07+4546796.12654728j, 1.31290507e+07+4547061.63810677j,
                              1.31275673e+07+4547327.08904792j, 1.31260839e+07+4547592.47937064j,
                              1.31246004e+07+4547857.8090748j, 1.31231170e+07+4548123.0781603j,
                              1.31216335e+07+4548388.28662704j, 1.31201500e+07+4548653.4344749j,
                              1.31186666e+07+4548918.52170378j, 1.31171831e+07+4549183.54831356j,
                              1.31156996e+07+4549448.51430414j, 1.31142161e+07+4549713.41967541j,
                              1.31127326e+07+4549978.26442727j])/1e6

        np.testing.assert_allclose(V_sum_exp, V_sum,
                                   rtol=rtol, atol=atol,
                                   err_msg='In TestCavityFeedback test_Vsum_IQ: total voltage ' +
                                   'is different from expected values!')
示例#28
0
    ImpedanceTableListRest,
    frequency_step,
    RFParams=rf_params,
    multi_turn_wake=True,
    front_wake_length=front_wake_length)

# PS_longitudinal_intensity = TotalInducedVoltage(
#     beam, profile, [PS_intensity_freq_10MHz, PS_intensity_freq_Rest, PS_inductive])

PS_longitudinal_intensity = TotalInducedVoltage(
    beam, profile, [PS_intensity_freq_Rest, PS_inductive])

# RF tracker
tracker = RingAndRFTracker(rf_params,
                           beam,
                           interpolation=True,
                           Profile=profile,
                           TotalInducedVoltage=PS_longitudinal_intensity)
full_tracker = FullRingAndRF([tracker])

# Beam generation
distribution_options = {
    'type': 'parabolic_amplitude',
    'density_variable': 'Hamiltonian',
    'bunch_length': bunch_length
}

match_beam_from_distribution(beam,
                             full_tracker,
                             ring,
                             distribution_options,
示例#29
0
logging.debug("Beam q/m ratio %.3e", profile.Beam.ratio)

OTFB = SPSCavityFeedback(rf,
                         beam,
                         profile,
                         G_llrf=5,
                         G_tx=0.5,
                         a_comb=15 / 16,
                         turns=N_pretrack,
                         post_LS2=False,
                         Commissioning=CavityFeedbackCommissioning(
                             debug=True, open_FF=True))

tracker = RingAndRFTracker(rf,
                           beam,
                           CavityFeedback=OTFB,
                           interpolation=True,
                           Profile=profile)

if not os.path.exists("fig"):
    os.mkdir("fig")

plot_long_phase_space(ring,
                      rf,
                      beam,
                      0,
                      5e-9,
                      -2e8,
                      2e8,
                      dirname='fig',
                      alpha=0.5,
示例#30
0
N_t = 2000  # Number of turns to track
dt_plt = int(sys.argv[2])  # Time steps between plots

# Simulation setup ------------------------------------------------------------
print("Setting up the simulation...")
print("")

# Define general parameters
ring = Ring(C, alpha, np.linspace(p_i, p_f, N_t + 1), Proton(), N_t)

# Define beam and distribution
beam = Beam(ring, N_p, N_b)

# Define RF station parameters and corresponding tracker
rf = RFStation(ring, [h], [V], [dphi])
long_tracker = RingAndRFTracker(rf, beam)

bigaussian(ring, rf, beam, tau_0 / 4, reinsertion=True, seed=1)

# Need slices for the Gaussian fit
# profile = Profile(beam, CutOptions(n_slices=N_p//1000),
#                  FitOptions(fit_option='gaussian'))

# Define what to save in file
# bunchmonitor = BunchMonitor(ring, rf, beam,
#                           this_directory + '../output_files/EX_01_output_data', Profile=profile)

# format_options = {'dirname': this_directory + '../output_files/EX_01_fig'}
# plots = Plot(ring, rf, beam, dt_plt, N_t, 0, 0.0001763*h,
#              -400e6, 400e6, xunit='rad', separatrix_plot=True,
#              Profile=profile, h5file=this_directory + '../output_files/EX_01_output_data',
                           n_turns)
general_params_res = Ring(C, momentum_compaction, sync_momentum, Proton(),
                          n_turns)

RF_sct_par = RFStation(general_params, [harmonic_number], [voltage_program],
                       [phi_offset], n_rf_systems)
RF_sct_par_freq = RFStation(general_params_freq, [harmonic_number],
                            [voltage_program], [phi_offset], n_rf_systems)
RF_sct_par_res = RFStation(general_params_res, [harmonic_number],
                           [voltage_program], [phi_offset], n_rf_systems)

my_beam = Beam(general_params, n_macroparticles, n_particles)
my_beam_freq = Beam(general_params_freq, n_macroparticles, n_particles)
my_beam_res = Beam(general_params_res, n_macroparticles, n_particles)

ring_RF_section = RingAndRFTracker(RF_sct_par, my_beam)
ring_RF_section_freq = RingAndRFTracker(RF_sct_par_freq, my_beam_freq)
ring_RF_section_res = RingAndRFTracker(RF_sct_par_res, my_beam_res)

# DEFINE BEAM------------------------------------------------------------------

bigaussian(general_params, RF_sct_par, my_beam, tau_0 / 4, seed=1)
bigaussian(general_params_freq,
           RF_sct_par_freq,
           my_beam_freq,
           tau_0 / 4,
           seed=1)
bigaussian(general_params_res, RF_sct_par_res, my_beam_res, tau_0 / 4, seed=1)

number_slices = 2**8
cut_options = CutOptions(cut_left=0,
示例#32
0
    def setUp(self):
        C = 2*np.pi*1100.009        # Ring circumference [m]
        gamma_t = 18.0              # Gamma at transition
        alpha = 1/gamma_t**2        # Momentum compaction factor
        p_s = 25.92e9               # Synchronous momentum at injection [eV]
        h = 4620                    # 200 MHz system harmonic
        phi = 0.                    # 200 MHz RF phase

        # With this setting, amplitude in the two four-section, five-section
        # cavities must converge, respectively, to
        # 2.0 MV = 4.5 MV * 4/18 * 2
        # 2.5 MV = 4.5 MV * 5/18 * 2
        V = 4.5e6                   # 200 MHz RF voltage

        N_t = 1                     # Number of turns to track

        self.ring = Ring(C, alpha, p_s, Particle=Proton(), n_turns=N_t)
        self.rf = RFStation(self.ring, h, V, phi)

        N_m = 1e6                   # Number of macro-particles for tracking
        N_b = 72*1.0e11             # Bunch intensity [ppb]

        # Gaussian beam profile
        self.beam = Beam(self.ring, N_m, N_b)
        sigma = 1.0e-9
        bigaussian(self.ring, self.rf, self.beam, sigma, seed=1234,
                   reinsertion=False)

        n_shift = 1550  # how many rf-buckets to shift beam
        self.beam.dt += n_shift * self.rf.t_rf[0, 0]

        self.profile = Profile(
            self.beam, CutOptions=CutOptions(
                cut_left=(n_shift-1.5)*self.rf.t_rf[0, 0],
                cut_right=(n_shift+2.5)*self.rf.t_rf[0, 0],
                n_slices=4*64))
        self.profile.track()

        # Cavities
        l_cav = 43*0.374
        v_g = 0.0946
        tau = l_cav/(v_g*c)*(1 + v_g)
        f_cav = 200.222e6
        n_cav = 2   # factor 2 because of two four/five-sections cavities
        short_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8,
                                           f_cav, 2*np.pi*tau)
        shortInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                 [short_cavity])
        l_cav = 54*0.374
        tau = l_cav/(v_g*c)*(1 + v_g)
        long_cavity = TravelingWaveCavity(l_cav**2 * n_cav * 27.1e3 / 8, f_cav,
                                          2*np.pi*tau)
        longInducedVoltage = InducedVoltageTime(self.beam, self.profile,
                                                [long_cavity])
        self.induced_voltage = TotalInducedVoltage(
            self.beam, self.profile, [shortInducedVoltage, longInducedVoltage])
        self.induced_voltage.induced_voltage_sum()

        self.cavity_tracker = RingAndRFTracker(
            self.rf, self.beam, Profile=self.profile, interpolation=True,
            TotalInducedVoltage=self.induced_voltage)

        self.OTFB = SPSCavityFeedback(
            self.rf, self.beam, self.profile, G_llrf=5, G_tx=0.5, a_comb=15/16,
            turns=50, Commissioning=CavityFeedbackCommissioning())

        self.OTFB_tracker = RingAndRFTracker(self.rf, self.beam,
                                             Profile=self.profile,
                                             TotalInducedVoltage=None,
                                             CavityFeedback=self.OTFB,
                                             interpolation=True)
示例#33
0
mpiprint("   SL a_i = %.4f a_f = %.4f" % (PL.lhc_a[0], PL.lhc_a[n_turns]))
mpiprint("   SL t_i = %.4f t_f = %.4f" % (PL.lhc_t[0], PL.lhc_t[n_turns]))

# Injecting noise in the cavity, PL on

# Define machine impedance from http://impedance.web.cern.ch/impedance/
ZTot = np.loadtxt(os.path.join(inputDir, 'Zlong_Allthemachine_450GeV_B1_LHC_inj_450GeV_B1.dat'),
                  skiprows=1)
ZTable = InputTable(ZTot[:, 0], ZTot[:, 1], ZTot[:, 2])
indVoltage = InducedVoltageFreq(
    beam, profile, [ZTable], frequency_resolution=freq_res)
totVoltage = TotalInducedVoltage(beam, profile, [indVoltage])

# TODO add the noiseFB
tracker = RingAndRFTracker(rf, beam, BeamFeedback=PL, Profile=profile,
                           interpolation=True, TotalInducedVoltage=totVoltage,
                           solver='simple')
# interpolation=True, TotalInducedVoltage=None)
mpiprint("PL, SL, and tracker set...")
# Fill beam distribution
fullring = FullRingAndRF([tracker])
# Juan's fit to LHC profiles: binomial w/ exponent 1.5
# matched_from_distribution_function(beam, fullring,
#    main_harmonic_option = 'lowest_freq',
#    distribution_exponent = 1.5, distribution_type='binomial',
#    bunch_length = 1.1e-9, bunch_length_fit = 'fwhm',
#    distribution_variable = 'Action')

# Initial losses, slicing, statistics
beam.losses_separatrix(ring, rf)
示例#34
0
    def test_SPS_RL(self):

        PL_gain = 1000      # gain of phase loop
        rtol = 1e-4         # relative tolerance
        atol = 0              # absolute tolerance
        # Phase loop setup

        phase_loop = BeamFeedback(self.ring, self.rf_station, self.profile,
                                  {'machine': 'SPS_RL', 'PL_gain': PL_gain})

        # Tracker setup
        section_tracker = RingAndRFTracker(
            self.rf_station, self.beam, Profile=self.profile,
            BeamFeedback=phase_loop, interpolation=False)
        tracker = FullRingAndRF([section_tracker])

        # average beam position
        beamAvgPos = np.zeros(self.ring.n_turns)

        n_turns = self.ring.n_turns
        for turn in range(n_turns):
            beamAvgPos[turn] = np.mean(self.beam.dt)
            self.profile.track()
            tracker.track()

        # difference between beam position and synchronuous position
        # (assuming no beam loading)
        delta_tau = beamAvgPos - (np.pi - self.rf_station.phi_rf[0, :-1])\
            / self.rf_station.omega_rf[0, :-1]

        # initial position for analytic solution
        init_pos = self.time_offset

        omega_eff = cmath.sqrt(-PL_gain**2 + 4*self.rf_station.omega_s0[0]**2)
        time = np.arange(n_turns) * self.ring.t_rev[0]
        # initial derivative for analytic solution;
        # defined such that analytical solution at turn 1 agrees with numerical
        # solution
        init_slope = 0.5 * (delta_tau[1] * omega_eff * np.exp(0.5*PL_gain*time[1])
                            / np.sin(0.5*omega_eff*time[1]) - delta_tau[0]
                            * (PL_gain+omega_eff/np.tan(0.5*omega_eff*time[1]))).real

        delta_tau_analytic = init_pos * np.exp(-0.5*PL_gain*time)
        delta_tau_analytic *= np.cos(0.5*time*omega_eff).real\
            + (PL_gain+2*init_slope/init_pos)\
            * (np.sin(0.5*time*omega_eff)/omega_eff).real

        difference = delta_tau - delta_tau_analytic
        # normalize result
        difference = difference / np.max(difference)
        # expected difference
        difference_exp = np.array([
            -1.56306635e-05, -1.55605315e-05,  -2.10224435e-05, -3.18525050e-05,
            -4.74014489e-05, -6.70584402e-05, -9.01307422e-05, -1.15823959e-04,
            -1.43290487e-04, -1.71572162e-04,  -1.99820151e-04,  -2.27071730e-04,
            -2.52331681e-04,  -2.74668126e-04,  -2.93165304e-04, -3.06972913e-04,
            -3.15442474e-04,  -3.17857324e-04, -3.13794970e-04,  -3.02786089e-04,
            -2.84680298e-04, -2.59322215e-04,  -2.26874004e-04,  -1.87452375e-04,
            -1.41293604e-04,  -8.89863575e-05,  -3.08865701e-05, 3.22411495e-05,
            9.97408029e-05,   1.70914181e-04, 2.44766912e-04, 3.20596833e-04,
            3.97403451e-04, 4.74233283e-04,   5.50189125e-04, 6.24368453e-04,
            6.95836553e-04,   7.63737143e-04,   8.27069057e-04, 8.84995559e-04,
            9.36770723e-04,   9.81561780e-04, 1.01869959e-03,   1.04738842e-03,
            1.06711062e-03, 1.07736961e-03,   1.07778386e-03,   1.06805613e-03,
            1.04797776e-03,   1.01747638e-03,   9.76519221e-04, 9.25420191e-04,
            8.64415092e-04,   7.93844624e-04, 7.14396030e-04, 6.26549187e-04,
            5.31154439e-04, 4.28985322e-04,   3.21198916e-04,   2.08550190e-04,
            9.21607082e-05,  -2.68249728e-05,  -1.47278123e-04, -2.67890543e-04,
            -3.87642210e-04,  -5.05244473e-04, -6.19660328e-04,  -7.29670300e-04,
            -8.34272846e-04, -9.32388033e-04,  -1.02301036e-03,  -1.10520861e-03,
            -1.17824066e-03,  -1.24119243e-03,  -1.29350096e-03, -1.33458128e-03,
            -1.36388379e-03,  -1.38105465e-03, -1.38595634e-03,  -1.37832214e-03,
            -1.35829791e-03, -1.32588558e-03,  -1.28146000e-03,  -1.22518721e-03,
            -1.15769141e-03,  -1.07943574e-03,  -9.91143310e-04, -8.93671637e-04,
            -7.87961546e-04,  -6.74866999e-04, -5.55444011e-04,  -4.30919368e-04,
            -3.02270469e-04, -1.70824836e-04,  -3.77396109e-05,   9.56816273e-05,
            2.28299979e-04,   3.58842001e-04,   4.86074690e-04, 6.08875045e-04,
            7.26090501e-04,   8.36677390e-04, 9.39639556e-04,   1.03407702e-03,
            1.11906014e-03, 1.19386315e-03,   1.25779004e-03,   1.31037519e-03,
            1.35108872e-03,   1.37958003e-03,   1.39570542e-03, 1.39927441e-03,
            1.39033118e-03,   1.36892681e-03, 1.33533475e-03,   1.28987173e-03,
            1.23311389e-03, 1.16551418e-03,   1.08773037e-03,   1.00059786e-03,
            9.04879918e-04,   8.01551710e-04,   6.91575582e-04, 5.75952750e-04,
            4.55756793e-04,   3.32302985e-04, 2.06487043e-04,   7.95882588e-05,
            -4.72208138e-05, -1.72823958e-04,  -2.96101535e-04,  -4.15925168e-04,
            -5.31250383e-04,  -6.41017819e-04,  -7.44349685e-04, -8.40276057e-04,
            -9.28032591e-04,  -1.00688055e-03, -1.07610640e-03,  -1.13518206e-03,
            -1.18370702e-03, -1.22129557e-03,  -1.24764964e-03,  -1.26264035e-03,
            -1.26627364e-03,  -1.25857717e-03,  -1.23964021e-03,
            -1.20980891e-03,  -1.16944284e-03,  -1.11887385e-03,
            -1.05870668e-03,  -9.89617769e-04,  -9.12311681e-04,
            -8.27560752e-04,  -7.36170045e-04,  -6.39042153e-04,
            -5.37114997e-04,  -4.31247869e-04,  -3.22637131e-04,
            -2.12194968e-04,  -1.00869243e-04,   1.03136916e-05,
            1.20241207e-04,   2.27979265e-04,   3.32675130e-04,
            4.33323979e-04,   5.29105666e-04,   6.19142445e-04,
            7.02728753e-04,   7.79114404e-04,   8.47787258e-04,
            9.08216047e-04,   9.59821724e-04,   1.00228122e-03,
            1.03538392e-03,   1.05880009e-03,   1.07260841e-03,
            1.07662550e-03,   1.07093155e-03,   1.05577003e-03,
            1.03129797e-03,   9.97904596e-04,   9.55975595e-04,
            9.05955028e-04,   8.48396342e-04,   7.83925297e-04,
            7.13242537e-04,   6.36896396e-04,   5.55809454e-04,
            4.70697276e-04,   3.82464668e-04,   2.91766220e-04,
            1.99564879e-04,   1.06707654e-04,   1.40463177e-05,
            -7.76333806e-05,  -1.67470574e-04,  -2.54708122e-04,
            -3.38623857e-04,  -4.18484684e-04])
        difference_exp = difference_exp/np.max(difference_exp)
        np.testing.assert_allclose(difference_exp, difference,
                                   rtol=rtol, atol=atol,
                                   err_msg='In TestBeamFeedback test_SPS_RL: difference between simulated and analytic result different than expected')
# Define RF station parameters and corresponding tracker
beam = Beam(general_params, N_p, N_b)
rf_params_1 = RFStation(general_params, [h], [V1], [dphi],
                                  section_index=1)
long_tracker_1 = RingAndRFTracker(rf_params_1, beam)

rf_params_2 = RFStation(general_params, [h], [V2], [dphi],
                                  section_index=2)
long_tracker_2 = RingAndRFTracker(rf_params_2, beam)

# Define full voltage over one turn and a corresponding "overall" set of 
#parameters, which is used for the separatrix (in plotting and losses)
Vtot = total_voltage([rf_params_1, rf_params_2])
rf_params_tot = RFStation(general_params, [h], [Vtot], [dphi])
beam_dummy = Beam(general_params, 1, N_b)
long_tracker_tot = RingAndRFTracker(rf_params_tot, beam_dummy)

print("General and RF parameters set...")


# Define beam and distribution

bigaussian(general_params, rf_params_tot, beam, tau_0/4, 
                              reinsertion = 'on', seed=1)

print("Beam set and distribution generated...")


# Need slices for the Gaussian fit; slice for the first plot
slice_beam = Profile(beam, CutOptions(n_slices=100),
                 FitOptions(fit_option='gaussian'))