ATLAS Offline Software
LHEsupport.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
2 
3 # Pythonised helper functions for usage in top-level JobOptions
4 # written by Zach Marshall <zach.marshall@cern.ch>
5 # updates by Christian Gutschow <chris.g@cern.ch>
6 
7 import os,shutil
8 from AthenaCommon import Logging
9 mglog = Logging.logging.getLogger('MCJobOptionUtils')
10 
11 
12 def 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  # If we want to just use a temp file, then put in a little temp holder
18  lhe_file_new_tmp = lhe_file_new if lhe_file_new is not None else lhe_file_old+'.tmp'
19  # Make sure the LHE file is there
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  # Convert the map into a str:str map, no matter what we started with
24  pdgid_map_str = { str(x) : str(pdgid_map[x]) for x in pdgid_map }
25  # Add anti-particles if they aren't already there
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  # In case we're reading the param section and we have a block, read the block name
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
37  blockName = line.strip().upper().split()[pos]
38  elif '</slha>' in line:
39  blockName = None
40  # Check for comments - just write those and move on
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  # Replace the PDG ID in the mass block
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  # Otherwise write the line again
65  newlhe.write(line)
66 
67  # Move the new file to the old file location
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  # Delete the old file if requested
73  elif delete_old_lhe:
74  os.remove(lhe_file_old)
75 
76  return lhe_file_new_tmp
77 
78 
upper
int upper(int c)
Definition: LArBadChannelParser.cxx:49
Trk::open
@ open
Definition: BinningType.h:40
python.LHEsupport.remap_lhe_pdgids
def remap_lhe_pdgids(lhe_file_old, lhe_file_new=None, pdgid_map={}, delete_old_lhe=True)
Definition: LHEsupport.py:12
str
Definition: BTagTrackIpAccessor.cxx:11
Trk::split
@ split
Definition: LayerMaterialProperties.h:38