def remove_dipolar_kicks(self):
        temp_lattice = sixtracklib.Elements()
        self.elements
        sixtracklib.Drift(cbuffer=temp_lattice.cbuffer)
        temp_tc_index = temp_lattice.cbuffer.n_objects
        temp_tc = sixtracklib.TriCub(cbuffer=temp_lattice.cbuffer)
        first_ecloud = list(self.tricubs.keys())[0]
        temp_tc.length = self.tricubs[first_ecloud].length
        temp_tc.x_shift = 0.
        temp_tc.y_shift = 0.
        temp_tc.tau_shift = 0.
        temp_tc.dipolar_kick_px = 0.
        temp_tc.dipolar_kick_py = 0.
        temp_tc.dipolar_kick_ptau = 0.

        temp_ps = particles_set = sixtracklib.ParticlesSet()
        particles = particles_set.Particles(num_particles=1)

        temp_part = pysixtrack.Particles(p0c=self.partCO.p0c)
        temp_part.x = 0
        temp_part.px = 0
        temp_part.y = 0
        temp_part.py = 0
        temp_part.tau = 0
        temp_part.ptau = 0
        temp_part.state = 1
        temp_part.partid = 0
        temp_part.elemid = 0
        temp_part.turn = 0
        particles.from_pysixtrack(temp_part, 0)

        temp_job = sixtracklib.TrackJob(temp_lattice, temp_ps, device=None)
        temp_tricub_data_buffer_id = temp_job.add_stored_buffer(
            cbuffer=self.tricub_data_buffer)

        first_tricub_data = list(self.tricub_data.keys())[0]
        sixtracklib.TriCub_buffer_create_assign_address_item(
            temp_job, temp_tc_index, temp_tricub_data_buffer_id,
            self.tricub_data_indices[first_tricub_data])
        temp_job.commit_address_assignments()
        temp_job.assign_all_addresses()

        temp_job.track_until(1)

        dipolar_kick_px = particles.px[0]
        dipolar_kick_py = particles.py[0]
        dipolar_kick_ptau = particles.ptau[0]
        print(dipolar_kick_px, dipolar_kick_py, dipolar_kick_ptau)
        #dipolar_kick_px = 0.* particles.px[0]
        #dipolar_kick_py = 0.*particles.py[0]
        #dipolar_kick_ptau = 0.*particles.ptau[0]
        for tc in self.tricubs.keys():
            tc_index = self.tricub_indices[tc]
            tricub = self.job.beam_elements_buffer.get_object(tc_index)
            tricub.dipolar_kick_px = dipolar_kick_px
            tricub.dipolar_kick_py = dipolar_kick_py
            tricub.dipolar_kick_ptau = dipolar_kick_ptau
        self.job.push_beam_elements()

        return
示例#2
0
def get_sixtracklib_particle_set(init_physical_coordinates: np.ndarray,
                                 p0c_ev: float):
    n_particles = init_physical_coordinates.shape[0]
    ps = sixtracklib.ParticlesSet()
    p = ps.Particles(num_particles=n_particles)

    for i_part in range(n_particles):
        part = pysixtrack.Particles(p0c=p0c_ev)

        part.x = init_physical_coordinates[i_part, 0]
        part.px = init_physical_coordinates[i_part, 1]
        part.y = init_physical_coordinates[i_part, 2]
        part.py = init_physical_coordinates[i_part, 3]
        part.tau = init_physical_coordinates[i_part, 4]
        part.ptau = init_physical_coordinates[i_part, 5]

        part.partid = i_part
        part.state = 1
        part.elemid = 0
        part.turn = 0

        p.from_pysixtrack(part, i_part)

    return ps
示例#3
0
        plt.plot(
            cub_absc,
            sc_data0.values,
            "ro",
            z_absc,
            y_exact2,
            "k",
            z_absc,
            y_interp_cub,
            "r-",
        )
        plt.show()

    # -------------------------------------------------------------------------
    # B) Init the particle set
    beam = st.ParticlesSet()
    particles = beam.Particles(num_particles=100, p0c=6.5e12)

    # -------------------------------------------------------------------------
    # C) Build the lattice. We add three interpolated space charge elements
    #    and keep track of the indices at which they are available
    lattice = st.Elements()

    sc0_index = lattice.cbuffer.n_objects  # index of sc0 element
    sc0 = lattice.SCInterpolatedProfile(
        number_of_particles=particles.num_particles)
    dr0 = lattice.Drift(length=1.0)
    q0 = lattice.Multipole(knl=[0.0, 0.1])

    sc1_index = lattice.cbuffer.n_objects  # index of sc1 element
    sc1 = lattice.SCInterpolatedProfile(
import sixtracklib
import pickle

ps = sixtracklib.ParticlesSet().fromfile('./input/sixtracklib.particles')

x = ps.particles[0].x
px = ps.particles[0].px
y = ps.particles[0].y
py = ps.particles[0].py
sigma = ps.particles[0].sigma
delta = ps.particles[0].delta

coordinates = {'x': x, 'px':px, 'y':y, 'py':py, 'sigma':sigma, 'delta':delta}

pickle.dump(coordinates, open('./input/initial_coordinates.pkl', 'wb'))
示例#5
0
def track_particle_sixtracklib(
        line, partCO, Dx_wrt_CO_m, Dpx_wrt_CO_rad,
        Dy_wrt_CO_m, Dpy_wrt_CO_rad,
        Dsigma_wrt_CO_m, Ddelta_wrt_CO, n_turns,
        device=None):

    Dx_wrt_CO_m, Dpx_wrt_CO_rad,\
        Dy_wrt_CO_m, Dpy_wrt_CO_rad,\
        Dsigma_wrt_CO_m, Ddelta_wrt_CO = vectorize_all_coords(
            Dx_wrt_CO_m, Dpx_wrt_CO_rad,
            Dy_wrt_CO_m, Dpy_wrt_CO_rad,
            Dsigma_wrt_CO_m, Ddelta_wrt_CO)

    import sixtracklib
    elements = sixtracklib.Elements()
    elements.BeamMonitor(num_stores=n_turns)
    elements.append_line(line)

    n_part = len(Dx_wrt_CO_m)

    # Build PyST particle

    ps = sixtracklib.ParticlesSet()
    p = ps.Particles(num_particles=n_part)

    for i_part in range(n_part):

        part = partCO.copy()
        part.x += Dx_wrt_CO_m[i_part]
        part.px += Dpx_wrt_CO_rad[i_part]
        part.y += Dy_wrt_CO_m[i_part]
        part.py += Dpy_wrt_CO_rad[i_part]
        part.sigma += Dsigma_wrt_CO_m[i_part]
        part.delta += Ddelta_wrt_CO[i_part]

        part.partid = i_part
        part.state = 1
        part.elemid = 0
        part.turn = 0

        p.from_pysixtrack(part, i_part)

    if device is None:
        job = sixtracklib.TrackJob(elements, ps)
    else:
        job = sixtracklib.TrackJob(elements, ps, device=device)

    job.track_until(n_turns)
    job.collect()

    res = job.output

    x_tbt = res.particles[0].x.reshape(n_turns, n_part)
    px_tbt = res.particles[0].px.reshape(n_turns, n_part)
    y_tbt = res.particles[0].y.reshape(n_turns, n_part)
    py_tbt = res.particles[0].py.reshape(n_turns, n_part)
    sigma_tbt = res.particles[0].sigma.reshape(n_turns, n_part)
    delta_tbt = res.particles[0].delta.reshape(n_turns, n_part)

    # For now data are saved at the end of the turn by STlib and at the beginning by the others
    #x_tbt[1:, :] = x_tbt[:-1, :]
    #px_tbt[1:, :] = px_tbt[:-1, :]
    #y_tbt[1:, :] = y_tbt[:-1, :]
    #py_tbt[1:, :] = py_tbt[:-1, :]
    #sigma_tbt[1:, :] = sigma_tbt[:-1, :]
    #delta_tbt[1:, :] = delta_tbt[:-1, :]
    #x_tbt[0, :] = p.x
    #px_tbt[0, :] = p.px
    #y_tbt[0, :] = p.y
    #py_tbt[0, :] = p.py
    #sigma_tbt[0, :] = p.sigma
    #delta_tbt[0, :] = p.delta

    print('Done loading!')

    return x_tbt, px_tbt, y_tbt, py_tbt, sigma_tbt, delta_tbt
示例#6
0
tc = st.TriCub(cbuffer=lattice.cbuffer)

elem = lattice.Drift(length=2.0)
elem = lattice.LimitRect(xmin=-1.0, xmax=1.0, ymin=-1.0, ymax=1.0)

tc5_index = lattice.cbuffer.n_objects  # Second TriCub element: index 5
tc = st.TriCub(cbuffer=lattice.cbuffer)

elem = lattice.Drift(length=0.5)
elem = lattice.LimitRect(xmin=-0.5, xmax=1.5, ymin=-1.5, ymax=0.5)

tc8_index = lattice.cbuffer.n_objects  # Third TriCub element: index 8
tc = st.TriCub(cbuffer=lattice.cbuffer)

# b) the particle set
particle_sets = st.ParticlesSet()
particles = particle_sets.Particles(num_particles=100)

# ------------------------------------------------------------------------------
# 2) Create the track_job; currently only CPU is supported

job = st.TrackJob(lattice, particle_sets)

# ------------------------------------------------------------------------------
# 3) Create the data buffer for the TriCubData instances and hand it over to
#    the track_job for management:

tricub_data_buffer = CBuffer()

tc_data_0_index = tricub_data_buffer.n_objects
tc_data_0 = st.TriCubData(cbuffer=tricub_data_buffer, nx=100, ny=100, nz=100)
device = 'opencl:0.0'
#device = None
n_part = 1000

seed = np.random.randint(10000)
#seed = 7489
print('Seed is %d:' % seed)
np.random.seed(seed)

lattice = st.Elements()
tc_index = lattice.cbuffer.n_objects
tc = st.TriCub(cbuffer=lattice.cbuffer)
tc.length = 1.0

particles_set = st.ParticlesSet()
particles = particles_set.Particles(num_particles=n_part)

nx = 5
ny = 7
nz = 9
A = np.random.rand(nx, ny, nz, 8) * 1.0e-3
dx = 0.001
dy = 0.002
dz = 0.003
x0 = -(nx // 2) * dx
y0 = -(ny // 2) * dy
z0 = -(nz // 2) * dz

TI = cTI.Tricubic_Interpolation(A=A,
                                dx=dx,
    lattice.Drift(length=0.3)
    lattice.Drift(length=0.4)
    lattice.Drift(length=0.5)
    bm1_index = lattice.cbuffer.n_objects
    lattice.BeamMonitor()
    lattice.Drift(length=0.3)
    lattice.Drift(length=0.4)
    lattice.Drift(length=0.5)
    bm2_index = lattice.cbuffer.n_objects
    lattice.BeamMonitor()

    assert lattice.cbuffer.get_object(bm0_index).out_address == 0
    assert lattice.cbuffer.get_object(bm1_index).out_address == 0
    assert lattice.cbuffer.get_object(bm2_index).out_address == 0

    pset = st.ParticlesSet()
    pset.Particles(num_particles=100)

    output_buffer = st.ParticlesSet()
    out_buffer0_index = output_buffer.cbuffer.n_objects
    output_buffer.Particles(num_particles=100)
    out_buffer1_index = output_buffer.cbuffer.n_objects
    output_buffer.Particles(num_particles=512)

    job = st.TrackJob(lattice, pset)

    # hand the output_buffer over to the track job:
    output_buffer_id = job.add_stored_buffer(cbuffer=output_buffer)
    assert output_buffer_id != st_ARCH_ILLEGAL_BUFFER_ID.value

    # use the predefined lattice_buffer_id value to refer to the
def update_optics(line, eclouds_info, optics, partCO, pinch_path):
    new_optics = optics.copy()
    d = 1.e-10
    init_part = pysixtrack.Particles(**partCO)
    init_part.x += np.array([0., 1. * d, 0., 0., 0., 0., 0.])
    init_part.px += np.array([0., 0., 1. * d, 0., 0., 0., 0.])
    init_part.y += np.array([0., 0., 0., 1. * d, 0., 0., 0.])
    init_part.py += np.array([0., 0., 0., 0., 1. * d, 0., 0.])
    init_part.tau += np.array([0., 0., 0., 0., 0., 1. * d, 0.])
    init_part.ptau += np.array([0., 0., 0., 0., 0., 0., 1. * d])

    n_part = 7

    ps = sixtracklib.ParticlesSet()
    p = ps.Particles(num_particles=n_part)

    for i_part in range(n_part):
        part = pysixtrack.Particles(p0c=init_part.p0c)

        part.x = init_part.x[i_part]
        part.px = init_part.px[i_part]
        part.y = init_part.y[i_part]
        part.py = init_part.py[i_part]
        part.tau = init_part.tau[i_part]
        part.ptau = init_part.ptau[i_part]

        part.partid = i_part
        part.state = 1
        part.elemid = 0
        part.turn = 0

        p.from_pysixtrack(part, i_part)

    ecloud_lattice = LatticeWithEclouds(line, eclouds_info, ps, device=None)
    ecloud_lattice.set_optics_CO(optics, partCO)
    ecloud_lattice.add_tricub_data(pinch_path, 'dipole', max_z=0.05)
    ecloud_lattice.remove_dipolar_kicks()

    tricub_to_tricub_data = {}
    for key in eclouds_info['length'].keys():
        tricub_to_tricub_data[key] = 'dipole'
    ecloud_lattice.finalize_assignments(tricub_to_tricub_data)
    job = ecloud_lattice.job
    job.track_until(1)

    X_init = np.empty([6, 7])
    X_fin = np.empty([6, 7])
    X_init[0, :] = init_part.x
    X_init[1, :] = init_part.px
    X_init[2, :] = init_part.y
    X_init[3, :] = init_part.py
    X_init[4, :] = init_part.tau
    X_init[5, :] = init_part.ptau

    fin_part = pysixtrack.Particles(p0c=init_part.p0c)
    fin_part.x = p.x.flatten()
    fin_part.px = p.px.flatten()
    fin_part.y = p.y.flatten()
    fin_part.py = p.py.flatten()
    fin_part.zeta = p.zeta.flatten()
    fin_part.delta = p.delta.flatten()

    X_fin[0, :] = fin_part.x
    X_fin[1, :] = fin_part.px
    X_fin[2, :] = fin_part.y
    X_fin[3, :] = fin_part.py
    X_fin[4, :] = fin_part.tau
    X_fin[5, :] = fin_part.ptau

    m = X_fin[:, 0] - X_init[:, 0]
    M = np.empty([6, 6])
    for j in range(6):
        M[:, j] = (X_fin[:, j + 1] - X_fin[:, 0]) / d

    Ms = normalization.healy_symplectify(M)
    W, invW, R = normalization.linear_normal_form(Ms)
    q1 = np.arccos(R[0, 0]) / np.pi / 2.
    q2 = np.arccos(R[2, 2]) / np.pi / 2.
    Qs = np.arccos(R[4, 4]) / np.pi / 2.

    new_optics['W'] = W
    new_optics['invW'] = invW
    new_optics['R'] = R
    new_optics['new_Qs'] = Qs
    new_optics['new_q1'] = q1
    new_optics['new_q2'] = q2

    return new_optics
        }, fid)

# save pysixtrack particles
particles = pysixtrack.Particles(p0c=pp.p0c,
                                 x=partCO.x + Dx_wrt_CO,
                                 px=partCO.px + Dpx_wrt_CO,
                                 y=partCO.y + Dy_wrt_CO,
                                 py=partCO.py + Dpy_wrt_CO,
                                 sigma=partCO.sigma + Dsigma_wrt_CO,
                                 delta=partCO.delta + Ddelta_wrt_CO)

with open(pp.input_dir + 'pysixtrack.particles', 'wb') as fid:
    pickle.dump(particles, fid)

# save a sixtracklib particle set
ps = sixtracklib.ParticlesSet()
p = ps.Particles(num_particles=n_macroparticles)

part = partCO.copy()
part.x += Dx_wrt_CO
part.px += Dpx_wrt_CO
part.y += Dy_wrt_CO
part.py += Dpy_wrt_CO
part.sigma += Dsigma_wrt_CO
part.delta += Ddelta_wrt_CO
part.partid = 1
part.state = 1
part.elemid = 0
part.turn = 0

p.from_pysixtrack(part, 0)  # 0 is the particle index
示例#11
0
def track_particle_sixtracklib_firstlast(
                            line, partCO, Dx_wrt_CO_m, Dpx_wrt_CO_rad,
                            Dy_wrt_CO_m, Dpy_wrt_CO_rad,
                            Dsigma_wrt_CO_m, Ddelta_wrt_CO, n_turns,
                            device=None):

    Dx_wrt_CO_m, Dpx_wrt_CO_rad,\
        Dy_wrt_CO_m, Dpy_wrt_CO_rad,\
        Dsigma_wrt_CO_m, Ddelta_wrt_CO = vectorize_all_coords(
                             Dx_wrt_CO_m, Dpx_wrt_CO_rad,
                             Dy_wrt_CO_m, Dpy_wrt_CO_rad,
                             Dsigma_wrt_CO_m, Ddelta_wrt_CO)


    #if type(partCO) is pysixtrack.Particles:
    #    part = partCO.copy()
    #else:
    #    part = pysixtrack.Particles(**partCO)

    n_turns_to_store=1000
    n_turns_tbt=1000
    #skip_turns=1000


    import sixtracklib
    elements=sixtracklib.Elements()
    #sixtracklib.append_beam_monitors_to_lattice(beam_elements_buffer=elements.cbuffer,
    #                                            until_turn_elem_by_elem=0,
    #                                            until_turn_turn_by_turn=n_turns_tbt,
    #                                            until_turn=n_turns,
    #                                            skip_turns=skip_turns
    #                                           )
    elements.BeamMonitor(num_stores=n_turns_tbt,start=0,skip=1,is_rolling=False)
    elements.BeamMonitor(num_stores=n_turns_to_store,start=0,skip=1,is_rolling=True)
    print(elements.get_elements())
    #elements.BeamMonitor(num_stores=n_turns)
    #elements.BeamMonitor(num_stores=n_turns_to_store)
    elements.append_line(line)

    n_stores=elements.get_elements()[1].num_stores
    n_part = len(Dx_wrt_CO_m)

    # Build PyST particle

    ps = sixtracklib.ParticlesSet()
    p = ps.Particles(num_particles=n_part)

    for i_part in range(n_part):

        if type(partCO) is pysixtrack.Particles:
            part = partCO.copy()
        else:
            part = pysixtrack.Particles(**partCO)
        part.x += Dx_wrt_CO_m[i_part]
        part.px += Dpx_wrt_CO_rad[i_part]
        part.y += Dy_wrt_CO_m[i_part]
        part.py += Dpy_wrt_CO_rad[i_part]
        part.sigma += Dsigma_wrt_CO_m[i_part]
        part.delta += Ddelta_wrt_CO[i_part]

        part.partid = i_part
        part.state = 1
        part.elemid = 0
        part.turn = 0

        p.from_pysixtrack(part, i_part)

    if device is None:
        job = sixtracklib.TrackJob(elements, ps)
    else:
        job = sixtracklib.TrackJob(elements, ps, device=device)

    start_tracking_time = time.time()
    job.track(n_turns)
    end_tracking_time = time.time()
    job.collect()
    end_collecting_time = time.time()
    res = job.output

    print(res.particles[0])
    print(res.particles[1])

    x_tbt_first       = res.particles[0].x.reshape(n_turns_tbt,n_part)    
    px_tbt_first      = res.particles[0].px.reshape(n_turns_tbt,n_part)    
    y_tbt_first       = res.particles[0].y.reshape(n_turns_tbt,n_part)    
    py_tbt_first      = res.particles[0].py.reshape(n_turns_tbt,n_part)    
    zeta_tbt_first    = res.particles[0].zeta.reshape(n_turns_tbt,n_part)    
    delta_tbt_first   = res.particles[0].delta.reshape(n_turns_tbt,n_part)    
    at_turn_tbt_first = res.particles[0].at_turn.reshape(n_turns_tbt,n_part)    
    state_tbt_first   = res.particles[0].state.reshape(n_turns_tbt,n_part)    

    x_tbt_last       = res.particles[1].x.reshape(n_stores,n_part)    
    px_tbt_last      = res.particles[1].px.reshape(n_stores,n_part)    
    y_tbt_last       = res.particles[1].y.reshape(n_stores,n_part)    
    py_tbt_last      = res.particles[1].py.reshape(n_stores,n_part)    
    zeta_tbt_last    = res.particles[1].zeta.reshape(n_stores,n_part)    
    delta_tbt_last   = res.particles[1].delta.reshape(n_stores,n_part)    
    at_turn_tbt_last = res.particles[1].at_turn.reshape(n_stores,n_part)    
    state_tbt_last   = res.particles[1].state.reshape(n_stores,n_part)    

    output_dict = {'x_tbt_first' : x_tbt_first,
                   'px_tbt_first' : px_tbt_first,
                   'y_tbt_first' : y_tbt_first,
                   'py_tbt_first' : py_tbt_first,
                   'zeta_tbt_first' : zeta_tbt_first,
                   'delta_tbt_first' : delta_tbt_first,
                   'at_turn_tbt_first' : at_turn_tbt_first,
#                   'state_tbt_first' : state_tbt_first,
                   'x_tbt_last' : x_tbt_last,
                   'px_tbt_last' : px_tbt_last,
                   'y_tbt_last' : y_tbt_last,
                   'py_tbt_last' : py_tbt_last,
                   'zeta_tbt_last' : zeta_tbt_last,
                   'delta_tbt_last' : delta_tbt_last,
                   'at_turn_tbt_last' : at_turn_tbt_last,
#                   'state_tbt_last' : state_tbt_last,
                   'tracking_time_mins' : (end_tracking_time - start_tracking_time)/60.,
                   'collecting_time_mins' : (end_collecting_time - end_tracking_time)/60.,
                  }


    print('Done loading!')
    return output_dict
if numpy_spec is not None:
    import numpy as np

if __name__ == '__main__':
    if not pyst.supports('cuda'):
        raise SystemExit("Example requires cuda support in sixtracklib")

    if pycuda_spec is None:
        raise SystemExit("Example requires pycuda installation")

    if numpy_spec is None:
        raise SystemExit("Example requires numpy installation")

    num_particles = 42
    partset = pyst.ParticlesSet()
    particles = partset.Particles(num_particles=num_particles)

    cmp_partset = pyst.ParticlesSet()
    cmp_particles = cmp_partset.Particles(num_particles=num_particles)

    elements = pyst.Elements()
    elements.Drift(length=1.2)
    elements.Multipole(knl=[0, 0.001])

    track_job = pyst.CudaTrackJob(elements, partset)

    if not track_job.has_particle_addresses and \
            track_job.can_fetch_particle_addresses:
        track_job.fetch_particle_addresses()
                     min_particle_id=0,
                     is_rolling=False,
                     is_turn_ordered=False)
    line.Drift(length=7.0)
    line.LimitEllipse(a=0.5, b=0.35)
    line.BeamMonitor(num_stores=5,
                     start=10,
                     skip=5,
                     out_address=0,
                     max_particle_id=0,
                     min_particle_id=0,
                     is_rolling=True,
                     is_turn_ordered=False)

    NUM_PARTICLES = 100
    pb = st.ParticlesSet()
    pb.Particles(num_particles=100)

    ptr_pb = st_Buffer_new_mapped_on_cbuffer(pb.cbuffer)
    ptr_particles = st_Particles_cbuffer_get_particles(pb.cbuffer, 0)
    assert ptr_particles != st_NullParticles

    job = st.CudaTrackJob(line, pb)
    assert job.arch_str == 'cuda'
    assert job.requires_collecting
    assert job.has_output_buffer
    assert not job.has_elem_by_elem_output
    assert job.has_beam_monitor_output
    assert job.num_beam_monitors == 2

    # Copy the original contents of the line, the particle buffer and the out-
示例#14
0
def test_kicks(
    cmp_file_name="precomputed_kicks.pickle",
    device_str=None,
    abs_tol=1e-15,
    rel_tol=0.0,
):

    ####### load file with correct kicks #######
    path_to_testdir = sttest.config.PATH_TO_TESTDATA_DIR
    assert path_to_testdir is not None
    assert os.path.exists(path_to_testdir)
    assert os.path.isdir(path_to_testdir)

    path_to_cmp_file = os.path.join(path_to_testdir, "tricub", cmp_file_name)
    assert os.path.exists(path_to_cmp_file)

    with open(path_to_cmp_file, "rb") as fp:
        n_part, prng_seed, kicks = pickle.load(fp)

    assert n_part > 0
    assert prng_seed is not None
    assert kicks is not None

    np.random.seed(int(prng_seed))

    lattice = st.Elements()
    tc_index = lattice.cbuffer.n_objects
    tc = st.TriCub(cbuffer=lattice.cbuffer)
    tc.length = 1.0

    particles_set = st.ParticlesSet()
    particles = particles_set.Particles(num_particles=n_part)

    nx = 5
    ny = 7
    nz = 9
    A = np.random.rand(nx, ny, nz, 8) * 1.0e-3
    dx = 0.001
    dy = 0.002
    dz = 0.003
    x0 = -(nx // 2) * dx
    y0 = -(ny // 2) * dy
    z0 = -(nz // 2) * dz

    test_x = x0 + (nx - 2) * dx * np.random.rand(n_part)
    test_y = y0 + (ny - 2) * dy * np.random.rand(n_part)
    test_z = z0 + (nz - 2) * dz * np.random.rand(n_part)

    for i_part in range(n_part):
        part = pysixtrack.Particles()
        part.x = test_x[i_part]
        part.y = test_y[i_part]
        part.tau = test_z[i_part]

        part.partid = i_part
        part.state = 1
        part.elemid = 0
        part.turn = 0
        particles.from_pysixtrack(part, i_part)

    job = st.TrackJob(lattice, particles_set, device=device_str)

    tricub_data_buffer = cobjects.CBuffer()
    tc_data_index = tricub_data_buffer.n_objects
    tc_data = st.TriCubData(cbuffer=tricub_data_buffer, nx=nx, ny=ny, nz=nz)

    tc_data.x0 = x0
    tc_data.y0 = y0
    tc_data.z0 = z0
    tc_data.dx = dx
    tc_data.dy = dy
    tc_data.dz = dz
    tc_data.mirror_x = 0
    tc_data.mirror_y = 0
    tc_data.mirror_z = 0
    scale = [1.0, dx, dy, dz, dx * dy, dx * dz, dy * dz, (dx * dy) * dz]
    for ii in range(nx):
        for jj in range(ny):
            for kk in range(nz):
                for ll in range(8):
                    tc_data.table_addr[ll + 8 *
                                       (ii + nx *
                                        (jj + ny * kk))] = (A[ii, jj, kk, ll] *
                                                            scale[ll])

    tricub_data_buffer_id = job.add_stored_buffer(cbuffer=tricub_data_buffer)

    st.TriCub_buffer_create_assign_address_item(job, tc_index,
                                                tricub_data_buffer_id,
                                                tc_data_index)

    job.commit_address_assignments()
    job.assign_all_addresses()
    job.track_until(1)
    job.collect()

    assert np.allclose(kicks[:, 0], particles.px, rel_tol, abs_tol)
    assert np.allclose(kicks[:, 1], particles.py, rel_tol, abs_tol)
    assert np.allclose(kicks[:, 2], particles.ptau, rel_tol, abs_tol)
import cobjects
from cobjects import CBuffer, CObject
import sixtracklib as st

if __name__ == '__main__':
    lattice = st.Elements()
    lattice.Drift(length=1.0)
    pset = st.ParticlesSet()
    pset.Particles(num_particles=100)

    job = st.TrackJob(lattice, pset)

    assert not job.has_stored_buffers
    assert job.num_stored_buffers == 0
    assert job.min_stored_buffer_id == 0
    assert job.max_stored_buffer_id == 0

    data_buffer = st.ParticlesSet()
    out_data_index = data_buffer.cbuffer.n_objects
    out_data = data_buffer.Particles(num_particles=1000)
    assert data_buffer.cbuffer.n_objects == 1
    assert data_buffer.cbuffer.size > 0

    data_buffer_id = job.add_stored_buffer(cbuffer=data_buffer)
    assert data_buffer_id != st.stcommon.st_ARCH_ILLEGAL_BUFFER_ID.value
    assert job.has_stored_buffers
    assert job.num_stored_buffers == 1
    assert job.min_stored_buffer_id == data_buffer_id
    assert job.max_stored_buffer_id == data_buffer_id

    st_data_buffer = job.stored_buffer(data_buffer_id)
                     min_particle_id=0,
                     is_rolling=False,
                     is_turn_ordered=False)
    line.Drift(length=7.0)
    line.LimitEllipse(a=0.5, b=0.35)
    line.BeamMonitor(num_stores=5,
                     start=10,
                     skip=5,
                     out_address=0,
                     max_particle_id=0,
                     min_particle_id=0,
                     is_rolling=True,
                     is_turn_ordered=False)

    NUM_PARTICLES = 100
    pb = pyst.ParticlesSet()
    pb.Particles(num_particles=100)

    ptr_pb = st_Buffer_new_mapped_on_cbuffer(pb.cbuffer)
    ptr_particles = st_Particles_cbuffer_get_particles(pb.cbuffer, 0)
    assert ptr_particles != st_NullParticles

    job = pyst.TrackJob(line, pb, 0, "opencl", "0.0")
    assert job.type_str() == 'opencl'
    assert job.requires_collecting
    assert job.has_output_buffer
    assert not job.has_elem_by_elem_output
    assert job.has_beam_monitor_output
    assert job.num_beam_monitors == 2

    # Copy the original contents of the line, the particle buffer and the out-