ATLAS Offline Software
DiagramRemoval.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2 
3 # Code to perform Diagram Removal 1 or 2, either for the matrix element (do_DRX) or for MadSpin (do_MadSpin_DRX)
4 # Works for tW, tWZ and tWH. Removes the overlap with tt, ttZ and ttH respectively.
5 # DR1: without interference. DR2: with interference.
6 # Does not work for tWgamma and tWll.
7 # Contact: olga.bylund@cern.ch
8 # Please let me know if you have any questions or problems.
9 
10 import os,re,glob,shutil,sys,fileinput
11 from AthenaCommon import Logging
12 drlog = Logging.logging.getLogger('DiagramRemoval')
13 
14 #General functions
15 def find_matrix_files(process_dir):
16  return glob.glob(process_dir+"/P*_*/matrix_*.f")
17 
18 
19 def get_process(infile,test_string='Process:'):
20  output = []
21  with open(infile,'r') as f:
22  for line in f:
23  if test_string in line:
24  output += [line]
25  return output
26 
27 
28 def return_out_index(process): #which index does the final state particle have
29  p_in,p_out = process.split(" > ")
30  p_in = p_in.split(" ")
31  p_out = p_out.split(" ")
32  particles = p_in+p_out
33 
34  windex = -1
35  bindex = -1
36  for i,particle in enumerate(particles):
37  if (particle in (["w-","w+"])) and i>=len(p_in): #is it a FS particle?
38  windex = i+1
39  elif (particle in (["b","b~"])) and i>=len(p_in):
40  bindex = i+1
41 
42  return bindex, windex
43 
44 
45 # Finds the amplitudes that overlap with tt(+X)
46 def find_W_prepare_DRXhack(mfile,bindex,windex,redefine_twidth,which_DR):
47  W_vector=[]
48  updated_vector=[]
49  the_W=""
50  with open(mfile,"r") as f, open("mytmp.txt","w") as tmpf:
51  to_replace={}
52  mylines = f.readlines()
53  for i,line in enumerate(mylines):
54  if "1,"+str(bindex)+"))" in line.split("(")[-1] and "XXXXX" not in mylines[i]: # is b quark being rewritten? Beware if >10
55  bindex=-1
56  elif "1,"+str(windex)+"))" in line.split("(")[-1] and "XXXXX" not in mylines[i]: # is w boson being rewritten? Beware if >10
57  windex=-1
58 
59  if W_vector!=[]:
60  for j in range(len(W_vector)):
61  if W_vector[j] in line and "AMP(" in line: #save AMP
62  amplitude = line.split(",")[-1]
63  if which_DR==1:
64  tmpf.write(" "+amplitude[:-2]+"=(0d0,0d0)\n") #set to zero (DR)
65  elif which_DR==2:
66  tmpf.write(amplitude[:-2]+"\n") #save amplitude
67  elif W_vector[j] in line and "AMP" not in line:
68  if W_vector[j]+")" in line: # W is redefined, stop keeping track of it
69  updated_vector.remove(W_vector[j])
70  else: # a new W is defined, containing a flagged W. keep track of it
71  the_W = line.split(",")[-2]+","+line.split(",")[-1][0:-2]
72  updated_vector.append(the_W)
73  W_vector=updated_vector
74 
75  if "W(1,"+str(bindex)+")" in mylines[i] and "W(1,"+str(windex)+")" in mylines[i] and "MDL_WT" in mylines[i]:
76  the_W = line.split(",")[-2]+","+line.split(",")[-1][0:-2]
77  W_vector.append(the_W)
78  updated_vector=W_vector
79 
80  if redefine_twidth:
81  edited_line = line.replace("MDL_WT","MDL_WT_nonzero")
82  to_replace[i]=edited_line
83  return to_replace
84 
85 #-------------------------------------
86 def do_DR1_hacks(mfile,tmpfile):
87  drlog.info("performing DR1 for file "+mfile)
88  dr1Hack_done = False
89  with open(tmpfile,"r") as mytmp:
90  for line in fileinput.input(mfile, inplace=True):
91  # fileinput redirects the print output to mfile
92  if re.search(r'TMP_JAMP\‍(\d+\‍) =', line) and not dr1Hack_done:
93  print("\nC DR hack")
94  for hackline in mytmp:
95  print(hackline)
96  print("C End DR hack. \n")
97  dr1Hack_done = True
98  print(line)
99 
100 #-------------------------------
101 #DR2 helper functions
102 def do_driver_hacks(driver_filename): #takes care of negative weights in code for driver.f for madspin
103  test_string1 = "weight.gt."
104  repl_string1 = "abs(weight).gt."
105 
106  test_string2 = "maxweight=weight"
107  repl_string2 = "maxweight=abs(weight)"
108 
109  source = open(driver_filename,"r")
110  mylines = source.readlines()
111  with open(driver_filename,"w") as source:
112  for i,line in enumerate(mylines):
113  if test_string1 in line:
114  mylines[i] = line.replace(test_string1,repl_string1)
115  if test_string2 in line:
116  mylines[i] = line.replace(test_string2,repl_string2)
117  source.write(mylines[i])
118 
119 
120 def do_fks_hacks(pdir): #takes care of negative weights for event generation code
121  shutil.copyfile(pdir+"fks_singular.f", pdir+"fks_singular.f~" )
122 
123  test_string = "wgt.lt.0.d0"
124  end_string = "return"
125 
126  with open(pdir+"fks_singular.f","w") as destination, open(pdir+"fks_singular.f~") as source:
127  mylines = source.readlines()
128  dont_comment = True
129  for i,line in enumerate(mylines):
130  if dont_comment:
131  if test_string in line:
132  dont_comment=False
133  destination.write("C"+line)
134  else:
135  destination.write(line)
136  else:
137  if end_string in line:
138  dont_comment=True
139  destination.write(line)
140  else:
141  destination.write("C"+line)
142 
143  os.remove(pdir+"fks_singular.f~")
144 
145 def do_coupl_hacks(pdir): #define the width of the top quark for the event generation code
146  shutil.copyfile(pdir+"coupl.inc", pdir+"coupl.inc~" )
147 
148  test_string1 = "MDL_WT"
149  test_string2 = "WIDTHS"
150 
151  with open(pdir+"../Cards/param_card.dat","r") as pcard:
152  the_lines = pcard.readlines()
153  for line in the_lines:
154  if "DECAY" in line and " 6 " in line:
155  top_width = line.split(" 6 ")[-1].rstrip()
156  break
157 
158  with open(pdir+"coupl.inc","w") as destination, open(pdir+"coupl.inc~") as source:
159  mylines = source.readlines()
160  for i,line in enumerate(mylines):
161  destination.write(line)
162  if test_string1 in line and test_string2 in line:
163  destination.write("\n DOUBLE PRECISION MDL_WT_nonzero\n")
164  destination.write(" PARAMETER (MDL_WT_nonzero="+top_width+")\n")
165 
166  os.remove(pdir+"coupl.inc~")
167 
168 #-------------------------
169 # DR2 specific
170 def find_jamp(mfile,helperfile,test_string,end_string):
171 
172  with open(mfile,"r") as source:
173  mylines = source.readlines()
174  dont_store = True
175  my_jamp = ""
176  for i,line in enumerate(mylines):
177  if dont_store:
178  if test_string in line:
179  dont_store=False
180  my_jamp += line
181 
182  else:
183  if end_string in line:
184  dont_store=True
185  else:
186  my_jamp += line
187 
188  with open(helperfile,"w") as destination:
189  destination.write(my_jamp)
190  drlog.info("my_jamp = "+str(my_jamp))
191 
192 
193 def do_DR2_hack(mfile, tmpfile, suffix,to_replace,should_replace): #to_replace and should_replace refer to whether to put top propagator on shell - do so for madgraph code but not for madspin
194  shutil.copyfile(mfile, mfile+"~" )
195  with open(mfile,"w") as destination, open(mfile+"~") as source, open(tmpfile,"r") as mytmp, open(mfile+".jamp1","r") as saved_jamp1, open(mfile+".jamp2","r") as saved_jamp2:
196  tmp_content = mytmp.readlines()
197  for i,line in enumerate(source):
198  if i in to_replace.keys() and should_replace==1:
199  destination.write(to_replace[i])
200  else:
201  destination.write(line)
202 
203  if "JAMP(NCOLOR)" in line and "COMPLEX*16" in line:
204  destination.write(" REAL*8 MATRIX"+suffix+"_res\n")
205  destination.write(" COMPLEX*16 JAMP_res(NCOLOR)\n")
206  elif "JAMP(1)=" in line:
207  drlog.info("performing DR2 for file "+mfile)
208  jamplines = saved_jamp1.readlines()
209  my_jamp1 = ""
210  for j,jline in enumerate(jamplines):
211  my_jamp1 += jline
212  jamp_res1 = "JAMP_res(1)="+write_jamp_res(my_jamp1,tmp_content)
213  elif "JAMP(2)=" in line:
214  jamplines = saved_jamp2.readlines()
215  my_jamp2 = ""
216  for j,jline in enumerate(jamplines):
217  my_jamp2 += jline
218 
219  jamp_res2 = "JAMP_res(2)="+write_jamp_res(my_jamp2,tmp_content)
220 
221  elif "DENOM(I)" in line:
222  line=next(source)
223  destination.write(line)
224  destination.write("\n "+jamp_res1)
225  destination.write(" "+jamp_res2+"\n")
226  hardcode = " MATRIX"+suffix+"_res = 0.D0\n DO I = 1, NCOLOR\n ZTEMP = (0.D0,0.D0)\n DO J = 1, NCOLOR\n ZTEMP = ZTEMP + CF(J,I)*JAMP_res(J)\n ENDDO\n MATRIX"+suffix+"_res = MATRIX"+suffix+"_res+ZTEMP*DCONJG(JAMP_res(I))/DENOM(I)\n ENDDO\n MATRIX"+suffix+" = MATRIX"+suffix+" - MATRIX"+suffix+"_res\n"
227  destination.write(hardcode)
228 
229  os.remove(mfile+"~")
230 
231 def write_jamp_res(my_jamp_line,tmp_c):
232  line = my_jamp_line
233  my_jamp_line = my_jamp_line.replace("+",",+")
234  my_jamp_line = my_jamp_line.replace("-",",-")
235  split_line = my_jamp_line.split(",")[1:]
236  jamp_resX = ""
237  for amp in tmp_c:
238  for term in split_line:
239  if amp[:-1] in term:
240  jamp_resX = jamp_resX+term
241 
242  jamp_prefix = line.split("=")[1].split("*(")
243  if len(jamp_prefix)>1:
244  jamp_resX = jamp_prefix[0]+"*("+jamp_resX
245  if jamp_resX[-2:]!="\n":
246  if "))" not in jamp_resX[-4:]:
247  jamp_resX=jamp_resX+")\n"
248  else:
249  jamp_resX=jamp_resX+"\n"
250 
251  else:
252  if "\n" not in jamp_resX:
253  jamp_resX=jamp_resX+"\n"
254 
255  return jamp_resX
256 
257 
258 
261 
262 def do_DRX(DRmode, process_dir):
263  drlog.info("in do_DRX, DRmode="+str(DRmode)+", process_dir = "+process_dir)
264  pdir=process_dir+'/SubProcesses/'
265 
266  if DRmode==2:
267  do_fks_hacks(pdir)
268  do_coupl_hacks(pdir)
269 
270  mfiles = find_matrix_files(pdir)
271 
272  for mfile in mfiles:
273  matrix_idx = re.compile(r"matrix_(\d+).f").search(mfile).group(1)
274  process = get_process(mfile)
275 
276  for myline in process:
277  m2 = myline.split("Process: ")[1]
278  the_process = m2.split(" WEIGHTED")[0]
279 
280  bindex, windex = return_out_index(the_process)
281 
282  if DRmode==1:
283  redefine_twidth=False
284  elif DRmode==2:
285  redefine_twidth=True
286  to_replace = find_W_prepare_DRXhack(mfile,bindex,windex,redefine_twidth,DRmode)
287 
288  if os.path.getsize("mytmp.txt")>0: #if there are hacks to make
289  if DRmode==1:
290  do_DR1_hacks(mfile,"mytmp.txt")
291  elif DRmode==2:
292  find_jamp(mfile,mfile+".jamp1","JAMP(1)","JAMP(2)")
293  find_jamp(mfile,mfile+".jamp2","JAMP(2)","MATRIX")
294  do_DR2_hack(mfile, "mytmp.txt","_"+matrix_idx,to_replace,1)
295 
296  os.remove(mfile+".jamp1")
297  os.remove(mfile+".jamp2")
298 
299 
302 def do_MadSpin_DRX(DRmode, msdirname):
303 
304  my_ms_dir=msdirname
305  pdir=my_ms_dir+'/production_me/SubProcesses/'
306  fdir=my_ms_dir+'/full_me/SubProcesses/'
307  full_files=os.listdir(fdir)
308  mfiles = find_matrix_files(pdir)
309 
310  for mfile in mfiles:
311  process = get_process(mfile)
312 
313  for myline in process:
314  m2 = myline.split("Process: ")[1]
315  the_process = m2.split("WEIGHTED")[0]
316 
317  bindex, windex = return_out_index(the_process)
318 
319  redefine_twidth=False #not needed to redefine top width for MadSpin part
320  to_replace = find_W_prepare_DRXhack(mfile,bindex,windex,redefine_twidth,DRmode)
321 
322  if os.path.getsize("mytmp.txt")>0: #if there are hacks to make
323  if DRmode==1:
324  do_DR1_hacks(mfile,"mytmp.txt")
325  elif DRmode==2:
326  find_jamp(mfile,mfile+".jamp1","JAMP(1)","JAMP(2)")
327  find_jamp(mfile,mfile+".jamp2","JAMP(2)","MATRIX")
328  do_DR2_hack(mfile,"mytmp.txt","_PROD",to_replace,0) #do not put top propagator on shell
329 
330  prefix = mfile.replace("/matrix_prod.f","")
331  prefix_full = prefix.replace("production_me","full_me")
332 
333  for f_file in full_files:
334  if prefix_full in fdir+f_file:
335  full_file_matrix = fdir+f_file+"/matrix.f"
336  full_file_matrix_prod = fdir+f_file+"/matrix_prod.f"
337  if DRmode==1:
338  do_DR1_hacks(full_file_matrix, "mytmp.txt")
339  do_DR1_hacks(full_file_matrix_prod, "mytmp.txt")
340  elif DRmode==2:
341  find_jamp(full_file_matrix,full_file_matrix+".jamp1","JAMP(1)","JAMP(2)")
342  find_jamp(full_file_matrix,full_file_matrix+".jamp2","JAMP(2)","MATRIX")
343  find_jamp(full_file_matrix_prod,full_file_matrix_prod+".jamp1","JAMP(1)","JAMP(2)")
344  find_jamp(full_file_matrix_prod,full_file_matrix_prod+".jamp2","JAMP(2)","MATRIX")
345 
346  do_DR2_hack(full_file_matrix, "mytmp.txt","",to_replace,0) #do not put top propagator on shell
347  do_DR2_hack(full_file_matrix_prod, "mytmp.txt","_PROD",to_replace,0) #do not put top propagator on shell
348  do_driver_hacks(fdir+f_file+"/driver.f")
349 
350  drlog.info("finished do_MadSpin_DRX")
351  sys.stdout.flush()
python.DiagramRemoval.find_W_prepare_DRXhack
def find_W_prepare_DRXhack(mfile, bindex, windex, redefine_twidth, which_DR)
Definition: DiagramRemoval.py:46
python.DiagramRemoval.write_jamp_res
def write_jamp_res(my_jamp_line, tmp_c)
Definition: DiagramRemoval.py:231
python.DiagramRemoval.do_driver_hacks
def do_driver_hacks(driver_filename)
Definition: DiagramRemoval.py:102
python.DiagramRemoval.do_DR1_hacks
def do_DR1_hacks(mfile, tmpfile)
Definition: DiagramRemoval.py:86
search
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
Definition: hcg.cxx:738
python.DiagramRemoval.do_DRX
def do_DRX(DRmode, process_dir)
Perform DR for matrix element #.
Definition: DiagramRemoval.py:262
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
python.DiagramRemoval.do_MadSpin_DRX
def do_MadSpin_DRX(DRmode, msdirname)
Perform Diagram Removal for MadSpin #.
Definition: DiagramRemoval.py:302
python.DiagramRemoval.get_process
def get_process(infile, test_string='Process:')
Definition: DiagramRemoval.py:19
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.DiagramRemoval.do_fks_hacks
def do_fks_hacks(pdir)
Definition: DiagramRemoval.py:120
python.DiagramRemoval.find_jamp
def find_jamp(mfile, helperfile, test_string, end_string)
Definition: DiagramRemoval.py:170
python.DiagramRemoval.do_DR2_hack
def do_DR2_hack(mfile, tmpfile, suffix, to_replace, should_replace)
Definition: DiagramRemoval.py:193
python.DiagramRemoval.return_out_index
def return_out_index(process)
Definition: DiagramRemoval.py:28
Trk::open
@ open
Definition: BinningType.h:40
CaloLCW_tf.group
group
Definition: CaloLCW_tf.py:28
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
python.DiagramRemoval.find_matrix_files
def find_matrix_files(process_dir)
Definition: DiagramRemoval.py:15
str
Definition: BTagTrackIpAccessor.cxx:11
python.DiagramRemoval.do_coupl_hacks
def do_coupl_hacks(pdir)
Definition: DiagramRemoval.py:145
Trk::split
@ split
Definition: LayerMaterialProperties.h:38