def fel_params(self, ks): import logging logger = logging.getLogger(fel.parray2beam.__module__) logger.setLevel(logging.CRITICAL) logger = logging.getLogger(fel.__name__) logger.setLevel(logging.CRITICAL) logger = logging.getLogger(rad.fel.__name__) logger.setLevel(logging.CRITICAL) lat = MagneticLattice(self.cell) p_array = copy.deepcopy(self.particle_array) step = 5e-7 beam = fel.parray2beam(p_array, step=2 * step) for q, k in zip(self.quadrupoles, ks): q.k1 = k lat.update_transfer_maps() fel_param = fel.beamlat2fel(beam, lat, smear_m=step) return fel_param
def test_twiss(): xdb = Xdb(index_file='/home/iagapov/data/xdb/test/index.h5', mode='r') f = xdb.read_undulator_config('sase3/1000eV') exec(f) lat = MagneticLattice(sase3) #rematch(18.0, l_fodo, qdh, lat, extra_fodo, beam, qf, qd) # jeez... tw0 = Twiss(beam) print tw0 tws = twiss(lat, tw0, nPoints=1000) f = plt.figure() ax = f.add_subplot(111) ax.set_xlim(0, lat.totalLen) f.canvas.set_window_title('Betas [m]') p1, = plt.plot(map(lambda p: p.s, tws), map(lambda p: p.beta_x, tws), lw=2.0) p2, = plt.plot(map(lambda p: p.s, tws), map(lambda p: p.beta_y, tws), lw=2.0) plt.grid(True) plt.legend([p1, p2], [r'$\beta_x$', r'$\beta_y$', r'$D_x$']) plt.show()
def split_lat(lattice): cells = [] cell = [] for elem in lattice.sequence: if elem.type == "undulator": if len(cell) > 0: cells.append(MagneticLattice(cell)) cells.append(MagneticLattice(elem)) cell = [] else: cell.append(elem) #if len(cell)>0: #cells.append(MagneticLattice(cell, energy = lattice.energy)) #cells.append(MagneticLattice([elem], energy = lattice.energy)) #cell = [] if len(cell) > 0: cells.append(MagneticLattice(cell)) return cells
def collect_drifts(lat): drift = 0 L = 0. seq = [] for i, elem in enumerate(lat.sequence): if elem.type in ["drift", "monitor"]: #print elem.id, elem.tilt, elem.l drift = 1 L += elem.l if i == len(lat.sequence) - 1: L = around(L, decimals=6) seq.append( Drift(l=L, eid="d" + str(int(L * 100000 + 10000000))[1:])) else: if drift > 0 and L > 0.: L = around(L, decimals=6) seq.append( Drift(l=L, eid="d" + str(int(L * 100000 + 10000000))[1:])) drift = 0 seq.append(elem) L = 0. return MagneticLattice(seq)
bc = (l1, b1, l2, b2) lin = (i1, bc, l3, cl) line1 = (t1, sa2, t3, un1, t5, un2, t5d) td2 = (tl1, tl2, tl3, tl4, tl5, t2, sa1, t4, sa3, t4d) td0 = (tl1, tl2, tld) td1 = (tl1, tl2, tl3, tl4, t1, sa2, t3, un1, t5, un2, t5d) td20 = (tl1, tl2, tl3, tl4, tl5, t20) td6 = (tl1, tl2, tl3, tl4, t1, sa2, sa2tt3, t3m1, t6) td7 = (tl1, tl2, tl3, tl4, t1, sa2, t3, un1, t5, un2, un2tt5d, t7) td8 = (tl1, tl2, tl3, tl4, t1, sa2, t3, un1, un1tt5, t5m1, t8) td9 = (tl1, tl2, tl3, tl4, tl5, t2, sa1, sa1tt4, t4m1, t9) td10 = (tl1, tl2, tl3, tl4, tl5, t2, sa1, t4, sa3, sa3tt4d, t10) xfelall = (lin, td2) #tw0 = Twiss(Beam()) lat = MagneticLattice(i1, energy=2.5) print lat.totalLen, len(lat.sequence) for elem in lat.sequence: if elem.tilt != 0: print elem.id, elem.type, elem.l, elem.tilt def collect_drifts(lat): drift = 0 L = 0. seq = [] for i, elem in enumerate(lat.sequence): if elem.type in ["drift", "monitor"]: #print elem.id, elem.tilt, elem.l drift = 1
beam.alpha_y = -0.54569 s_start=0 z_start=0 z_stop=190 dir_name='./flash/elegant_old/' file_flo=dir_name+'FLASH_S2E_flo.txt' file_par=dir_name+'FLASH_S2E_par.txt' lat_def = read_lattice_elegant(file_flo,file_par) lat_def=insert_drifts(z_start,z_stop,lat_def) tw0 = Twiss(beam) lat = MagneticLattice(lat_def, beam.E) write_lattice(lat, file_name = "lattice_FLASH_S2E.txt") tws=twiss(lat, tw0) lat.update_transfer_maps() tws=twiss(lat, tw0, nPoints = 10000) file_opt=dir_name+'FLASH_S2E_twi.txt' dd = np.genfromtxt(file_opt) s_dd=dd[:,0]
sys.path.append(rep_dir + 'sase1/') from sase1 import * exp_dir = '/data/fhgfs/iagapov/exp207/' #exp_dir = './exp1/' run_ids = xrange(0,1) beta_av = 25.0 xt_couple = True start_stage = 1 stop_stage = 3 debug = True create_exp_dir(exp_dir, run_ids) lat = MagneticLattice(sase1_segment(n=20)) rematch(beta_av, l_fodo, qdh, lat, extra_fodo, beam, qf, qd) # jeez... tw0 = Twiss(beam) tws=twiss(lat, tw0, nPoints = 100) # to make sure the average beta exists, show twiss if needed beam.E = float(sys.argv[1]) # 14.0 E_ev = float(sys.argv[2]) # 8000.0 # calculate UR parameters (required later for input generation) up = UndulatorParameters(und) up.E = beam.E up.printParameters() und.Kx = up.get_k(E_ev) up = UndulatorParameters(und) up.E = beam.E
beam = Beam() beam.E = 148.3148e-3 #in GeV ?! beam.beta_x = 14.8821 beam.beta_y = 18.8146 beam.alpha_x = -0.61309 beam.alpha_y = -0.54569 beam.emit_xn = 1.5e-6 beam.emit_yn = 1.5e-6 beam.emit_x = beam.emit_xn / (beam.E * 1e9 / E_ele_eV) beam.emit_y = beam.emit_yn / (beam.E * 1e9 / E_ele_eV) beam.tlen = 2e-3 # in m tw0 = Twiss(beam) exec(open('lattice_FLASH_S2E.txt')) lat = MagneticLattice(lattice, beam.E) tws = twiss(lat, tw0, nPoints=1000) lat.update_transfer_maps() tws = twiss(lat, tw0, nPoints=1000) lat.update_transfer_maps(track_acceleration=True) # elegant optics file_opt = '../flash/elegant_old/FLASH_S2E_twi.txt' dd = np.genfromtxt(file_opt) s_dd = dd[:, 0] betax_dd = dd[:, 1] alphax_dd = dd[:, 2] betay_dd = dd[:, 7] alphay_dd = dd[:, 8] energy_dd = dd[:, 13] * E_ele_eV * 1e-6
# injector from I1 import * from L1 import * from B1 import * from L2 import * from B2 import * from L3 import * from CL import * from CL2SA1 import * from SA1 import * from T4 import * from SA3 import * from CL2SA2 import * from SA2 import * lat_i1 = MagneticLattice(gun_5MeV + i1_150M, stop=i1_starti1d) tws = twiss(lat_i1, tws_5M, nPoints=None) print("'GUN': length = ", lat_i1.totalLen, "s = ", tws[-1].s) plot_opt_func(lat_i1, tws, top_plot=["E"], fig_name="i1", legend=False) plt.show() lat = MagneticLattice(i1_150M) tws = twiss(lat, tws_150M, nPoints=1000) #print "I1 (from 150MeV) : length = ", lat.totalLen, "s = ", tws[-1].s print("I1 (from 150MeV) : delta on the end: bx =", tws[-1].beta_x - tws_L1.beta_x, " by =", tws[-1].beta_y - tws_L1.beta_y) plot_opt_func(lat, tws, top_plot=["E"], fig_name="i1 from 150 MeV") plt.show() #exec(open("L1.inp"))
lat_def = read_lattice_elegant(file_flo,file_par) z_shift=0 z_start=0-z_shift z_stop=50.1917045455325-z_shift lat_def=insert_drifts(z_start,z_stop,lat_def) #f=open('dump.txt','wt') #pickle.dump(lat_def, f) #f.close() tw0 = Twiss(beam) lat = MagneticLattice(lat_def, beam.E) lat.printElements() write_lattice(lat, file_name = "lattice_Igor.txt") tws=twiss(lat, tw0, nPoints = 10000) file_opt=dir_name+'XFEL_BC2_twi.txt' #f=open(file_opt,'rb') #dd=csv.reader(f) #for row in dd: # print row #f.close() dd = np.genfromtxt(file_opt)
file_par = dir_name + 'XFEL_BC2_par.txt' lat_def = read_lattice_elegant(file_flo, file_par) z_shift = 0 z_start = 0 - z_shift z_stop = 50.1917045455325 - z_shift lat_def = insert_drifts(z_start, z_stop, lat_def) #f=open('dump.txt','wt') #pickle.dump(lat_def, f) #f.close() tw0 = Twiss(beam) lat = MagneticLattice(lat_def, beam.E) lat.printElements() write_lattice(lat, file_name="lattice_Igor.txt") tws = twiss(lat, tw0, nPoints=10000) file_opt = dir_name + 'XFEL_BC2_twi.txt' #f=open(file_opt,'rb') #dd=csv.reader(f) #for row in dd: # print row #f.close() dd = np.genfromtxt(file_opt) s_dd = dd[:, 0] betax_dd = dd[:, 1]
beam.beta_x = 14.8821 beam.beta_y = 18.8146 beam.alpha_x = -0.61309 beam.alpha_y = -0.54569 beam.emit_xn = 1.5e-6 beam.emit_yn = 1.5e-6 beam.emit_x = beam.emit_xn / (beam.E / m_e_GeV) beam.emit_y = beam.emit_yn / (beam.E / m_e_GeV) gun_energy = 0.0053 #GeV tw0 = Twiss(beam) BPM1TCOL.type = "drift" BPM2UND3.type = "drift" #BPM14SMATCH.type="drift" lat = MagneticLattice(lattice, start=STARTACC39) orb = Orbit(lat) #lat = MagneticLattice(lattice) setup = log.MachineSetup() ampls1, phases1 = mi.get_cavity_info(["M1.ACC1"]) #ampls2, phases2 = mi.get_cavity_info(["M2.ACC1"]) print "energy gun = ", mi.get_gun_energy() beam.E = mi.get_gun_energy() + ampls1[0] * cos(phases1[0] * pi / 180.) * 0.001 print "ACC1 = ", ampls1[0] * cos(phases1[0] * pi / 180.) * 0.001 read_cavs(lat, mi) E = beam.E print "initial energy = ", E
beam.beta_x = 14.8821 beam.beta_y = 18.8146 beam.alpha_x = -0.61309 beam.alpha_y = -0.54569 beam.emit_xn = 1.5e-6 beam.emit_yn = 1.5e-6 beam.emit_x = beam.emit_xn / (beam.E / m_e_GeV) beam.emit_y = beam.emit_yn / (beam.E / m_e_GeV) gun_energy = 0.0053 #GeV tw0 = Twiss(beam) BPM1TCOL.type="drift" BPM2UND3.type="drift" #BPM14SMATCH.type="drift" lat = MagneticLattice(lattice, start=STARTACC39) orb = Orbit(lat) #lat = MagneticLattice(lattice) setup = log.MachineSetup() ampls1, phases1 = mi.get_cavity_info(["M1.ACC1"]) #ampls2, phases2 = mi.get_cavity_info(["M2.ACC1"]) print "energy gun = ", mi.get_gun_energy() beam.E = mi.get_gun_energy() + ampls1[0]*cos(phases1[0]*pi/180.)*0.001 print "ACC1 = ", ampls1[0]*cos(phases1[0]*pi/180.)*0.001 read_cavs(lat, mi) E = beam.E
rfc1 = Drift(l = 5.0) #Cavity(l=5.0, f=1.3 * GHz, v=25.5 * MV, id='rfc1') d0 = Drift(l = 2.0) e1 = RBend(angle = 0.1, l = 2.0) d1 = Drift(l = 1.0) e2 = RBend(angle = -0.1, l = 2.0) d2 = Drift(l = 1.0) beam = Beam() beam.E = 1.0 # GeV beam.sigma_E = 1.0e-3 # GeV beam.beta_x = 10 beam.beta_y = 20 beam.emit_x = 1.e-6 beam.emit_y = 1.e-6 lat = MagneticLattice((rfc1, d0, e1, d1, e2, (d2,)*5, e2, d2, e1,d1)) ''' twiss calculation ''' tw0 = Twiss(beam) tws=twiss(lat, tw0, nPoints = 1000) f=plt.figure() ax = f.add_subplot(111) ax.set_xlim(0, lat.totalLen) f.canvas.set_window_title('Betas [m]') p1, = plt.plot(map(lambda p: p.s, tws), map(lambda p: p.beta_x, tws), lw=2.0)
from ocelot import MagneticLattice __author__ = 'Sergey Tomin' from ocelot.gui.accelerator import * from ocelot.mint.xfel_interface import * #tws0 = Twiss() #tws0.beta_x = 29.171 #tws0.beta_y = 29.171 #tws0.alpha_x = 10.955 #tws0.alpha_y = 10.955 # #tws0.E = 0.005 * GeV # injector from desy.xfel.linac.I1 import * lat_i1 = MagneticLattice(gun_5MeV + i1_150M, stop=i1_starti1d) tws = twiss(lat_i1, tws_5M, nPoints=None) print("'GUN': length = ", lat_i1.totalLen, "s = ", tws[-1].s) plot_opt_func(lat_i1, tws, top_plot=["Dx"], fig_name="i1", legend=False) plt.show() mi = XFELMachineInterface() for elem in lat_i1.sequence: ki = mi.get_value(elem.id) k1 = ki / elem.l print(elem.id, k1)
s_stop=190 beam.emit_xn = 1.5e-6 beam.emit_yn = 1.5e-6 beam.emit_x = beam.emit_xn / (beam.E / 0.000511) beam.emit_y = beam.emit_yn / (beam.E / 0.000511) tw0 = Twiss(beam) exec( open('lattice_FLASH_S2E.txt')) lat = MagneticLattice(lattice, beam.E) tws=twiss(lat, tw0, nPoints=1000) lat.update_transfer_maps() tws=twiss(lat, tw0, nPoints=1000) lat.update_transfer_maps(track_acceleration = True) f=plt.figure() ax = f.add_subplot(111) ax.set_xlim(0, lat.totalLen) f.canvas.set_window_title('Betas [m]') p1, = plt.plot(map(lambda p: p.s, tws), map(lambda p: p.beta_x, tws), lw=2.0) p2, = plt.plot(map(lambda p: p.s, tws), map(lambda p: p.beta_y, tws), lw=2.0) plt.grid(True)
''' statistical run SASE ''' from ocelot import MagneticLattice from ocelot.gui.accelerator import * sys.path.append('../utils/') from xfel_utils import * launcher = get_genesis_launcher(384) beta_av = 15.0 from sase3 import * lat = MagneticLattice(sase3_segment(n=11)) rematch(beta_av, l_fodo, qdh, lat, extra_fodo, beam, qf, qd) # jeez... beam.tpulse = 20.0 # electron bunch length in fs (rms) beam.C = 0.25 # bunch charge (nC) beam.I = 1.0e-9 * beam.C / ( np.sqrt(2*pi) * beam.tpulse * 1.e-15 ) beam.E = 17.5 beam.sigma_E = 0.0001 print 'average beam size', np.sqrt(beam.emit_x * beta_av) # print out UR parameter estimates up = UndulatorParameters(und) up.E = beam.E up.printParameters()
#beam.alpha_x = -0.9443235467729223 #beam.alpha_y = -0.7496068140092198 beam.beta_x = 14.8821 beam.beta_y = 18.8146 beam.alpha_x = -0.61309 beam.alpha_y = -0.54569 beam.emit_xn = 1.5e-6 beam.emit_yn = 1.5e-6 beam.emit_x = beam.emit_xn / (beam.E / m_e_GeV) beam.emit_y = beam.emit_yn / (beam.E / m_e_GeV) tw0 = Twiss(beam) method = MethodTM() method.global_method = SecondTM lat = MagneticLattice(lattice, method=method) tws=twiss(lat, tw0, nPoints=None) #plot_opt_func(lat, tws, top_plot=["E"]) #plt.show() particle = Particle(E=beam.E) #p_array, charge_array = astraBeam2particleArray(filename='elegant_files/flash_out_200000.ast') #particleArray2astraBeam(p_array,charge_array, filename="start_BC3.ast") p_array, charge_array = astraBeam2particleArray(filename='start_BC3.ast') bins_start, hist_start = get_current(p_array, charge=charge_array[0], num_bins=200) dz = 0.2 order = 2
#t20_bz_1.e1 = e12_bz1_td20 #t20_bz_1.tilt = tilt_bz1_td20 #xQK1_TD1 = +7.2197740604e-03*1.00067 #xQK2_TD1 = +9.1218401096e-03*0.99976 #yQK1_TD1 = +2.3348937648e-02*1.00071 #yQK2_TD1 = +2.3727377870e-02*0.99988 #t1_help_2a.angle = tl_qkh_2.k1*tl_qkh_2.l*xQK1_TD1/cos(arctan(yQK1_TD1/xQK1_TD1)) #t1_help_2a.tilt = -arctan(yQK1_TD1/xQK1_TD1) #t1_help_2b.angle = tl_qkh_2.k1*tl_qkh_2.l*xQK2_TD1/cos(arctan(yQK2_TD1/xQK2_TD1)) #t1_help_2b.tilt = -arctan(yQK2_TD1/xQK2_TD1) file_name = "xfelall.inp" #tw0 = Twiss(Beam()) #i1 = i1[75:] lat = MagneticLattice((tl1, tl2, tl3, tl4, tl5, t2)) #lat = MagneticLattice((tl4,t1)) #lat = MagneticLattice(lat.sequence[72:]) write_lattice(lat, file_name="CL2SA1.inp") #Ei = 0.005 #Ef = 0.005 #for elem in lat.sequence: # if elem.type == "cavity": # Ef += elem.delta_e # if elem.type == "quadrupole": # elem.k1 = elem.k1*Ei/Ef #lat.update_transfer_maps() print lat.totalLen, len(lat.sequence) #Q = lat.sequence[74]
# MAD-X can generate sequence of elements and the sequence can be used for Ocelot lattice construction def RFcavity(l, volt, lag, harmon): rf = Cavity(l=l, eid=id) rf.volt = volt rf.lag = lag rf.harmon = harmon return rf lines_seq = lattice_str_from_madx("data/p3x_v16.seq") exec("\n".join(lines_seq)) seq = madx_seq2ocelot_seq(lattice, tot_length=ring.l, exclude_elems=[]) lat = MagneticLattice(seq) print "ring circumstance = ", lat.totalLen tws = twiss(lat, Twiss()) plot_opt_func(lat, tws) plt.show() #save lattice to file io.write_lattice(lat, "data/petra.inp") # second method more difficult and probability of errors is higher lines_data = lattice_str_from_madx("data/quadsex_p3x_v16.dat") lines_geo = lattice_str_from_madx("data/petra3_upv16.geo") #save_lattice_str(lines_data, "quadsex_p3x_v16.inp") #save_lattice_str(lines_geo, "petra3_upv16.inp")
tw0 = Twiss(beam) """ sequence = read_lattice_elegant(file_flo="elegant_files/FLASH1_flo.txt", file_par="elegant_files/FLASH1_par.txt") lat = MagneticLattice(sequence) for elem in lat.sequence: print elem.type, elem.id tw0 = Twiss(beam) tws=twiss(lat, tw0, nPoints=None) plot_opt_func(lat, tws, top_plot=["E"]) write_lattice(lat, file_name="lattice_und.inp") """ #exec(open('lattice_und.inp')) #seq = cut_lattice(old_seq=lattice, elem_id="D6DUMP") lat = MagneticLattice(lattice, start=STARTACC39) #lat = MagneticLattice(lattice) tws = twiss(lat, tw0) plot_opt_func(lat, tws, top_plot="E") #for e in lattice.sequence: # obj = e.transfer_map*obj E = beam.E L = 0 for elem in lat.sequence: #if "ACC1" in elem.id and elem.type == "cavity": # elem.v = elem.v*0.923 # elem.transfer_map = create_transfer_map(elem) # print elem.v if "ACC45" in elem.id and elem.type == "cavity":
beam.alpha_x = -0.61309 beam.alpha_y = -0.54569 beam.emit_xn = 1.5e-6 beam.emit_yn = 1.5e-6 beam.emit_x = beam.emit_xn / (beam.E / m_e_GeV) beam.emit_y = beam.emit_yn / (beam.E / m_e_GeV) tw0 = Twiss(beam) from desy.demos.ebeam.flash.lattice_FLASH_S2E import * #exec(open('lattice.inp')) #beam.beta_x = 23 #beam.beta_y = 25 method = MethodTM() method.global_method = SecondTM #method.params[Quadrupole] = "kick" lat = MagneticLattice(lattice, method=method) tws = twiss(lat, tw0, nPoints=None) plot_opt_func(lat, tws, top_plot=["E"]) #for elem in lat.sequence: # if elem.id == "C1_ACC39": # elem.v = elem.v #lat.update_transfer_maps() tws = twiss(lat, tw0, nPoints=1000) plot_opt_func(lat, tws, top_plot="E") p_array, charge_array = astraBeam2particleArray( filename='elegant_files/flash_out_200000.ast')
__author__ = 'Sergey Tomin' from ocelot.gui.accelerator import * exec( open("i1_old.inp")) tws0 = Twiss() tws0.beta_x = 13.172200000 tws0.beta_y = 13.172200 tws0.alpha_x = -1.635400 tws0.alpha_y = -1.635400 tws0.E = 0.1503 lat = MagneticLattice(lat_150MeV) tws = twiss(lat, tws0, nPoints=None) plot_opt_func(lat, tws, top_plot=["Dy", "Dx"]) plt.show() print tws[-1].beta_x, tws[-1].beta_y, tws[-1].alpha_x, tws[-1].alpha_y, tws[-1].E # Problem! the first section works wrong. # Probably the difference is because R matrices in MAD8 and Ocelot for cavities on low energy is different tws0 = Twiss() tws0.beta_x = 29.171000000 tws0.beta_y = 29.171000000 tws0.alpha_x = 10.955000 tws0.alpha_y = 10.955000 tws0.E = 0.005
from bc import * from pylab import * from ocelot import MagneticLattice from ocelot.cpbd.optics import * from ocelot.gui.accelerator import plot_lattice, plot_opt_func #lat = MagneticLattice(sase3_segment(n=7), energy=17.5) lat = MagneticLattice(bc2_l3, energy=2.4) beam = Beam() beam.E = 2.4 beam.beta_x = 41.1209 beam.beta_y = 86.3314 beam.alpha_x = 1.9630 beam.alpha_y = 4.0972 tw0 = Twiss(beam) print tw0 tws = twiss(lat, tw0, nPoints=2000) plot_opt_func(lat, tws, top_plot=["E"]) plt.show() f = plt.figure() ax = f.add_subplot(211) ax.set_xlim(0, lat.totalLen) f.canvas.set_window_title('Betas [m]') p1, = plt.plot(map(lambda p: p.s, tws), map(lambda p: p.beta_x, tws), lw=2.0) p2, = plt.plot(map(lambda p: p.s, tws), map(lambda p: p.beta_y, tws), lw=2.0) plt.grid(True)
# #plot_opt_func(lat, tws, top_plot=["Dx"]) #plt.show() #particle = Particle(E=beam.E) #p_array, charge_array = astraBeam2particleArray(filename='elegant_files/flash_out_200000.ast') #particleArray2astraBeam(p_array,charge_array, filename="start_BC3.ast") p_array, charge_array = astraBeam2particleArray(filename='start_BC3.ast') bins_start, hist_start = get_current(p_array, charge=charge_array[0], num_bins=200) from ocelot.cpbd.csr import * lat = MagneticLattice(lattice, stop=WATCHBC3_2, method=method) csr = CSR() csr.step = 1 #sc = SpaceCharge() p_array.q_array = charge_array #p_array.list2array(p_list) navi = Navigator(lat) #navi.add_physics_proc(sc, lat.sequence[0], lat.sequence[-1]) navi.add_physics_proc(csr, D00982, WATCHBC3_2) navi.unit_step = 0.05 print("### ", csr.z_csr_start, lat.totalLen) tws_track, p_array = track(lat, p_array, navi)