Skip to content

Commit 281e4eb

Browse files
committed
Merge branch 'release_v1.0.0'
2 parents 5270b23 + 4db4aa4 commit 281e4eb

26 files changed

+631
-1077
lines changed

pymask/beambeam.py

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,8 @@ def generate_set_of_bb_encounters_1beam(
181181
harmonic_number = 35640,
182182
bunch_spacing_buckets = 10,
183183
numberOfHOSlices = 11,
184-
bunch_charge_ppb = 0.,
184+
bunch_num_particles = 0.,
185+
bunch_particle_charge = 0.,
185186
sigt=0.0755,
186187
relativistic_beta=1.,
187188
ip_names = ['ip1', 'ip2', 'ip5', 'ip8'],
@@ -201,7 +202,8 @@ def generate_set_of_bb_encounters_1beam(
201202
if len(myBBLRlist)>0:
202203
myBBLR=pd.DataFrame(myBBLRlist)[['beam','other_beam','ip_name','label','identifier']]
203204

204-
myBBLR['self_charge_ppb'] = bunch_charge_ppb
205+
myBBLR['self_num_particles'] = bunch_num_particles
206+
myBBLR['self_particle_charge'] = bunch_particle_charge
205207
myBBLR['self_relativistic_beta'] = relativistic_beta
206208
myBBLR['elementName']=myBBLR.apply(lambda x: elementName(x.label, x.ip_name.replace('ip', ''), x.beam, x.identifier), axis=1)
207209
myBBLR['other_elementName']=myBBLR.apply(
@@ -229,7 +231,8 @@ def generate_set_of_bb_encounters_1beam(
229231
myBBHO=pd.DataFrame(myBBHOlist)[['beam','other_beam', 'ip_name','label','identifier']]
230232

231233

232-
myBBHO['self_charge_ppb'] = bunch_charge_ppb/numberOfHOSlices
234+
myBBHO['self_num_particles'] = bunch_num_particles/numberOfHOSlices
235+
myBBHO['self_particle_charge'] = bunch_particle_charge
233236
myBBHO['self_relativistic_beta'] = relativistic_beta
234237
for ip_nn in ip_names:
235238
myBBHO.loc[myBBHO['ip_name']==ip_nn, 'atPosition']=list(z_centroids)
@@ -249,7 +252,7 @@ def generate_set_of_bb_encounters_1beam(
249252

250253
return myBB
251254

252-
def generate_mad_bb_info(bb_df, mode='dummy', madx_reference_bunch_charge=1):
255+
def generate_mad_bb_info(bb_df, mode='dummy', madx_reference_bunch_num_particles=1):
253256

254257
if mode == 'dummy':
255258
bb_df['elementClass']='beambeam'
@@ -259,7 +262,7 @@ def generate_mad_bb_info(bb_df, mode='dummy', madx_reference_bunch_charge=1):
259262
'yma = 1, ' + \
260263
f'charge = 0*{charge}, ' +\
261264
'slot_id = %d'%({'bb_lr': 4, 'bb_ho': 6}[label]) # need to add 60 for central
262-
bb_df['elementDefinition']=bb_df.apply(lambda x: elementDefinition(x.elementName, x.elementClass, eattributes(x['self_charge_ppb'], x['label'])), axis=1)
265+
bb_df['elementDefinition']=bb_df.apply(lambda x: elementDefinition(x.elementName, x.elementClass, eattributes(x['self_num_particles'], x['label'])), axis=1)
263266
bb_df['elementInstallation']=bb_df.apply(lambda x: elementInstallation(x.elementName, x.elementClass, x.atPosition, x.ip_name), axis=1)
264267
elif mode=='from_dataframe':
265268
bb_df['elementClass']='beambeam'
@@ -272,7 +275,7 @@ def generate_mad_bb_info(bb_df, mode='dummy', madx_reference_bunch_charge=1):
272275
bb_df['elementDefinition']=bb_df.apply(lambda x: elementDefinition(x.elementName, x.elementClass,
273276
eattributes(np.sqrt(x['other_Sigma_11']),np.sqrt(x['other_Sigma_33']),
274277
x['xma'], x['yma'],
275-
x['other_charge_ppb']/madx_reference_bunch_charge, x['label'])),
278+
x['other_particle_charge']*x['other_num_particles']/madx_reference_bunch_num_particles, x['label'])), # patch due to the fact that mad-x takes n_part from the weak beam
276279
axis=1)
277280
bb_df['elementInstallation']=bb_df.apply(lambda x: elementInstallation(x.elementName, x.elementClass, x.atPosition, x.ip_name), axis=1)
278281
else:
@@ -290,8 +293,10 @@ def get_counter_rotating(bb_df):
290293
c_bb_df['identifier'] = bb_df['identifier']
291294
c_bb_df['elementClass'] = bb_df['elementClass']
292295
c_bb_df['elementName'] = bb_df['elementName']
293-
c_bb_df['self_charge_ppb'] = bb_df['self_charge_ppb']
294-
c_bb_df['other_charge_ppb'] = bb_df['other_charge_ppb']
296+
c_bb_df['self_num_particles'] = bb_df['self_num_particles']
297+
c_bb_df['other_num_particles'] = bb_df['other_num_particles']
298+
c_bb_df['self_particle_charge'] = bb_df['self_particle_charge']
299+
c_bb_df['other_particle_charge'] = bb_df['other_particle_charge']
295300
c_bb_df['other_elementName'] = bb_df['other_elementName']
296301

297302
c_bb_df['atPosition'] = bb_df['atPosition'] * (-1.)
@@ -349,9 +354,9 @@ def install_lenses_in_sequence(mad, bb_df, sequence_name,
349354
regenerate_mad_bb_info_in_df=True):
350355

351356
if regenerate_mad_bb_info_in_df:
352-
madx_reference_bunch_charge = mad.sequence[sequence_name].beam.npart
357+
madx_reference_bunch_num_particles = mad.sequence[sequence_name].beam.npart
353358
generate_mad_bb_info(bb_df, mode='from_dataframe',
354-
madx_reference_bunch_charge=madx_reference_bunch_charge)
359+
madx_reference_bunch_num_particles=madx_reference_bunch_num_particles)
355360

356361
mad.input(bb_df['elementDefinition'].str.cat(sep='\n'))
357362

@@ -429,7 +434,8 @@ def get_partner_corrected_position_and_optics(bb_df_b1, bb_df_b2, ip_position_df
429434
for ss in _sigma_names:
430435
self_df.loc[ee, f'other_Sigma_{ss}'] = other_df.loc[other_ee, f'self_Sigma_{ss}']
431436
# Get charge of other beam
432-
self_df.loc[ee, 'other_charge_ppb'] = other_df.loc[other_ee, 'self_charge_ppb']
437+
self_df.loc[ee, 'other_num_particles'] = other_df.loc[other_ee, 'self_num_particles']
438+
self_df.loc[ee, 'other_particle_charge'] = other_df.loc[other_ee, 'self_particle_charge']
433439
self_df.loc[ee, 'other_relativistic_beta'] = other_df.loc[other_ee, 'self_relativistic_beta']
434440

435441
def compute_separations(bb_df):
@@ -621,26 +627,27 @@ def setup_beam_beam_in_line(
621627
bb_df,
622628
bb_coupling=False,
623629
):
624-
import pysixtrack
630+
import xline
625631
assert bb_coupling is False # Not implemented
626632

627633
for ee, eename in zip(line.elements, line.element_names):
628-
if isinstance(ee, pysixtrack.elements.BeamBeam4D):
629-
ee.charge = bb_df.loc[eename, 'other_charge_ppb']
634+
if isinstance(ee, xline.elements.BeamBeam4D):
635+
ee.charge = (bb_df.loc[eename, 'other_num_particles']
636+
* bb_df.loc[eename, 'other_particle_charge']) # TODO update xline interface to separate charge and b. population
630637
ee.sigma_x = np.sqrt(bb_df.loc[eename, 'other_Sigma_11'])
631638
ee.sigma_y = np.sqrt(bb_df.loc[eename, 'other_Sigma_33'])
632639
ee.beta_r = bb_df.loc[eename, 'other_relativistic_beta']
633640
ee.x_bb = bb_df.loc[eename, 'separation_x']
634641
ee.y_bb = bb_df.loc[eename, 'separation_y']
635642

636-
if isinstance(ee, pysixtrack.elements.BeamBeam6D):
643+
if isinstance(ee, xline.elements.BeamBeam6D):
637644

638645
ee.phi = bb_df.loc[eename, 'phi']
639646
ee.alpha = bb_df.loc[eename, 'alpha']
640647
ee.x_bb_co = bb_df.loc[eename, 'separation_x']
641648
ee.y_bb_co = bb_df.loc[eename, 'separation_y']
642-
643-
ee.charge_slices = [bb_df.loc[eename, 'other_charge_ppb']]
649+
ee.charge_slices = [(bb_df.loc[eename, 'other_num_particles']
650+
* bb_df.loc[eename, 'other_particle_charge'])] # TODO update xline interface to separate charge and b. population
644651
ee.zeta_slices = [0.0]
645652
ee.sigma_11 = bb_df.loc[eename, 'other_Sigma_11']
646653
ee.sigma_12 = bb_df.loc[eename, 'other_Sigma_12']
@@ -735,7 +742,8 @@ def generate_bb_dataframes(mad,
735742
harmonic_number=35640,
736743
bunch_spacing_buckets=10,
737744
numberOfHOSlices=11,
738-
bunch_population_ppb=None,
745+
bunch_num_particles=None,
746+
bunch_particle_charge=None,
739747
sigmaz_m=None,
740748
z_crab_twiss=0.,
741749
remove_dummy_lenses=True):
@@ -744,13 +752,17 @@ def generate_bb_dataframes(mad,
744752
assert mad.sequence.lhcb1.beam[pp] == mad.sequence.lhcb2.beam[pp]
745753

746754
circumference = mad.sequence.lhcb1.beam.circ
747-
madx_reference_bunch_charge = mad.sequence.lhcb1.beam.npart
755+
madx_reference_bunch_num_particles = mad.sequence.lhcb1.beam.npart
756+
757+
if bunch_num_particles is None:
758+
bunch_num_particles = madx_reference_bunch_num_particles
759+
if bunch_particle_charge is None:
760+
bunch_particle_charge = mad.sequence.lhcb1.beam.charge
761+
762+
763+
748764
relativistic_gamma = mad.sequence.lhcb1.beam.gamma
749765
relativistic_beta = np.sqrt(1 - 1.0 / relativistic_gamma ** 2)
750-
if bunch_population_ppb is not None:
751-
bunch_charge_ppb = bunch_population_ppb
752-
else:
753-
bunch_charge_ppb = madx_reference_bunch_charge
754766

755767
if sigmaz_m is not None:
756768
sigt = sigmaz_m
@@ -760,15 +772,18 @@ def generate_bb_dataframes(mad,
760772
bb_df_b1 = generate_set_of_bb_encounters_1beam(
761773
circumference, harmonic_number,
762774
bunch_spacing_buckets,
763-
numberOfHOSlices, bunch_charge_ppb, sigt,
764-
relativistic_beta, ip_names, numberOfLRPerIRSide,
775+
numberOfHOSlices,
776+
bunch_num_particles, bunch_particle_charge,
777+
sigt, relativistic_beta, ip_names, numberOfLRPerIRSide,
765778
beam_name = 'b1',
766779
other_beam_name = 'b2')
767780

768781
bb_df_b2 = generate_set_of_bb_encounters_1beam(
769782
circumference, harmonic_number,
770783
bunch_spacing_buckets,
771-
numberOfHOSlices, bunch_charge_ppb, sigt,
784+
numberOfHOSlices,
785+
bunch_num_particles, bunch_particle_charge,
786+
sigt,
772787
relativistic_beta, ip_names, numberOfLRPerIRSide,
773788
beam_name = 'b2',
774789
other_beam_name = 'b1')
@@ -808,13 +823,13 @@ def generate_bb_dataframes(mad,
808823

809824
# Generate mad info
810825
generate_mad_bb_info(bb_df_b1, mode='from_dataframe',
811-
madx_reference_bunch_charge=madx_reference_bunch_charge)
826+
madx_reference_bunch_num_particles=madx_reference_bunch_num_particles)
812827
generate_mad_bb_info(bb_df_b2, mode='from_dataframe',
813-
madx_reference_bunch_charge=madx_reference_bunch_charge)
828+
madx_reference_bunch_num_particles=madx_reference_bunch_num_particles)
814829
generate_mad_bb_info(bb_df_b3, mode='from_dataframe',
815-
madx_reference_bunch_charge=madx_reference_bunch_charge)
830+
madx_reference_bunch_num_particles=madx_reference_bunch_num_particles)
816831
generate_mad_bb_info(bb_df_b4, mode='from_dataframe',
817-
madx_reference_bunch_charge=madx_reference_bunch_charge)
832+
madx_reference_bunch_num_particles=madx_reference_bunch_num_particles)
818833

819834
bb_dfs = {
820835
'b1': bb_df_b1,
@@ -873,4 +888,4 @@ def compute_xma_yma(bb_df):
873888
)
874889

875890
bb_df['xma'] = xma
876-
bb_df['yma'] = yma
891+
bb_df['yma'] = yma

pymask/pymasktools.py

Lines changed: 50 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,8 @@ def check_separations_against_madvars(checks, twiss_df_b1, twiss_df_b2, variable
182182
cc['plane'], target, cc['tol'])
183183

184184
def generate_sixtrack_input(mad, seq_name, bb_df, output_folder,
185-
reference_bunch_charge_sixtrack_ppb,
185+
reference_num_particles_sixtrack,
186+
reference_particle_charge_sixtrack,
186187
emitnx_sixtrack_um,
187188
emitny_sixtrack_um,
188189
sigz_sixtrack_m,
@@ -193,7 +194,7 @@ def generate_sixtrack_input(mad, seq_name, bb_df, output_folder,
193194
ibbc_sixtrack,
194195
radius_sixtrack_multip_conversion_mad,
195196
skip_mad_use=False):
196-
197+
197198
six_fol_name = output_folder
198199
os.makedirs(six_fol_name, exist_ok=True)
199200

@@ -233,8 +234,11 @@ def generate_sixtrack_input(mad, seq_name, bb_df, output_folder,
233234
if len(sxt_df_4d) > 0:
234235
sxt_df_4d['h-sep [mm]'] = -sxt_df_4d['separation_x']*1e3
235236
sxt_df_4d['v-sep [mm]'] = -sxt_df_4d['separation_y']*1e3
236-
sxt_df_4d['strength-ratio'] = (sxt_df_4d['other_charge_ppb']
237-
/ reference_bunch_charge_sixtrack_ppb)
237+
sxt_df_4d['strength-ratio'] = (
238+
sxt_df_4d['other_num_particles']
239+
* sxt_df_4d['other_particle_charge']
240+
/ reference_num_particles_sixtrack)
241+
#/ reference_particle_charge_sixtrack)# patch for sixtrack inconsistency
238242
sxt_df_4d['4dSxx [mm*mm]'] = sxt_df_4d['other_Sigma_11']*1e6
239243
sxt_df_4d['4dSyy [mm*mm]'] = sxt_df_4d['other_Sigma_33']*1e6
240244
sxt_df_4d['4dSxy [mm*mm]'] = sxt_df_4d['other_Sigma_13']*1e6
@@ -256,7 +260,11 @@ def generate_sixtrack_input(mad, seq_name, bb_df, output_folder,
256260
sxt_df_6d['v-sep [mm]'] = -sxt_df_6d['separation_y']*1e3
257261
sxt_df_6d['phi [rad]'] = sxt_df_6d['phi']
258262
sxt_df_6d['alpha [rad]'] = sxt_df_6d['alpha']
259-
sxt_df_6d['strength-ratio'] = sxt_df_6d['other_charge_ppb']/reference_bunch_charge_sixtrack_ppb
263+
sxt_df_6d['strength-ratio'] = (
264+
sxt_df_6d['other_num_particles']
265+
* sxt_df_6d['other_particle_charge']
266+
/ reference_num_particles_sixtrack)
267+
#/ reference_particle_charge_sixtrack) # patch for sixtrack
260268
sxt_df_6d['Sxx [mm*mm]'] = sxt_df_6d['other_Sigma_11'] *1e6
261269
sxt_df_6d['Sxxp [mm*mrad]'] = sxt_df_6d['other_Sigma_12'] *1e6
262270
sxt_df_6d['Sxpxp [mrad*mrad]'] = sxt_df_6d['other_Sigma_22'] *1e6
@@ -290,7 +298,7 @@ def generate_sixtrack_input(mad, seq_name, bb_df, output_folder,
290298
]), axis=1)
291299

292300
f3_common_settings = ' '.join([
293-
f"{reference_bunch_charge_sixtrack_ppb}",
301+
f"{reference_num_particles_sixtrack*reference_particle_charge_sixtrack}",
294302
f"{emitnx_sixtrack_um}",
295303
f"{emitny_sixtrack_um}",
296304
f"{sigz_sixtrack_m}",
@@ -370,24 +378,24 @@ def get_optics_and_orbit_at_start_ring(mad, seq_name, with_bb_forces=False,
370378
}
371379
return optics_at_start_ring
372380

373-
def generate_pysixtrack_line_with_bb(mad, seq_name, bb_df,
381+
def generate_xline_with_bb(mad, seq_name, bb_df,
374382
closed_orbit_method='from_mad', pickle_lines_in_folder=None,
375383
skip_mad_use=False):
376384

377385
opt_and_CO = get_optics_and_orbit_at_start_ring(mad, seq_name,
378386
with_bb_forces=False, skip_mad_use=True)
379387

380-
# Build pysixtrack model
381-
import pysixtrack
382-
pysxt_line = pysixtrack.Line.from_madx_sequence(
383-
mad.sequence[seq_name])
388+
# Build xline model
389+
import xline
390+
line = xline.Line.from_madx_sequence(
391+
mad.sequence[seq_name], apply_madx_errors=True)
384392

385393
if bb_df is not None:
386-
bb.setup_beam_beam_in_line(pysxt_line, bb_df, bb_coupling=False)
394+
bb.setup_beam_beam_in_line(line, bb_df, bb_coupling=False)
387395

388396
# Temporary fix due to bug in mad loader
389-
cavities, cav_names = pysxt_line.get_elements_of_type(
390-
pysixtrack.elements.Cavity)
397+
cavities, cav_names = line.get_elements_of_type(
398+
xline.elements.Cavity)
391399
for cc, nn in zip(cavities, cav_names):
392400
if cc.frequency ==0.:
393401
ii_mad = mad.sequence[seq_name].element_names().index(nn)
@@ -397,37 +405,42 @@ def generate_pysixtrack_line_with_bb(mad, seq_name, bb_df,
397405

398406
mad_CO = np.array([opt_and_CO[kk] for kk in ['x', 'px', 'y', 'py', 'sigma', 'delta']])
399407

400-
pysxt_line.disable_beambeam()
401-
part_on_CO = pysxt_line.find_closed_orbit(
408+
line.disable_beambeam()
409+
part_on_CO = line.find_closed_orbit(
402410
guess=mad_CO, p0c=opt_and_CO['p0c_eV'],
403411
method={'from_mad': 'get_guess', 'from_tracking': 'Nelder-Mead'}[closed_orbit_method])
404-
pysxt_line.enable_beambeam()
412+
line.enable_beambeam()
405413

406-
pysxt_line_bb_dipole_cancelled = pysxt_line.copy()
414+
line_bb_dipole_cancelled = line.copy()
407415

408-
pysxt_line_bb_dipole_cancelled.beambeam_store_closed_orbit_and_dipolar_kicks(
416+
line_bb_dipole_cancelled.beambeam_store_closed_orbit_and_dipolar_kicks(
409417
part_on_CO,
410418
separation_given_wrt_closed_orbit_4D=True,
411419
separation_given_wrt_closed_orbit_6D=True)
412420

413-
pysxt_dict = {
414-
'line_bb_dipole_not_cancelled': pysxt_line,
415-
'line_bb_dipole_cancelled': pysxt_line_bb_dipole_cancelled,
421+
xline_dict = {
422+
'line_bb_dipole_not_cancelled': line,
423+
'line_bb_dipole_cancelled': line_bb_dipole_cancelled,
416424
'particle_on_closed_orbit': part_on_CO}
417425

418426
if pickle_lines_in_folder is not None:
419-
pysix_fol_name = pickle_lines_in_folder
420-
os.makedirs(pysix_fol_name, exist_ok=True)
421-
422-
with open(pysix_fol_name + "/line_bb_dipole_not_cancelled.pkl", "wb") as fid:
423-
pickle.dump(pysxt_line.to_dict(keepextra=True), fid)
424-
425-
with open(pysix_fol_name + "/line_bb_dipole_cancelled.pkl", "wb") as fid:
426-
pickle.dump(pysxt_line_bb_dipole_cancelled.to_dict(keepextra=True), fid)
427-
428-
with open(pysix_fol_name + "/particle_on_closed_orbit.pkl", "wb") as fid:
429-
pickle.dump(part_on_CO.to_dict(), fid)
430-
431-
return pysxt_dict
432-
433-
427+
xline_fol_name = pickle_lines_in_folder
428+
os.makedirs(xline_fol_name, exist_ok=True)
429+
430+
line.to_json(xline_fol_name + "/line_bb_dipole_not_cancelled.json", keepextra=True)
431+
line_bb_dipole_cancelled.to_json(xline_fol_name + "/line_bb_dipole_cancelled.json", keepextra=True)
432+
part_on_CO.to_json(xline_fol_name + "/particle_on_closed_orbit.json")
433+
434+
return xline_dict
435+
436+
def save_mad_sequence_and_error(mad, seq_name, filename='lhc'):
437+
mad.select(flag="error",clear=True)
438+
mad.select(flag="error",class_="multipole")
439+
mad.select(flag="error",class_="hkicker")
440+
mad.select(flag="error",class_="vkicker")
441+
mad.select(flag="error",class_="kicker")
442+
mad.esave(file=filename + "_errors.tfs")
443+
mad.select(flag="error",clear=True)
444+
mad.select(flag="error",full=True)
445+
mad.esave(file=filename + "_errors_all.tfs")
446+
mad.save(sequence=seq_name,beam=True,file=filename + "_seq.madx")

python_examples/clean_all

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ rm twiss_bb
99
rm last_twiss.*.gz
1010
rm fort.*
1111
rm *.tfs
12-
rm -r pysixtrack
12+
rm -r xline
1313
rm -r temp
1414
rm -r __pycache__
1515

0 commit comments

Comments
 (0)