Ejemplo n.º 1
0
 def test_wakefield_wakefile(self):
     '''
     Track an LHC bunch and a LHC wakefield
     '''
     wakefile = 'autoruntests/wake_table.dat'  #'./wakeforhdtl_PyZbase_Allthemachine_450GeV_B1_LHC_inj_450GeV_B1.dat'
     Qp_x, Qp_y = 1., 1.
     Q_s = 0.0049
     n_macroparticles = 10
     intensity = 1e11
     longitudinal_focusing = 'linear'
     machine = m.LHC(n_segments=1,
                     machine_configuration='450GeV',
                     longitudinal_focusing=longitudinal_focusing,
                     Qp_x=[Qp_x],
                     Qp_y=[Qp_y],
                     Q_s=Q_s,
                     beta_x=[65.9756],
                     beta_y=[71.5255],
                     printer=SilentPrinter())
     epsn_x = 3.5e-6
     epsn_y = 3.5e-6
     sigma_z = 1.56e-9 * c / 4.
     np.random.seed(0)
     bunch_cpu = machine.generate_6D_Gaussian_bunch(n_macroparticles,
                                                    intensity,
                                                    epsn_x,
                                                    epsn_y,
                                                    sigma_z=sigma_z)
     np.random.seed(0)
     bunch_gpu = machine.generate_6D_Gaussian_bunch(n_macroparticles,
                                                    intensity,
                                                    epsn_x,
                                                    epsn_y,
                                                    sigma_z=sigma_z)
     n_slices_wakefields = 55
     n_sigma_z_wakefields = 3
     slicer_for_wakefields_cpu = UniformBinSlicer(
         n_slices_wakefields, n_sigma_z=n_sigma_z_wakefields)
     wake_components = [
         'time', 'dipole_x', 'dipole_y', 'no_quadrupole_x',
         'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
     ]
     wake_table_cpu = WakeTable(wakefile,
                                wake_components,
                                printer=SilentPrinter())
     wake_field_cpu = WakeField(slicer_for_wakefields_cpu, wake_table_cpu)
     # also checked for 100 turns!
     self.assertTrue(
         self._track_cpu_gpu([wake_field_cpu],
                             bunch_cpu,
                             bunch_gpu,
                             nturns=2),
         'Tracking through WakeField(waketable) differs')
Ejemplo n.º 2
0
# SLICER FOR WAKEFIELDS
# =====================
n_slices = 500  # 500
slicer_for_wakefields = UniformBinSlicer(
    n_slices,
    z_cuts=(-4. * sigma_z,
            4. * sigma_z))  #,circumference=circumference, h_bunch=h1)

# WAKEFIELD
# ==========
n_turns_wake = 1  # for the moment we consider that the wakefield decays after 1 turn
wakefile1 = (
    '/afs/cern.ch/work/n/natriant/private/pyheadtail_example_crabcavity/wakefields/SPS_complete_wake_model_2018_Q26.txt'
)
ww1 = WakeTable(
    wakefile1,
    ['time', 'dipole_x', 'dipole_y', 'quadrupole_x', 'quadrupole_y'],
    n_turns_wake=n_turns_wake)
# only dipolar kick
#my_length = len(ww1.wake_table['quadrupole_x'])
#ww1.wake_table['quadrupole_x'] = np.zeros(my_length)
#ww1.wake_table['quadrupole_y'] = np.zeros(my_length)

# only quadrupolar kick
#my_length = len(ww1.wake_table['dipole_x'])
#ww1.wake_table['dipole_x'] = np.zeros(my_length)
#ww1.wake_table['dipole_y'] = np.zeros(my_length)

wake_field_complete = WakeField(slicer_for_wakefields,
                                ww1)  #, beta_x=beta_x, beta_y=beta_y)

# CREATE TRANSVERSE AND LONGITUDINAL MAPS
def run(intensity, chroma=0, i_oct=0):
    '''Arguments:
        - intensity: integer number of charges in beam
        - chroma: first-order chromaticity Q'_{x,y}, identical
          for both transverse planes
        - i_oct: octupole current in A (positive i_oct means
          LOF = i_oct > 0 and LOD = -i_oct < 0)
    '''

    # BEAM AND MACHINE PARAMETERS
    # ============================
    from LHC import LHC
    # energy set above will enter get_nonlinear_params p0
    assert machine_configuration == 'LHC-injection'
    machine = LHC(n_segments=1,
                  machine_configuration=machine_configuration,
                  **get_nonlinear_params(chroma=chroma,
                                         i_oct=i_oct,
                                         p0=0.45e12 * e / c))

    # BEAM
    # ====
    epsn_x = 3.e-6  # normalised horizontal emittance
    epsn_y = 3.e-6  # normalised vertical emittance
    sigma_z = 1.2e-9 * machine.beta * c / 4.  # RMS bunch length in meters

    bunch = machine.generate_6D_Gaussian_bunch(n_macroparticles,
                                               intensity,
                                               epsn_x,
                                               epsn_y,
                                               sigma_z=sigma_z,
                                               matched=True)

    print("\n--> Bunch length and emittance: {:g} m, {:g} eVs.".format(
        bunch.sigma_z(), bunch.epsn_z()))

    # CREATE BEAM SLICERS
    # ===================
    slicer_for_slicemonitor = UniformBinSlicer(50,
                                               z_cuts=(-3 * sigma_z,
                                                       3 * sigma_z))
    slicer_for_wakefields = UniformBinSlicer(
        50,
        z_cuts=(-3 * sigma_z, 3 * sigma_z),
        circumference=machine.circumference,
        h_bunch=machine.h_bunch)
    print("Slice")

    # CREATE WAKES
    # ============
    wake_table1 = WakeTable(
        wakefile,
        [
            'time',
            'dipole_x',
            'dipole_y',
            # 'quadrupole_x', 'quadrupole_y',
            'noquadrupole_x',
            'noquadrupole_y',
            # 'dipole_xy', 'dipole_yx',
            'nodipole_xy',
            'nodipole_yx',
        ])
    wake_field = WakeField(slicer_for_wakefields, wake_table1, mpi=True)

    # CREATE DAMPER
    # =============
    dampingtime = 50.
    gain = 2. / dampingtime
    damper = IdealBunchFeedback(gain)

    # CREATE MONITORS
    # ===============
    try:
        bucket = machine.longitudinal_map.get_bucket(bunch)
    except AttributeError:
        bucket = machine.rfbucket

    simulation_parameters_dict = {
        'gamma': machine.gamma,
        'intensity': intensity,
        'Qx': machine.Q_x,
        'Qy': machine.Q_y,
        'Qs': bucket.Q_s,
        'beta_x': bunch.beta_Twiss_x(),
        'beta_y': bunch.beta_Twiss_y(),
        'beta_z': bucket.beta_z,
        'epsn_x': bunch.epsn_x(),
        'epsn_y': bunch.epsn_y(),
        'sigma_z': bunch.sigma_z(),
    }
    bunchmonitor = BunchMonitor(
        outputpath + '/bunchmonitor_{:04d}_chroma={:g}'.format(it, chroma),
        n_turns,
        simulation_parameters_dict,
        write_buffer_to_file_every=512,
        buffer_size=4096)
    slicemonitor = SliceMonitor(
        outputpath + '/slicemonitor_{:04d}_chroma={:g}'.format(it, chroma),
        n_turns_slicemon,
        slicer_for_slicemonitor,
        simulation_parameters_dict,
        write_buffer_to_file_every=1,
        buffer_size=n_turns_slicemon)

    # TRACKING LOOP
    # =============
    # machine.one_turn_map.append(damper)
    machine.one_turn_map.append(wake_field)

    # for slice statistics monitoring:
    s_cnt = 0
    monitorswitch = False

    print('\n--> Begin tracking...\n')

    # GO!!!
    for i in range(n_turns):

        t0 = time.clock()

        # track the beam around the machine for one turn:
        machine.track(bunch)

        ex, ey, ez = bunch.epsn_x(), bunch.epsn_y(), bunch.epsn_z()
        mx, my, mz = bunch.mean_x(), bunch.mean_y(), bunch.mean_z()

        # monitor the bunch statistics (once per turn):
        bunchmonitor.dump(bunch)

        # if the centroid becomes unstable (>1cm motion)
        # then monitor the slice statistics:
        if not monitorswitch:
            if mx > 1e-2 or my > 1e-2 or i > n_turns - n_turns_slicemon:
                print("--> Activate slice monitor")
                monitorswitch = True
        else:
            if s_cnt < n_turns_slicemon:
                slicemonitor.dump(bunch)
                s_cnt += 1

        # stop the tracking as soon as we have not-a-number values:
        if not all(np.isfinite(c) for c in [ex, ey, ez, mx, my, mz]):
            print('*** STOPPING SIMULATION: non-finite bunch stats!')
            break

        # print status all 1000 turns:
        if i % 100 == 0:
            t1 = time.clock()
            print('Emittances: ({:.3g}, {:.3g}, {:.3g}) '
                  '& Centroids: ({:.3g}, {:.3g}, {:.3g})'
                  '@ turn {:d}, {:g} ms, {:s}'.format(
                      ex, ey, ez, mx, my, mz, i, (t1 - t0) * 1e3,
                      time.strftime("%d/%m/%Y %H:%M:%S", time.localtime())))

    print('\n*** Successfully completed!')
Ejemplo n.º 4
0
def run():
    def track_n_save(bunch, map_):
        mean_x = np.empty(n_turns)
        mean_y = np.empty(n_turns)
        sigma_z = np.empty(n_turns)

        for i in xrange(n_turns):
            mean_x[i] = bunch.mean_x()
            mean_y[i] = bunch.mean_y()
            sigma_z[i] = bunch.sigma_z()

            for m_ in map_:
                m_.track(bunch)

        return mean_x, mean_y, sigma_z

    def my_fft(data):
        t = np.arange(len(data))
        fft = np.fft.rfft(data)
        fft_freq = np.fft.rfftfreq(t.shape[-1])

        return fft_freq, np.abs(fft.real)

    def generate_bunch(n_macroparticles, alpha_x, alpha_y, beta_x, beta_y,
                       linear_map):

        intensity = 1.05e11
        sigma_z = 0.059958
        gamma = 3730.26
        p0 = np.sqrt(gamma**2 - 1) * m_p * c

        beta_z = (linear_map.eta(dp=0, gamma=gamma) *
                  linear_map.circumference / (2 * np.pi * linear_map.Q_s))

        epsn_x = 3.75e-6  # [m rad]
        epsn_y = 3.75e-6  # [m rad]
        epsn_z = 4 * np.pi * sigma_z**2 * p0 / (beta_z * e)

        bunch = generators.generate_Gaussian6DTwiss(
            macroparticlenumber=n_macroparticles,
            intensity=intensity,
            charge=e,
            gamma=gamma,
            mass=m_p,
            circumference=C,
            alpha_x=alpha_x,
            beta_x=beta_x,
            epsn_x=epsn_x,
            alpha_y=alpha_y,
            beta_y=beta_y,
            epsn_y=epsn_y,
            beta_z=beta_z,
            epsn_z=epsn_z)
        # print ('bunch sigma_z=' + bunch.sigma_z())

        return bunch

    def track_n_show(bunch, slicer, map_woWakes, wake_field):
        fig, ((ax1, ax2)) = plt.subplots(2, 1, figsize=(16, 16))

        xp_diff = np.zeros(n_macroparticles)

        for i in xrange(n_turns):
            for m_ in map_woWakes:
                m_.track(bunch)

            # Dipole X kick.
            if i == (n_turns - 1):
                xp_old = bunch.xp.copy()
            wake_field.track(bunch)

            if i == (n_turns - 1):
                xp_diff[:] = bunch.xp[:] - xp_old[:]

        # Plot bunch.z vs. slice index of particle. Mark particles within
        # z cuts in green.
        nsigmaz_lbl = ' (nsigmaz =' + str(n_sigma_z) + ')'

        slice_set = bunch.get_slices(slicer)
        pidx = slice_set.particles_within_cuts
        slidx = slice_set.slice_index_of_particle

        z_cut_tail, z_cut_head = slice_set.z_cut_tail, slice_set.z_cut_head

    # In[4]:
    # Basic parameters.
    n_turns = 10
    n_segments = 1
    n_macroparticles = 50

    Q_x = 64.28
    Q_y = 59.31
    Q_s = 0.0020443

    C = 26658.883
    R = C / (2. * np.pi)

    alpha_x_inj = 0.
    alpha_y_inj = 0.
    beta_x_inj = 66.0064
    beta_y_inj = 71.5376
    alpha_0 = [0.0003225]

    #waketable filename
    fn = os.path.join(os.path.dirname(__file__), 'wake_table.dat')
    # In[5]:

    # Parameters for transverse map.
    s = np.arange(0, n_segments + 1) * C / n_segments

    alpha_x = alpha_x_inj * np.ones(n_segments)
    beta_x = beta_x_inj * np.ones(n_segments)
    D_x = np.zeros(n_segments)

    alpha_y = alpha_y_inj * np.ones(n_segments)
    beta_y = beta_y_inj * np.ones(n_segments)
    D_y = np.zeros(n_segments)

    # In[6]:

    # In[7]:

    # In[8]:

    # CASE TEST SETUP
    trans_map = TransverseMap(s, alpha_x, beta_x, D_x, alpha_y, beta_y, D_y,
                              Q_x, Q_y)
    long_map = LinearMap(alpha_0, C, Q_s)

    bunch = generate_bunch(n_macroparticles, alpha_x_inj, alpha_y_inj,
                           beta_x_inj, beta_y_inj, long_map)

    # In[9]:

    # CASE I
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # DIPOLE X, UniformBinSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'dipole_x', 'no_dipole_y', 'no_quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_bin_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[10]:

    # CASE II
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # DIPOLE X, UniformChargeSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_charge_slicer = UniformChargeSlicer(n_slices=n_slices,
                                                n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'dipole_x', 'no_dipole_y', 'no_quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_charge_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[11]:

    # CASE III
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # Quadrupole X, UniformChargeSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_charge_slicer = UniformChargeSlicer(n_slices=n_slices,
                                                n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'no_dipole_x', 'no_dipole_y', 'quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_charge_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[12]:

    # CASE IV
    # Transverse and long. tracking (linear), and wakes from WakeTable source.
    # Quadrupole X, UniformBinSlicer

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    wake_file_columns = [
        'time', 'no_dipole_x', 'no_dipole_y', 'quadrupole_x',
        'no_quadrupole_y', 'no_dipole_xy', 'no_dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())
    wake_field = WakeField(uniform_bin_slicer, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[15]:

    # CASE V
    # Transverse and long. tracking (linear),
    # Resonator circular

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson_circ = CircularResonator(R_shunt=1e6, frequency=1e8, Q=1)
    wake_field = WakeField(uniform_bin_slicer, reson_circ)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[16]:

    # CASE V b.
    # Transverse and long. tracking (linear),
    # Several Resonators circular

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson_circ = CircularResonator(R_shunt=1e6, frequency=1e8, Q=1)
    reson_circ2 = CircularResonator(R_shunt=1e6, frequency=1e9, Q=0.8)
    reson_circ3 = CircularResonator(R_shunt=5e6, frequency=1e6, Q=0.2)

    wake_field = WakeField(uniform_bin_slicer, reson_circ, reson_circ2,
                           reson_circ3)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[17]:

    # CASE V c.
    # Transverse and long. tracking (linear),
    # Resonator parallel_plates

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson_para = ParallelPlatesResonator(R_shunt=1e6, frequency=1e8, Q=1)
    wake_field = WakeField(uniform_bin_slicer, reson_para)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[18]:

    # CASE V d.
    # Transverse and long. tracking (linear),
    # Resonator w. longitudinal wake

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    reson = Resonator(R_shunt=1e6,
                      frequency=1e8,
                      Q=1,
                      Yokoya_X1=1,
                      Yokoya_X2=1,
                      Yokoya_Y1=1,
                      Yokoya_Y2=1,
                      switch_Z=True)
    wake_field = WakeField(uniform_bin_slicer, reson)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[19]:

    # CASE VI
    # Transverse and long. tracking (linear),
    # ResistiveWall circular

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    resis_circ = CircularResistiveWall(pipe_radius=5e-2,
                                       resistive_wall_length=C,
                                       conductivity=1e6,
                                       dt_min=1e-3)
    wake_field = WakeField(uniform_bin_slicer, resis_circ)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[20]:

    # CASE VI b.
    # Transverse and long. tracking (linear),
    # ResistiveWall parallel_plates

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    resis_para = ParallelPlatesResistiveWall(pipe_radius=5e-2,
                                             resistive_wall_length=C,
                                             conductivity=1e6,
                                             dt_min=1e-3)
    wake_field = WakeField(uniform_bin_slicer, resis_para)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)

    # In[21]:

    # CASE VII.
    # Transverse and long. tracking (linear),
    # Pass mixture of WakeSources to define WakeField.

    n_sigma_z = 2
    n_slices = 15
    uniform_bin_slicer = UniformBinSlicer(n_slices=n_slices,
                                          n_sigma_z=n_sigma_z)

    # Definition of WakeField as a composition of different sources.
    resis_circ = CircularResistiveWall(pipe_radius=5e-2,
                                       resistive_wall_length=C,
                                       conductivity=1e6,
                                       dt_min=1e-3)
    reson_para = ParallelPlatesResonator(R_shunt=1e6, frequency=1e8, Q=1)
    wake_file_columns = [
        'time', 'dipole_x', 'dipole_y', 'quadrupole_x', 'quadrupole_y',
        'dipole_xy', 'dipole_yx'
    ]
    table = WakeTable(fn,
                      wake_file_columns,
                      printer=SilentPrinter(),
                      warningprinter=SilentPrinter())

    wake_field = WakeField(uniform_bin_slicer, resis_circ, reson_para, table)

    trans_map = [m for m in trans_map]
    map_woWakes = trans_map + [long_map]

    track_n_save(bunch, map_woWakes)
Ejemplo n.º 5
0
def run(intensity, chroma=0, i_oct=0):
    '''Arguments:
        - intensity: integer number of charges in beam
        - chroma: first-order chromaticity Q'_{x,y}, identical
          for both transverse planes
        - i_oct: octupole current in A (positive i_oct means
          LOF = i_oct > 0 and LOD = -i_oct < 0)
    '''

    # BEAM AND MACHINE PARAMETERS
    # ============================
    from LHC import LHC
    # energy set above will enter get_nonlinear_params p0
    assert machine_configuration == 'LHC-injection'
    machine = LHC(n_segments=1,
                  machine_configuration=machine_configuration,
                  **get_nonlinear_params(chroma=chroma,
                                         i_oct=i_oct,
                                         p0=0.45e12 * e / c))

    # BEAM
    # ====

    #print(filling_scheme)

    epsn_x = 3.e-6  # normalised horizontal emittance
    epsn_y = 3.e-6  # normalised vertical emittance
    sigma_z = 1.2e-9 * machine.beta * c / 4.  # RMS bunch length in meters

    beam = machine.generate_6D_Gaussian_bunch(n_macroparticles,
                                              intensity,
                                              epsn_x,
                                              epsn_y,
                                              sigma_z=sigma_z,
                                              matched=True,
                                              filling_scheme=filling_scheme)

    bunch_list = beam.split_to_views()

    for b in bunch_list:
        if b.bucket_id[0] < batch_length:
            b.x += 1e-3
            b.y += 1e-3

    bunch = bunch_list[0]

    print("\n--> Bunch length and emittance: {:g} m, {:g} eVs.".format(
        bunch.sigma_z(), bunch.epsn_z()))

    # CREATE BEAM SLICERS
    # ===================
    slicer_for_slicemonitor = UniformBinSlicer(50,
                                               z_cuts=(-3 * sigma_z,
                                                       3 * sigma_z))
    slicer_for_wakefields = UniformBinSlicer(
        50,
        z_cuts=(-3 * sigma_z, 3 * sigma_z),
        circumference=machine.circumference,
        h_bunch=machine.h_bunch)

    # CREATE WAKES
    # ============
    wake_table1 = WakeTable(
        wakefile,
        [
            'time',
            'dipole_x',
            'dipole_y',
            # 'quadrupole_x', 'quadrupole_y',
            'noquadrupole_x',
            'noquadrupole_y',
            # 'dipole_xy', 'dipole_yx',
            'nodipole_xy',
            'nodipole_yx',
        ])
    wake_field = WakeField(slicer_for_wakefields,
                           wake_table1,
                           mpi='linear_mpi_full_ring_fft')

    # CREATE DAMPER
    # =============
    from PyHEADTAIL_feedback.feedback import OneboxFeedback
    from PyHEADTAIL_feedback.processors.multiplication import ChargeWeighter
    from PyHEADTAIL_feedback.processors.register import TurnFIRFilter
    from PyHEADTAIL_feedback.processors.convolution import Lowpass, FIRFilter
    from PyHEADTAIL_feedback.processors.resampling import DAC, HarmonicADC, BackToOriginalBins, Upsampler
    from MD4063_filter_functions import calculate_coefficients_3_tap, calculate_hilbert_notch_coefficients
    #    from PyHEADTAIL_feedback.processors.addition import NoiseGenerator

    dampingtime = 20.
    gain = 2. / dampingtime

    lowpass100kHz = [
        1703, 1169, 1550, 1998, 2517, 3108, 3773, 4513, 5328, 6217, 7174, 8198,
        9282, 10417, 11598, 12813, 14052, 15304, 16555, 17793, 19005, 20176,
        21294, 22345, 23315, 24193, 24969, 25631, 26171, 26583, 26860, 27000,
        27000, 26860, 26583, 26171, 25631, 24969, 24193, 23315, 22345, 21294,
        20176, 19005, 17793, 16555, 15304, 14052, 12813, 11598, 10417, 9282,
        8198, 7174, 6217, 5328, 4513, 3773, 3108, 2517, 1998, 1550, 1169, 1703
    ]

    lowpassEnhanced = [
        490, 177, -478, -820, -370, 573, 1065, 428, -909, -1632, -799, 1015,
        2015, 901, -1592, -3053, -1675, 1642, 3670, 1841, -2828, -6010, -3929,
        2459, 7233, 4322, -6384, -17305, -18296, -5077, 16097, 32000, 32000,
        16097, -5077, -18296, -17305, -6384, 4322, 7233, 2459, -3929, -6010,
        -2828, 1841, 3670, 1642, -1675, -3053, -1592, 901, 2015, 1015, -799,
        -1632, -909, 428, 1065, 573, -370, -820, -478, 177, 490
    ]

    lowpass20MHz = [
        38, 118, 182, 112, -133, -389, -385, -45, 318, 257, -259, -665, -361,
        473, 877, 180, -996, -1187, 162, 1670, 1329, -954, -2648, -1219, 2427,
        4007, 419, -5623, -6590, 2893, 19575, 32700, 32700, 19575, 2893, -6590,
        -5623, 419, 4007, 2427, -1219, -2648, -954, 1329, 1670, 162, -1187,
        -996, 180, 877, 473, -361, -665, -259, 257, 318, -45, -385, -389, -133,
        112, 182, 118, 38
    ]

    phaseEqualizer = [
        2, 4, 7, 10, 12, 16, 19, 22, 27, 31, 36, 42, 49, 57, 67, 77, 90, 104,
        121, 141, 164, 191, 223, 261, 305, 358, 422, 498, 589, 700, 836, 1004,
        1215, 1483, 1832, 2301, 2956, 3944, 5600, 9184, 25000, -16746, -4256,
        -2056, -1195, -769, -523, -372, -271, -202, -153, -118, -91, -71, -56,
        -44, -34, -27, -20, -15, -11, -7, -4, -1
    ]

    FIR_phase_filter = np.loadtxt(
        './injection_error_input_data/FIR_Phase_40MSPS.csv')
    FIR_phase_filter = np.array(phaseEqualizer)
    FIR_phase_filter = FIR_phase_filter / float(np.sum(FIR_phase_filter))

    FIR_gain_filter = np.array(lowpass20MHz)
    FIR_gain_filter = FIR_gain_filter / float(np.sum(lowpass20MHz))

    # Cut-off frequency of the kicker system
    fc = 1.0e6
    ADC_bits = 16
    ADC_range = (-1e-3, 1e-3)

    # signal processing delay in turns before the first measurements is applied
    delay = 1
    extra_adc_bins = 10
    # betatron phase advance between the pickup and the kicker. The value 0.25
    # corresponds to the 90 deg phase change from from the pickup measurements
    # in x-plane to correction kicks in xp-plane.

    additional_phase = 0.25  # Kicker-to-pickup phase advance 0 deg
    #    additional_phase = 0. # Kicker-to-pickup phase advance 90 deg

    f_RF = 1. / (machine.circumference / c / (float(machine.h_RF)))
    #    turn_phase_filter_x = calculate_hilbert_notch_coefficients(machine.Q_x, delay, additional_phase)
    #    turn_phase_filter_y = calculate_hilbert_notch_coefficients(machine.Q_y, delay, additional_phase)

    turn_phase_filter_x = calculate_coefficients_3_tap(machine.Q_x, delay,
                                                       additional_phase)
    turn_phase_filter_y = calculate_coefficients_3_tap(machine.Q_y, delay,
                                                       additional_phase)

    print('f_RF: ' + str(f_RF))

    processors_detailed_x = [
        Bypass(),
        ChargeWeighter(normalization='segment_average'),
        #         NoiseGenerator(RMS_noise_level, debug=False),
        HarmonicADC(1 * f_RF / 10.,
                    ADC_bits,
                    ADC_range,
                    n_extras=extra_adc_bins),
        TurnFIRFilter(turn_phase_filter_x, machine.Q_x, delay=delay),
        FIRFilter(FIR_phase_filter, zero_tap=40),
        Upsampler(3, [1.5, 1.5, 0]),
        FIRFilter(FIR_gain_filter, zero_tap=34),
        DAC(ADC_bits, ADC_range),
        Lowpass(fc, f_cutoff_2nd=10 * fc),
        BackToOriginalBins(),
    ]

    processors_detailed_y = [
        Bypass(),
        ChargeWeighter(normalization='segment_average'),
        #         NoiseGenerator(RMS_noise_level, debug=False),
        HarmonicADC(1 * f_RF / 10.,
                    ADC_bits,
                    ADC_range,
                    n_extras=extra_adc_bins),
        TurnFIRFilter(turn_phase_filter_y, machine.Q_y, delay=delay),
        FIRFilter(FIR_phase_filter, zero_tap=40),
        Upsampler(3, [1.5, 1.5, 0]),
        FIRFilter(FIR_gain_filter, zero_tap=34),
        DAC(ADC_bits, ADC_range),
        Lowpass(fc, f_cutoff_2nd=10 * fc),
        BackToOriginalBins(),
    ]

    # Kicker-to-pickup phase advance 0 deg
    damper = OneboxFeedback(gain,
                            slicer_for_wakefields,
                            processors_detailed_x,
                            processors_detailed_y,
                            pickup_axis='displacement',
                            kicker_axis='divergence',
                            mpi=True,
                            beta_x=machine.beta_x,
                            beta_y=machine.beta_y)

    #    # Kicker-to-pickup phase advance 90 deg
    #    damper = OneboxFeedback(gain,slicer_for_wakefields,
    #                                  processors_detailed_x,processors_detailed_y, mpi=True,
    #                            pickup_axis='displacement', kicker_axis='displacement')

    # CREATE MONITORS
    # ===============

    try:
        bucket = machine.longitudinal_map.get_bucket(bunch)
    except AttributeError:
        bucket = machine.rfbucket

    simulation_parameters_dict = {
        'gamma': machine.gamma,
        'intensity': intensity,
        'Qx': machine.Q_x,
        'Qy': machine.Q_y,
        'Qs': bucket.Q_s,
        'beta_x': bunch.beta_Twiss_x(),
        'beta_y': bunch.beta_Twiss_y(),
        'beta_z': bucket.beta_z,
        'epsn_x': bunch.epsn_x(),
        'epsn_y': bunch.epsn_y(),
        'sigma_z': bunch.sigma_z(),
    }
    bunchmonitor = BunchMonitor(
        outputpath + '/bunchmonitor_{:04d}_chroma={:g}'.format(it, chroma),
        n_turns,
        simulation_parameters_dict,
        write_buffer_to_file_every=512,
        buffer_size=4096,
        mpi=True,
        filling_scheme=filling_scheme)
    #    slicemonitor = SliceMonitor(
    #        outputpath+'/slicemonitor_{:04d}_chroma={:g}_bunch_{:04d}'.format(it, chroma, bunch.bucket_id[0]),
    #        n_turns_slicemon,
    #        slicer_for_slicemonitor, simulation_parameters_dict,
    #        write_buffer_to_file_every=1, buffer_size=n_turns_slicemon)

    # TRACKING LOOP
    # =============
    machine.one_turn_map.append(damper)
    machine.one_turn_map.append(wake_field)

    # for slice statistics monitoring:
    s_cnt = 0
    monitorswitch = False

    print('\n--> Begin tracking...\n')

    # GO!!!
    for i in range(n_turns):

        t0 = time.clock()

        # track the beam around the machine for one turn:
        machine.track(beam)

        bunch_list = beam.split_to_views()
        bunch = bunch_list[0]

        ex, ey, ez = bunch.epsn_x(), bunch.epsn_y(), bunch.epsn_z()
        mx, my, mz = bunch.mean_x(), bunch.mean_y(), bunch.mean_z()

        # monitor the bunch statistics (once per turn):
        bunchmonitor.dump(beam)

        # if the centroid becomes unstable (>1cm motion)
        # then monitor the slice statistics:
        if not monitorswitch:
            if mx > 1e-2 or my > 1e-2 or i > n_turns - n_turns_slicemon:
                print("--> Activate slice monitor")
                monitorswitch = True
        else:
            if s_cnt < n_turns_slicemon:
                #                slicemonitor.dump(bunch)
                s_cnt += 1

        # stop the tracking as soon as we have not-a-number values:
        if not all(np.isfinite(c) for c in [ex, ey, ez, mx, my, mz]):
            print('*** STOPPING SIMULATION: non-finite bunch stats!')
            break

        # print status all 1000 turns:
        if i % 100 == 0:
            t1 = time.clock()
            print('Emittances: ({:.3g}, {:.3g}, {:.3g}) '
                  '& Centroids: ({:.3g}, {:.3g}, {:.3g})'
                  '@ turn {:d}, {:g} ms, {:s}'.format(
                      ex, ey, ez, mx, my, mz, i, (t1 - t0) * 1e3,
                      time.strftime("%d/%m/%Y %H:%M:%S", time.localtime())))

    print('\n*** Successfully completed!')
# SLICER FOR WAKEFIELDS
# ============
n_slices = 500
n_sigma = 3.
slicer_for_wakefields = UniformBinSlicer(
    n_slices,
    z_cuts=(-n_sigma * sigma_z,
            n_sigma * sigma_z))  #,circumference=circumference, h_bunch=h1)

# WAKEFIELD
# ==========
n_turns_wake = 1  # for the moment we consider that the wakefield decays after 1 turn
wakefile1 = ('SPS_complete_wake_model_2018_Q26.txt')

ww1 = WakeTable(
    wakefile1,
    ['time', 'dipole_x', 'dipole_y', 'quadrupole_x', 'quadrupole_y'],
    n_turns_wake=n_turns_wake)

# only dipolar kick
my_length = len(ww1.wake_table['quadrupole_x'])
ww1.wake_table['quadrupole_x'] = np.zeros(my_length)
ww1.wake_table['quadrupole_y'] = np.zeros(my_length)
ww1.wake_table['dipole_x'] = np.zeros(my_length)

#ww1.wake_table['dipole_y'] = ww1.wake_table['dipole_y']*100

wake_field = WakeField(slicer_for_wakefields,
                       ww1)  #, beta_x=beta_x, beta_y=beta_y)

one_turn_map.append(wake_field)
n_slices = 500 # 500
slicer_for_wakefields = UniformBinSlicer(n_slices, z_cuts=(-3.*sigma_z, 3.*sigma_z))#,circumference=circumference, h_bunch=h1)

# WAKEFIELD
# ==========
n_turns_wake = 1 # for the moment we consider that the wakefield decays after 1 turn
#wakefile1 = ('/afs/cern.ch/work/n/natriant/private/pyheadtail_example_crabcavity/wakefields/newkickers_Q26_2018_modified.txt')
#wakefile1 = ('/afs/cern.ch/work/n/natriant/private/pyheadtail_example_crabcavity/wakefields/SPS_complete_wake_model_2018_Q26.txt')


#wakefile1 = ('/afs/cern.ch/work/n/natriant/private/pyheadtail_example_crabcavity/wakefields/step_analytical_wake.txt')
wakefile2 = ('/afs/cern.ch/work/n/natriant/private/pyheadtail_example_crabcavity/wakefields/Analytical_Wall_Q26_270GeV.txt')
wakefile3 = ('/afs/cern.ch/work/n/natriant/private/pyheadtail_example_crabcavity/wakefields/SPS_wake_model_with_EF_BPH_BPV_RF200_RF800_kicker_steps_ZS_2018_Q26.txt')

#ww1 = WakeTable(wakefile1, ['time', 'dipole_y'], n_turns_wake=n_turns_wake)
ww2 = WakeTable(wakefile2, ['time', 'dipole_x', 'dipole_y', 'quadrupole_x', 'quadrupole_y'], n_turns_wake=43)
ww3 = WakeTable(wakefile3, ['time', 'dipole_x', 'dipole_y', 'quadrupole_x', 'quadrupole_y'], n_turns_wake=n_turns_wake)

# multiply with a factor 2

#ww1.wake_table['dipole_y'] = 2*ww1.wake_table['dipole_y'] # for the analytical step wake

ww2.wake_table['dipole_y'] = 1.034*ww2.wake_table['dipole_y'] # for the analytical step wake
ww2.wake_table['dipole_x'] = 1.034*ww2.wake_table['dipole_x'] # for the analytical step wake
ww2.wake_table['quadrupole_y'] = 1.034*ww2.wake_table['quadrupole_y'] # for the analytical step wake
ww2.wake_table['quadrupole_x'] = 1.034*ww2.wake_table['quadrupole_x'] # for the analytical step wake




#wake_field_kicker = WakeField(slicer_for_wakefields, ww1)#, beta_x=beta_x, beta_y=beta_y)