ATLAS Offline Software
lhe_nominal_weight_updater.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2 
3 from AthenaCommon import Logging
4 from ...decorators import timed
5 from ...utility import LHE
6 from xml.etree import ElementTree
7 import shutil
8 
9 
10 logger = Logging.logging.getLogger("PowhegControl")
11 
12 @timed("LHE file updating nominal weight")
13 def lhe_nominal_weight_updater(powheg_LHE_output):
14  """Post-process LHE file to update the nominal weight.
15  In some cases (namely when for_reweighting == 1), virtual corrections
16  are added only in the reweighting stage. In this case, the nominal weight
17  in the <event> block, i.e. in the XWGTUP field, is unfortunately not updated.
18  This can be a problem later on because Pythia8 uses this weight as nominal,
19  while the 0th weight in the <rwgt> block is the 'correct' nominal, i.e.
20  which includes these virtual corrections.
21  This post-processor will replace the value in the XWGTUP field
22  by this 0th weight. In addition, the original XWGTUP value is saved as an additional
23  weight in the <rwgt> block, in a weight with name 'XWGTUP_original',
24  with an id equal to 9001 and in a group or weights
25  called 'supplemental'.
26 
27  #@param powheg_LHE_output Name of LHE file produced by PowhegBox.
28 
29  @author Timothee Theveneaux-Pelzer <tpelzer@cern.ch>
30  #"""
31 
32  logger.info("Updating XWGTUP value in lhe file with weight of index 0")
33 
34  wgtid_for_old_XWGTUP_value = 9001 # if not set to None, the old value of XWGTUP will be saved
35  weightgroup_name_for_old_XWGTUP_value = "supplemental"
36  weight_name_for_old_XWGTUP_value = "XWGTUP_original"
37 
38  # Get opening and closing strings
39  preamble = LHE.preamble(powheg_LHE_output)
40  if (wgtid_for_old_XWGTUP_value is not None and
41  weightgroup_name_for_old_XWGTUP_value is not None and
42  weight_name_for_old_XWGTUP_value is not None):
43  # first modify the header, to add the additional weight
44  header_old_str = LHE.header_block(powheg_LHE_output)
45  header_new = LHE.add_weight_to_header(header_old_str, weightgroup_name_for_old_XWGTUP_value, weight_name_for_old_XWGTUP_value, wgtid_for_old_XWGTUP_value)
46  header_new_str_bytestr = ElementTree.tostring(header_new)
47  header_new_str = header_new_str_bytestr.decode('utf-8').replace("\"", "\'").strip() + "\n"
48  # some complicated loop to restore order of original lines
49  header_lines = []
50  for l in header_new_str.splitlines():
51  if l.find("<weightgroup") >= 0:
52  ll = l.strip(">").split()
53  combine = ""
54  name = ""
55  for word in ll:
56  if word.find("combine") >= 0:
57  combine = word.split("combine='")[1].split("'")[0]
58  elif word.find("name") >= 0:
59  name = word.split("name='")[1].split("'")[0]
60  l_formated = "<weightgroup name='%s' combine='%s' >"%(name, combine)
61  header_lines.append(l_formated)
62  else:
63  header_lines.append(l)
64  header_new_str = "\n".join(header_lines)+"\n"
65  # then loop on the preamble lines and write the new preamble
66  preamble_new = ""
67  inHeader = False
68  for input_line in preamble.splitlines():
69  if inHeader: # in header
70  if input_line.find("</header>") >=0:
71  preamble_new += header_new_str # write the new header
72  inHeader = False # next line is out of header
73  else:
74  continue # nothing to do if outside the header
75  else: # not in header
76  if input_line.find("<header>") >=0:
77  inHeader = True # header starts
78  else:
79  preamble_new += input_line + "\n" # not in header, writing the line unmodified
80  preamble = preamble_new # update preamble
81  postamble = LHE.postamble(powheg_LHE_output) # postamble is unmodified
82 
83  powheg_LHE_updated = "{}.updated".format(powheg_LHE_output)
84  with open(powheg_LHE_updated, "w") as f_output:
85  f_output.write("{}".format(preamble))
86  for input_event in LHE.event_iterator(powheg_LHE_output):
87  output_event = LHE.update_XWGTUP_with_reweighted_nominal(input_event, wgtid_for_old_XWGTUP_value)
88  f_output.write(output_event)
89  f_output.write(postamble)
90 
91  # Make a backup of the original events
92  shutil.move(powheg_LHE_output, "{}.lhe_nominal_weight_updater_backup".format(powheg_LHE_output))
93  shutil.move(powheg_LHE_updated, powheg_LHE_output)
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
python.decorators.timed.timed
def timed(name)
Decorator to output function execution time.
Definition: timed.py:12
vtune_athena.format
format
Definition: vtune_athena.py:14
python.algorithms.postprocessors.lhe_nominal_weight_updater.lhe_nominal_weight_updater
def lhe_nominal_weight_updater(powheg_LHE_output)
Definition: lhe_nominal_weight_updater.py:13
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
Trk::open
@ open
Definition: BinningType.h:40
Trk::split
@ split
Definition: LayerMaterialProperties.h:38