12def remap_lhe_pdgids(lhe_file_old,lhe_file_new=None,pdgid_map={},delete_old_lhe=True):
13 """Update the PDG IDs used in an LHE file. This is a bit finicky, as we have to
14 both touch the LHE file metadata _and_ modify the events themselves. But since this
15 is "just" a remapping, it should be safe assuming Pythia8 is told the correct thing
16 afterwards and can get the showering right."""
17
18 lhe_file_new_tmp = lhe_file_new if lhe_file_new is not None else lhe_file_old+'.tmp'
19
20 if not os.access(lhe_file_old,os.R_OK):
21 raise RuntimeError('Could not access old LHE file at '+str(lhe_file_old)+'. Please check the file location.')
22
23
24 pdgid_map_str = { str(x) : str(pdgid_map[x]) for x in pdgid_map }
25
26 pdgid_map_str.update( { '-'+str(x) : '-'+str(pdgid_map[x]) for x in pdgid_map if '-'+str(x) not in pdgid_map } )
27
28 newlhe = open(lhe_file_new_tmp,'w')
29 blockName = None
30 eventRead = False
31 with open(lhe_file_old,'r') as fileobject:
32 for line in fileobject:
33
34 if line.strip().
upper().startswith(
'BLOCK')
or line.strip().
upper().startswith(
'DECAY')\
35 and len(line.strip().
split()) > 1:
36 pos = 0 if line.strip().startswith('DECAY') else 1
38 elif '</slha>' in line:
39 blockName = None
40
41 if len(line.split(
'#')[0].
strip())==0:
42 line_mod = line
43 for pdgid in pdgid_map_str:
44 if pdgid in line_mod.split():
45 line_mod = line_mod.replace( pdgid , pdgid_map_str[pdgid] )
46 newlhe.write(line_mod)
47 continue
48
49 if blockName=='MASS' and line.split()[0] in pdgid_map_str:
50 newlhe.write( line.replace( line.split()[0] , pdgid_map_str[ line.split()[0] ] , 1 ) )
51 continue
52 if blockName=='DECAY' and line.split()[1] in pdgid_map_str:
53 newlhe.write( line.replace( line.split()[1] , pdgid_map_str[ line.split()[1] ] , 1 ) )
54 continue
55 if blockName=='QNUMBERS' and line.split()[2] in pdgid_map_str:
56 newlhe.write( line.replace( line.split()[2] , pdgid_map_str[ line.split()[2] ] , 1 ) )
57 continue
58 if '<event>' in line:
59 eventRead = True
60 if eventRead and len(line.split())==13 and line.split()[0] in pdgid_map_str:
61 newlhe.write( line.replace( line.split()[0] , pdgid_map_str[ line.split()[0] ] , 1 ) )
62 continue
63
64
65 newlhe.write(line)
66
67
68 if lhe_file_new is None:
69 os.remove(lhe_file_old)
70 shutil.move(lhe_file_new_tmp,lhe_file_old)
71 lhe_file_new_tmp = lhe_file_old
72
73 elif delete_old_lhe:
74 os.remove(lhe_file_old)
75
76 return lhe_file_new_tmp
77
78
std::vector< std::string > split(const std::string &s, const std::string &t=":")