示例#1
0
    def _prepare_monitors(self):

        pp = self.pp

        if hasattr(pp, 'write_buffer_every'):
            write_buffer_every = pp.write_buffer_every
        else:
            write_buffer_every = 3

        # define a bunch monitor
        from PyHEADTAIL.monitors.monitors import BunchMonitor

        self.bunch_monitor = BunchMonitor(
            "bunch_evolution_%02d" % self.SimSt.present_simulation_part,
            pp.N_turns,
            {"Comment": "PyHDTL simulation"},
            write_buffer_every=write_buffer_every,
        )

        # define a slice monitor
        from PyHEADTAIL.monitors.monitors import SliceMonitor

        self.slice_monitor = SliceMonitor(
            "slice_evolution_%02d" % self.SimSt.present_simulation_part,
            pp.N_turns,
            self.slicer,
            {"Comment": "PyHDTL simulation"},
            write_buffer_every=write_buffer_every,
        )
示例#2
0
 def test_bunchmonitor(self):
     ''' Test the bunchmonitor and all statistics functions
     '''
     self.n_macroparticles = 100  # use a high number to get acc statistics
     n_steps = 5
     self.monitor_fn = 'monitor'
     bunchmonitor1 = BunchMonitor(self.monitor_fn + '1',
                                  n_steps=n_steps,
                                  write_buffer_every=2,
                                  buffer_size=3)
     bunchmonitor2 = BunchMonitor(self.monitor_fn + '2',
                                  n_steps=n_steps,
                                  write_buffer_every=2,
                                  buffer_size=3)
     bunch_cpu = self.create_gaussian_bunch()
     bunch_gpu = self.create_gaussian_bunch()
     self._monitor_cpu_gpu(bunchmonitor1, bunchmonitor2, bunch_cpu,
                           bunch_gpu)
示例#3
0
 def setUp(self):
     self.n_turns = 10
     self.bunch_fn = 'bunchm'
     self.s_fn = 'sm'
     self.nslices = 5
     self.bunch_monitor = BunchMonitor(filename=self.bunch_fn,
                                       n_steps=self.n_turns,
                                       write_buffer_every=2,
                                       buffer_size=7,
                                       stats_to_store=['mean_x', 'macrop'])
示例#4
0
    def init_start_ring(self):
        stats_to_store = [
            'mean_x', 'mean_xp', 'mean_y', 'mean_yp', 'mean_z', 'mean_dp',
            'sigma_x', 'sigma_y', 'sigma_z', 'sigma_dp', 'epsn_x', 'epsn_y',
            'epsn_z', 'macroparticlenumber', 'i_bunch', 'i_turn'
        ]

        n_stored_turns = len(filling_pattern) * (
            self.ring_of_CPUs.N_turns / self.ring_of_CPUs.N_parellel_rings +
            self.ring_of_CPUs.N_parellel_rings)

        from PyHEADTAIL.monitors.monitors import BunchMonitor
        self.bunch_monitor = BunchMonitor(
            'bunch_monitor_ring%03d' % self.ring_of_CPUs.myring,
            n_stored_turns, {'Comment': 'PyHDTL simulation'},
            write_buffer_every=1,
            stats_to_store=stats_to_store)
    def init_master(self):

        # generate a bunch
        bunch = self.machine.generate_6D_Gaussian_bunch_matched(
            n_macroparticles=n_macroparticles,
            intensity=intensity,
            epsn_x=epsn_x,
            epsn_y=epsn_y,
            sigma_z=sigma_z)
        print 'Bunch initialized.'

        # initial slicing
        from PyHEADTAIL.particles.slicing import UniformBinSlicer
        self.slicer = UniformBinSlicer(n_slices=n_slices, n_sigma_z=n_sigma_z)

        # compute initial displacements
        inj_opt = self.machine.transverse_map.get_injection_optics()
        sigma_x = np.sqrt(inj_opt['beta_x'] * epsn_x / self.machine.betagamma)
        sigma_y = np.sqrt(inj_opt['beta_y'] * epsn_y / self.machine.betagamma)
        x_kick = x_kick_in_sigmas * sigma_x
        y_kick = y_kick_in_sigmas * sigma_y

        # apply initial displacement
        bunch.x += x_kick
        bunch.y += y_kick

        # define a bunch monitor
        from PyHEADTAIL.monitors.monitors import BunchMonitor
        self.bunch_monitor = BunchMonitor('bunch_evolution',
                                          N_turns,
                                          {'Comment': 'PyHDTL simulation'},
                                          write_buffer_every=8)

        #slice for the first turn
        slice_obj_list = bunch.extract_slices(self.slicer)

        pieces_to_be_treated = slice_obj_list

        print 'N_turns', self.N_turns

        return pieces_to_be_treated
# setup transverse losses (to "protect" the ecloud)
import PyHEADTAIL.aperture.aperture as aperture
apt_xy = aperture.EllipticalApertureXY(x_aper=ecloud.impact_man.chamb.x_aper,
                                       y_aper=ecloud.impact_man.chamb.y_aper)
machine.one_turn_map.append(apt_xy)

# generate a bunch
bunch = machine.generate_6D_Gaussian_bunch_matched(n_macroparticles=300000,
                                                   intensity=intensity,
                                                   epsn_x=epsn_x,
                                                   epsn_y=epsn_y,
                                                   sigma_z=1.35e-9 / 4 * c)

# apply initial displacement
bunch.x += x_kick
bunch.y += y_kick

# define a bunch monitor
from PyHEADTAIL.monitors.monitors import BunchMonitor
bunch_monitor = BunchMonitor('bunch_evolution.h5',
                             N_turns, {'Comment': 'PyHDTL simulation'},
                             write_buffer_every=8)

# simulate
import time
for i_turn in xrange(N_turns):
    print '%s Turn %d' % (time.strftime("%d/%m/%Y %H:%M:%S",
                                        time.localtime()), i_turn)
    machine.track(bunch, verbose=False)
    bunch_monitor.dump(bunch)
示例#7
0
def run(job_id, accQ_y):
    it = job_id

    # SIMULATION PARAMETERS
    # =====================

    # Simulation parameters
    n_turns = 10000
    n_macroparticles = 100000  # per bunch

    # MACHINE PARAMETERS
    # ==================

    intensity = 1e13  # protons
    #    intensity = 2*4e12 # protons
    E0 = 71e6  # Kinetic energy [eV]
    p0 = np.sqrt((m_p_MeV + E0)**2 - m_p_MeV**2) * e / c

    print('Beam kinetic energy: ' + str(E0 * 1e-6) + ' MeV')
    print('Beam momentum: ' + str(p0 * 1e-6 * c / e) + ' MeV/c')

    accQ_x = 4.31  # Horizontal tune
    #    accQ_y = 3.80 # Vertical tune is an input argument

    chroma = -1.4  # Chromaticity

    alpha = 5.034**-2  # momentum compaction factor

    circumference = 160.  # [meters]

    # Approximated average beta functions (lumped wake normalizations)
    beta_x = circumference / (2. * np.pi * accQ_x)
    beta_y = circumference / (2. * np.pi * accQ_y)

    # Harmonic number for RF
    h_RF = [2]  # a list of harmonic number for RF
    V_RF = [5e3 * 2]  # a list of RF voltages
    p_increment = 0.
    dphi_RF = [np.pi]  # a list of RF phases
    #    dphi_RF = 0.

    # non-linear longitudinal mode includes RF, otherwise linear needs synhotron tune Q_s
    longitudinal_mode = 'non-linear'
    #    Q_s=0.02 # Longitudinal tune

    optics_mode = 'smooth'
    n_segments = 1
    s = None
    alpha_x = None
    alpha_y = None
    D_x = 0
    D_y = 0
    charge = e
    mass = m_p
    name = None
    app_x = 0
    app_y = 0
    app_xy = 0

    # Creates PyHEADTAIL object for the synchotron
    machine = Synchrotron(optics_mode=optics_mode,
                          circumference=circumference,
                          n_segments=n_segments,
                          s=s,
                          name=name,
                          alpha_x=alpha_x,
                          beta_x=beta_x,
                          D_x=D_x,
                          alpha_y=alpha_y,
                          beta_y=beta_y,
                          D_y=D_y,
                          accQ_x=accQ_x,
                          accQ_y=accQ_y,
                          Qp_x=chroma,
                          Qp_y=chroma,
                          app_x=app_x,
                          app_y=app_y,
                          app_xy=app_xy,
                          alpha_mom_compaction=alpha,
                          longitudinal_mode=longitudinal_mode,
                          h_RF=np.atleast_1d(h_RF),
                          V_RF=np.atleast_1d(V_RF),
                          dphi_RF=np.atleast_1d(dphi_RF),
                          p0=p0,
                          p_increment=p_increment,
                          charge=charge,
                          mass=mass)

    print('')
    print('machine.beta: ')
    print(machine.beta)
    print('')

    print('')
    print('machine.gamma: ')
    print(machine.gamma)
    print('')

    epsn_x = 300e-6
    epsn_y = 300e-6
    sigma_z = 15  # bunch length in meters to be matched to the bucket

    # Creates transverse macroparticle distribution
    allbunches = machine.generate_6D_Gaussian_bunch(n_macroparticles,
                                                    intensity, epsn_x, epsn_y,
                                                    sigma_z)

    # Creates longitudinal macroparticle distribution
    rfb = RFBucket(circumference, machine.gamma, m_p, e, [alpha], 0., h_RF,
                   V_RF, dphi_RF)
    rfb_matcher = RFBucketMatcher(rfb, WaterbagDistribution, sigma_z=sigma_z)

    rfb_matcher.integrationmethod = 'cumtrapz'

    z, dp, _, _ = rfb_matcher.generate(n_macroparticles)
    np.copyto(allbunches.z, z)
    np.copyto(allbunches.dp, dp)

    # Slicer object, which used for wakefields and slice monitors
    slicer = UniformBinSlicer(75, z_cuts=(-2. * sigma_z, 2. * sigma_z))

    # WAKE FIELDS
    # ===========

    # Length of the wake function in turns, wake
    n_turns_wake = 150

    # Parameters for a resonator
    # frequency is in the units of (mode-Q_frac), where
    #       mode: integer number of coupled bunch mode (1 matches to the observations)
    #       Q_frac: resonance fractional tune

    f_r = (1 - 0.83) * 1. / (circumference / (c * machine.beta))
    Q = 15
    R = 1.0e6

    # Renator wake object, which is added to the one turn map
    wakes = CircularResonator(R, f_r, Q, n_turns_wake=n_turns_wake)
    wake_field = WakeField(slicer, wakes)
    machine.one_turn_map.append(wake_field)

    # CREATE MONITORS
    # ===============
    simulation_parameters_dict = {'gamma'           : machine.gamma,\
                                  'intensity'       : intensity,\
                                  'Qx'              : accQ_x,\
                                  'Qy'              : accQ_y,\
#                                  'Qs'              : Q_s,\
                                  'beta_x'          : beta_x,\
                                  'beta_y'          : beta_y,\
    #                               'beta_z'          : bucket.beta_z,\
                                  'epsn_x'          : epsn_x,\
                                  'epsn_y'          : epsn_y,\
                                  'sigma_z'         : sigma_z,\
                                 }
    # Bunch monitor strores bunch average positions for all the bunches
    bunchmonitor = BunchMonitor(outputpath + '/bunchmonitor_{:04d}'.format(it),
                                n_turns,
                                simulation_parameters_dict,
                                write_buffer_every=32,
                                buffer_size=32)

    # Slice monitors saves slice-by-slice data for each bunch
    slicemonitor = SliceMonitor(outputpath +
                                '/slicemonitor_{:01d}_{:04d}'.format(0, it),
                                60,
                                slicer,
                                simulation_parameters_dict,
                                write_buffer_every=60,
                                buffer_size=60)

    # Counter for a number of turns stored to slice monitors
    s_cnt = 0

    # TRACKING LOOP
    # =============
    monitor_active = False
    print('\n--> Begin tracking...\n')

    for i in range(n_turns):
        t0 = time.clock()

        # Tracks beam through the one turn map simulation map
        machine.track(allbunches)

        # Stores bunch mean coordinate values
        bunchmonitor.dump(allbunches)

        # If the total oscillation amplitude of bunches exceeds the threshold
        # or the simulation is running on the last turns, triggers the slice
        # monitors for headtail motion data
        if (allbunches.mean_x() > 1e-1 or allbunches.mean_y() > 1e-1 or i >
            (n_turns - 64)):
            monitor_active = True

        # saves slice monitor data if monitors are activated and less than
        # 64 turns have been stored
        if monitor_active and s_cnt < 64:
            slicemonitor.dump(allbunches)
            s_cnt += 1
        elif s_cnt == 64:
            break

        # If this script is runnin on the first processor, prints the current
        # bunch coordinates and emittances
        if (i % 100 == 0):
            print(
                '{:4d} \t {:+3e} \t {:+3e} \t {:+3e} \t {:3e} \t {:3e} \t {:3f} \t {:3f} \t {:3f} \t {:3s}'
                .format(i, allbunches.mean_x(), allbunches.mean_y(),
                        allbunches.mean_z(), allbunches.epsn_x(),
                        allbunches.epsn_y(), allbunches.epsn_z(),
                        allbunches.sigma_z(), allbunches.sigma_dp(),
                        str(time.clock() - t0)))

# apply initial displacement
bunch.x += x_kick
bunch.y += y_kick


# Manage multi-job operation
import Save_Load_Status as SLS
SimSt = SLS.SimulationStatus(N_turns_per_run=N_turns_per_run, N_turns_target=N_turns_target, jobid=jobid,check_for_resubmit=True, queue=queue)
SimSt.before_simulation()


# define a bunch monitor 
from PyHEADTAIL.monitors.monitors import BunchMonitor
bunch_monitor = BunchMonitor('bunch_evolution_%02d'%SimSt.present_simulation_part, N_turns_per_run, {'Comment':'PyHDTL simulation'}, 
					write_buffer_every = 8)


if not SimSt.first_run:
	# If not first part, load saved bunch and ecloud
	bunch = SLS.beam_from_h5status('bunch_status_part%02d.h5'%(SimSt.present_simulation_part-1))
	SLS.reinit_ecloud_from_h5status('ecloud_init_status.h5', ecloud)
else:
	#save ecloud particles status
	SLS.dump_ecloud_status(ecloud, 'ecloud_init_status.h5')

# simulate
import time
for i_turn in xrange(N_turns_per_run):
	print '%s Turn %d'%(time.strftime("%d/%m/%Y %H:%M:%S", time.localtime()), i_turn)
	machine.track(bunch, verbose = False)
    def init_master(self):

        # Manage multi-job operation
        if pp.footprint_mode:
            if pp.N_turns != pp.N_turns_target:
                raise ValueError(
                    'In footprint mode you need to set N_turns_target=N_turns_per_run!'
                )

        import PyPARIS_sim_class.Save_Load_Status as SLS
        SimSt = SLS.SimulationStatus(N_turns_per_run=pp.N_turns,
                                     check_for_resubmit=True,
                                     N_turns_target=pp.N_turns_target)
        SimSt.before_simulation()
        self.SimSt = SimSt

        # generate a bunch
        if pp.footprint_mode:
            self.bunch = self.machine.generate_6D_Gaussian_bunch_matched(
                n_macroparticles=pp.n_macroparticles_for_footprint_track,
                intensity=pp.intensity,
                epsn_x=pp.epsn_x,
                epsn_y=pp.epsn_y,
                sigma_z=pp.sigma_z)
        elif SimSt.first_run:

            if pp.bunch_from_file is not None:
                print 'Loading bunch from file %s ...' % pp.bunch_from_file
                with h5py.File(pp.bunch_from_file, 'r') as fid:
                    self.bunch = self.buffer_to_piece(
                        np.array(fid['bunch']).copy())
                print 'Bunch loaded from file.\n'

            else:
                self.bunch = self.machine.generate_6D_Gaussian_bunch_matched(
                    n_macroparticles=pp.n_macroparticles,
                    intensity=pp.intensity,
                    epsn_x=pp.epsn_x,
                    epsn_y=pp.epsn_y,
                    sigma_z=pp.sigma_z)

                # compute initial displacements
                inj_opt = self.machine.transverse_map.get_injection_optics()
                sigma_x = np.sqrt(inj_opt['beta_x'] * pp.epsn_x /
                                  self.machine.betagamma)
                sigma_y = np.sqrt(inj_opt['beta_y'] * pp.epsn_y /
                                  self.machine.betagamma)
                x_kick = pp.x_kick_in_sigmas * sigma_x
                y_kick = pp.y_kick_in_sigmas * sigma_y

                # apply initial displacement
                if not pp.footprint_mode:
                    self.bunch.x += x_kick
                    self.bunch.y += y_kick

                print 'Bunch initialized.'
        else:
            print 'Loading bunch from file...'
            with h5py.File(
                    'bunch_status_part%02d.h5' %
                (SimSt.present_simulation_part - 1), 'r') as fid:
                self.bunch = self.buffer_to_piece(
                    np.array(fid['bunch']).copy())
            print 'Bunch loaded from file.'

        # initial slicing
        self.slicer = UniformBinSlicer(n_slices=pp.n_slices,
                                       z_cuts=(-pp.z_cut, pp.z_cut))

        # define a bunch monitor
        from PyHEADTAIL.monitors.monitors import BunchMonitor
        self.bunch_monitor = BunchMonitor(
            'bunch_evolution_%02d' % self.SimSt.present_simulation_part,
            pp.N_turns, {'Comment': 'PyHDTL simulation'},
            write_buffer_every=3)

        # define a slice monitor
        from PyHEADTAIL.monitors.monitors import SliceMonitor
        self.slice_monitor = SliceMonitor(
            'slice_evolution_%02d' % self.SimSt.present_simulation_part,
            pp.N_turns,
            self.slicer, {'Comment': 'PyHDTL simulation'},
            write_buffer_every=3)

        #slice for the first turn
        slice_obj_list = self.bunch.extract_slices(self.slicer)

        pieces_to_be_treated = slice_obj_list

        print 'N_turns', self.N_turns

        if pp.footprint_mode:
            self.recorded_particles = ParticleTrajectories(
                pp.n_macroparticles_for_footprint_track, self.N_turns)

        return pieces_to_be_treated
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!')
    def perform_bunch_operations_at_start_ring(self, bunch):
        
        if self.bunch_monitor is None:
            
            simstate_part = bunch.slice_info['simstate_part']
            stats_to_store = [
             'mean_x', 'mean_xp', 'mean_y', 'mean_yp', 'mean_z', 'mean_dp',
             'sigma_x', 'sigma_y', 'sigma_z','sigma_dp', 'epsn_x', 'epsn_y',
             'epsn_z', 'macroparticlenumber',
             'i_bunch', 'i_turn']

            n_stored_turns = np.sum(np.array(filling_pattern)>0)*(\
                self.ring_of_CPUs.N_turns/self.ring_of_CPUs.N_parellel_rings\
                + self.ring_of_CPUs.N_parellel_rings)

            from PyHEADTAIL.monitors.monitors import BunchMonitor
            self.bunch_monitor = BunchMonitor(
                                'bunch_monitor_part%03d_ring%03d'%(
                                    simstate_part, self.ring_of_CPUs.myring),
                                n_stored_turns, 
                                {'Comment':'PyHDTL simulation'}, 
                                write_buffer_every = 1,
                                stats_to_store = stats_to_store)

            # define a slice monitor 
            z_left = bunch.slice_info['z_bin_left'] - bunch.slice_info['z_bin_center']
            z_right = bunch.slice_info['z_bin_right'] - bunch.slice_info['z_bin_center']
            slicer = UniformBinSlicer(n_slices = self.n_slices_per_bunch, z_cuts=(z_left, z_right))
            from PyHEADTAIL.monitors.monitors import SliceMonitor
            self.slice_monitor = SliceMonitor('slice_monitor_part%03d_ring%03d'%(
                simstate_part, self.ring_of_CPUs.myring),
                n_stored_turns, slicer,  {'Comment':'PyHDTL simulation'}, 
                write_buffer_every = 1, bunch_stats_to_store=stats_to_store,
                slice_stats_to_store='mean_x mean_y mean_z n_macroparticles_per_slice'.split())
        
    

        # Save bunch properties
        if bunch.macroparticlenumber > 0 and bunch.slice_info['i_turn'] < self.N_turns:
            # Attach bound methods to monitor i_bunch and i_turns 
            bunch.i_bunch = types.MethodType(lambda ss: ss.slice_info['i_bunch'], bunch)
            bunch.i_turn = types.MethodType(lambda ss: ss.slice_info['i_turn'], bunch)
            self.bunch_monitor.dump(bunch)

            # Monitor slice wrt bunch center
            bunch.z -= bunch.slice_info['z_bin_center']
            self.slice_monitor.dump(bunch)
            bunch.z += bunch.slice_info['z_bin_center']

        # Save full beam at user-defined positions
        if bunch.slice_info['i_turn'] in self.save_beam_at_turns:
            dirname = 'bunch_states_turn%d'%bunch.slice_info['i_turn']
            import PyPARIS.gen_multibunch_beam as gmb
            gmb.save_bunch_to_folder(bunch, dirname)

        # Save full beam at end simulation 
        if bunch.slice_info['i_turn'] == self.N_turns:
            # PyPARIS wants N_turns to be a multiple of N_parellel_rings
            assert(self.ring_of_CPUs.I_am_the_master) 
            dirname = 'beam_status_part%02d'%(self.SimSt.present_simulation_part)
            import PyPARIS.gen_multibunch_beam as gmb
            gmb.save_bunch_to_folder(bunch, dirname)
            if bunch.slice_info['i_bunch'] == bunch.slice_info['N_bunches_tot_beam'] - 1:
                if not self.SimSt.first_run:
                    os.system('rm -r beam_status_part%02d' % (self.SimSt.present_simulation_part - 1))
                self.SimSt.after_simulation()
示例#12
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!')
示例#13
0
def run():
    # HELPERS
    def read_all_data(bfile, sfile, pfile):
        bunchdata = hp.File(bfile + '.h5')
        slicedata = hp.File(sfile + '.h5')
        particledata = hp.File(pfile + '.h5part')

        # Bunchdata
        bdata = bunchdata['Bunch']

        n_turns = len(bdata['mean_x'])
        _ = np.empty(n_turns)
        for key in list(bdata.keys()):
            _[:] = bdata[key][:]

        # Slicedata
        sdata = slicedata['Slices']
        sbdata = slicedata['Bunch']

        n_turns = len(sbdata['mean_x'])
        _ = np.empty(n_turns)
        for key in list(sbdata.keys()):
            _[:] = sbdata[key][:]

        n_slices, n_turns = sdata['mean_x'].shape
        _ = np.empty((n_slices, n_turns))
        for key in list(sdata.keys()):
            _[:, :] = sdata[key][:, :]

        # Particledata
        pdata = particledata['Step#0']
        n_particles = len(pdata['x'])
        n_steps = len(list(particledata.keys()))
        _ = np.empty(n_particles)

        for i in range(n_steps):
            step = 'Step#%d' % i
            for key in list(particledata[step].keys()):
                _[:] = particledata[step][key][:]

        bunchdata.close()
        slicedata.close()
        particledata.close()

    def read_n_plot_data(bfile, sfile, pfile):
        bunchdata = hp.File(bfile + '.h5')
        slicedata = hp.File(sfile + '.h5')
        particledata = hp.File(pfile + '.h5part')

        fig = plt.figure(figsize=(16, 16))
        ax1 = fig.add_subplot(311)
        ax2 = fig.add_subplot(312)
        ax3 = fig.add_subplot(313)

        ax1.plot(bunchdata['Bunch']['mean_x'][:])
        ax2.plot(slicedata['Slices']['mean_x'][:, :])
        ax3.plot(particledata['Step#0']['x'][:])
        #ax2.plot(slicedata[])

        plt.show()

        bunchdata.close()
        slicedata.close()
        particledata.close()

    def generate_bunch(n_macroparticles, alpha_x, alpha_y, beta_x, beta_y,
                       alpha_0, Q_s, R):

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

        beta_z = eta * R / 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
        )  # WITH OR WITHOUT 4 PIjQuery202047649151738733053_1414145430832?

        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)
        return bunch

    # In[4]:
    # Basic parameters.
    n_turns = 2
    n_segments = 5
    n_macroparticles = 500

    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

    # ##### Things tested:   - Instantiation of the three monitors BunchMonitor, SliceMonitor, ParticleMonitor.   - dump(beam) method for all the three.   - read data from file. Plot example data from Bunch-, Slice- and Particle-Monitors.   - SliceMonitor: does it handle/request slice_sets correctly?   - Buffers are on for Bunch- and SliceMonitors.  Look at one of the files in hdfview to check the units, attributes, ...

    # 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]:

    # Instantiate BunchMonitor, SliceMonitor and ParticleMonitor and dump data to file.
    bunch = generate_bunch(n_macroparticles, alpha_x_inj, alpha_y_inj,
                           beta_x_inj, beta_y_inj, alpha_0, Q_s, R)

    trans_map = TransverseMap(s, alpha_x, beta_x, D_x, alpha_y, beta_y, D_y,
                              Q_x, Q_y)

    # Slicer config for SliceMonitor.
    unibin_slicer = UniformBinSlicer(n_slices=10, n_sigma_z=None, z_cuts=None)

    # Monitors
    bunch_filename = 'bunch_mon'
    slice_filename = 'slice_mon'
    particle_filename = 'particle_mon'

    bunch_monitor = BunchMonitor(filename=bunch_filename,
                                 n_steps=n_turns,
                                 parameters_dict={'Q_x': Q_x},
                                 write_buffer_every=20)
    slice_monitor = SliceMonitor(filename=slice_filename,
                                 n_steps=n_turns,
                                 slicer=unibin_slicer,
                                 parameters_dict={'Q_x': Q_x},
                                 write_buffer_every=20)
    particle_monitor = ParticleMonitor(filename=particle_filename,
                                       stride=10,
                                       parameters_dict={'Q_x': Q_x})

    arrays_dict = {}
    map_ = trans_map
    for i in range(n_turns):
        for m_ in map_:
            m_.track(bunch)
        bunch_monitor.dump(bunch)
        slice_monitor.dump(bunch)

        slice_set_pmon = bunch.get_slices(unibin_slicer)
        arrays_dict.update({
            'slidx': slice_set_pmon.slice_index_of_particle,
            'zz': bunch.z
        })
        particle_monitor.dump(bunch, arrays_dict)

    read_all_data(bunch_filename, slice_filename, particle_filename)

    os.remove(bunch_filename + '.h5')
    os.remove(slice_filename + '.h5')
    os.remove(particle_filename + '.h5part')