38def reweighter(process, weight_groups, powheg_LHE_output):
39 """! Add a series of additional weights to an LHE file.
41 @param process PowhegBox process.
42 @param weight_groups OrderedDict containing groups of weights to add.
43 @param powheg_LHE_output Name of LHE file produced by PowhegBox.
45 logger.info(
"Starting to run PowhegControl PDF and QCD scale reweighter")
50 non_weight_attributes = [
"parameter_names",
"combination_method",
"keywords"]
53 xml_kwds = {
"renscfact":
"renscfact",
"facscfact":
"facscfact",
"lhans1":
"lhapdf",
"lhans2":
"lhapdf",
"width_correction" :
"width_correction",
"run_mode":
"run_mode"}
56 _idx_scale_start, _idx_PDF_start, _idx_other_start = 1001, 2001, 3001
58 if not process.use_XML_reweighting:
59 logger.warning(
"... XML-style reweighting is not enabled for this process. Will use old (multiple-pass) method.")
62 for group_name, weight_group
in weight_groups.items():
63 logger.info(
"Preparing weight group: {:<19} with {} weights".format(group_name, len(weight_group) - len(non_weight_attributes)))
66 is_parallel_xml_compatible = process.use_XML_reweighting
and all([k
in xml_kwds.keys()
for _kw_set
in weight_group[
"keywords"]
for k
in _kw_set])
67 if is_parallel_xml_compatible:
68 _keywords = [list(
set([xml_kwds[k]
for k
in _kw_set]))
for _kw_set
in weight_group[
"keywords"]]
70 if process.use_XML_reweighting:
71 logger.warning(
"... this weight group is incompatible with XML-style reweighting. Will use old (multiple-pass) method.")
72 _keywords = weight_group[
"keywords"]
73 keyword_dict = dict((n, k)
for n, k
in zip(weight_group[
"parameter_names"], _keywords))
76 tuple_kwargs = {
"keywords": keyword_dict,
"combine": weight_group[
"combination_method"],
"group": group_name,
"parallel_xml_compatible": is_parallel_xml_compatible}
80 weight_list.append(
WeightTuple(parameter_settings=weight_group[
"nominal"], ID=0, name=
"nominal", **tuple_kwargs))
83 elif group_name ==
"scale_variation":
84 for idx, name
in enumerate([k
for k
in weight_group.keys()
if k
not in non_weight_attributes], start=_idx_scale_start):
85 weight_list.append(
WeightTuple(parameter_settings=weight_group[name], ID=idx, name=name, **tuple_kwargs))
86 _idx_scale_start = idx + 1
89 elif group_name ==
"PDF_variation":
90 for idx, name
in enumerate([k
for k
in weight_group.keys()
if k
not in non_weight_attributes], start=_idx_PDF_start):
91 weight_list.append(
WeightTuple(parameter_settings=weight_group[name], ID=idx, name=name, **tuple_kwargs))
92 _idx_PDF_start = idx + 1
96 for idx, name
in enumerate([k
for k
in weight_group.keys()
if k
not in non_weight_attributes], start=_idx_other_start):
97 weight_list.append(
WeightTuple(parameter_settings=weight_group[name], ID=idx, name=name, **tuple_kwargs))
98 _idx_other_start = idx + 1
101 if os.path.isfile(
"pwgcounters.dat"):
102 shutil.copy(
"pwgcounters.dat",
"pwgcounters.dat.bak")
106 shutil.copy(
"powheg.input",
"powheg.input.before_reweighting")
108 raise IOError(
"Powheg input card ('powheg.input') cannot be found at the start of reweighting. In a normal setup, PowhegControl generates this input card. Its absence is probably a sign of problems --- please investigate or contact the PowhegControl experts.")
112 shutil.copy(powheg_LHE_output,
"{}.before_reweighting".format(powheg_LHE_output))
114 raise IOError(
"Nominal LHE file could not be found. Probably POWHEG-BOX crashed during event generation.")
117 if process.use_XML_reweighting:
120 if process.has_parameter(
"run_mode")
and process.parameters_by_keyword(
"run_mode")[0].value != 1
and hasattr(process,
"reweight_for_MiNNLO")
and process.reweight_for_MiNNLO:
121 weight_list = [
WeightTuple(ID=0, name=
"nominal", group=
"nominal", parallel_xml_compatible=
True, parameter_settings=[(
"run_mode",1)], keywords={
"run_mode":[
"run_mode"]}, combine=
None)] + weight_list
123 weight_list = [
WeightTuple(ID=0, name=
"nominal", group=
"nominal", parallel_xml_compatible=
True, parameter_settings=[], keywords=
None, combine=
None)] + weight_list
125 FileParser(
"powheg.input").text_replace(
"pdfreweight .*",
"pdfreweight 0")
127 xml_lines, serial_xml_weight_list, current_weightgroup = [], [],
None
128 for weight
in weight_list:
130 if weight.parallel_xml_compatible
and weight.group != current_weightgroup:
131 xml_lines.append(
"</weightgroup>")
132 current_weightgroup = weight.group
133 xml_lines.append(
"<weightgroup name='{}' combine='{}'>".format(weight.group, weight.combine))
135 if weight.parallel_xml_compatible:
136 keyword_pairs_str =
" ".join([
"{}={}".format(k, v)
for p, v
in weight.parameter_settings
for k
in weight.keywords[p]])
137 xml_lines.append(
"<weight id='{}'> {} </weight>".format(weight.ID, keyword_pairs_str))
139 serial_xml_weight_list.append(weight)
140 xml_lines.append(xml_lines.pop(0))
141 n_parallel_xml_weights = len(weight_list) - len(serial_xml_weight_list)
144 if n_parallel_xml_weights > 0:
146 with open(
"reweighting_input.xml",
"w")
as f_rwgt:
147 f_rwgt.write(
"<initrwgt>\n")
148 [f_rwgt.write(
"{}\n".format(xml_line))
for xml_line
in xml_lines]
149 f_rwgt.write(
"</initrwgt>")
154 FileParser(
"powheg.input").text_replace(
"rwl_file .*",
"rwl_file 'reweighting_input.xml'")
155 FileParser(
"powheg.input").text_replace(
"rwl_add .*",
"rwl_add 1")
156 FileParser(
"powheg.input").text_replace(
"clobberlhe .*",
"clobberlhe 1")
157 if process.has_parameter(
"run_mode")
and process.parameters_by_keyword(
"run_mode")[0].value != 1
and hasattr(process,
"reweight_for_MiNNLO")
and process.reweight_for_MiNNLO:
158 FileParser(
"powheg.input").text_replace(
"run_mode .*",
"run_mode 1")
160 logger.info(
"Preparing simultaneous calculation of {} additional weights for generated events.".format(n_parallel_xml_weights))
163 if list(process.parameters_by_name(
"manyseeds"))[0].value == 1:
164 if process.powheg_version ==
"RES":
165 os.system(
'cp reweighting_input.xml backup_of_reweighting_input.xml')
166 os.system(
'cp powheg.input powheg.input.for_reweighting')
167 multicore_untimed(process)
169 FileParser(
"powheg.input").text_replace(
"manyseeds .*",
"manyseeds 0")
170 FileParser(
"powheg.input").text_replace(
"parallelstage .*",
"parallelstage -1")
171 os.system(
'cp reweighting_input.xml backup_of_reweighting_input.xml')
172 os.system(
'cp powheg.input powheg.input.for_reweighting')
173 singlecore_untimed(process)
175 os.system(
'cp reweighting_input.xml backup_of_reweighting_input.xml')
176 os.system(
'cp powheg.input powheg.input.for_reweighting')
177 singlecore_untimed(process)
183 if len(serial_xml_weight_list) > 0:
184 logger.info(
"Preparing individual calculation of {} additional weights for generated events.".format(len(serial_xml_weight_list)))
185 shutil.move(
"reweighting_input.xml",
"reweighting_input.nominal")
186 for idx_weight, weight
in enumerate(serial_xml_weight_list, start=1):
187 add_single_weight(process, weight, idx_weight, len(serial_xml_weight_list), use_XML=
True)
189 shutil.move(
"reweighting_input.nominal",
"reweighting_input.xml")
194 logger.info(
"Preparing individual calculation of {} additional weights for generated events.".format(len(weight_list)))
195 for idx_weight, weight
in enumerate(weight_list, start=1):
199 if process.use_XML_reweighting:
200 comment_patterns = [
"#pdf",
"#rwgt",
"#new weight",
"#matching",
" #Random" ]
201 if process.remove_oldStyle_rwt_comments:
203 logger.info(
"Removing comment lines from lhe file - these lines can be added back using the 'remove_oldStyle_rwt_comments=False' argument in generate()")
205 for pattern
in comment_patterns:
206 removed =
FileParser(powheg_LHE_output).text_remove(
"^"+pattern)
207 logger.info(
"{} line(s) starting with '{}' were removed from {}".format(removed, pattern, powheg_LHE_output))
209 logger.info(
"Fixing comment lines from lhe file - these lines can be simply removed using the 'remove_oldStyle_rwt_comments=True' argument in generate()")
210 for pattern
in comment_patterns:
215 for weight
in weight_list:
216 replacelist += [[
".* id='{}' .*".format(weight.ID),
"<weight id='{weight_id}'>{weight_name}</weight>".format(weight_id=weight.ID, weight_name=weight.name), 1]]
219 replacelist += [[
'LesHouchesEvents version="1.0"',
'LesHouchesEvents version="3.0"', 1]]
220 FileParser(powheg_LHE_output).text_replace_multi(replacelist)
223 shutil.move(
"powheg_nominal.input",
"powheg.input")
224 if os.path.isfile(
"pwgcounters.dat.bak"):
225 shutil.move(
"pwgcounters.dat.bak",
"pwgcounters.dat")
305 if not os.path.isfile(
"{}.before_reweighting".format(lheFile)):
306 logger.error(
"Impossible to find file {}.before_reweighting".format(lheFile))
310 shutil.move(lheFile,
"{}.text_replace_backup".format(lheFile))
314 with open(
"{}.text_replace_backup".format(lheFile),
"rb")
as f_input:
315 line_in = f_input.readline()
317 if re.search(
"^"+pattern.lstrip(), line_in.decode().lstrip()):
319 elif re.search(
"^</event>", line_in.decode().lstrip()):
321 line_in = f_input.readline()
323 n_found_noWeights = 0
324 n_events_noWeights = 0
325 with open(
"{}.before_reweighting".format(lheFile),
"rb")
as f_input:
326 line_in = f_input.readline()
328 if re.search(
"^"+pattern.lstrip(), line_in.decode().lstrip()):
329 n_found_noWeights += 1
330 elif re.search(
"^</event>", line_in.decode().lstrip()):
331 n_events_noWeights += 1
332 line_in = f_input.readline()
335 impossible_to_fix =
False
340 with open(lheFile,
"w")
as f_output:
342 if n_found == n_found_noWeights:
344 with open(
"{}.text_replace_backup".format(lheFile),
"rb")
as f_input, open(
"{}.before_reweighting".format(lheFile),
"rb")
as f_input_noWeights:
345 line_in = f_input.readline()
346 line_in_noWeights = f_input_noWeights.readline()
348 if re.search(
"^"+pattern.lstrip(), line_in.decode().lstrip()):
350 while line_in_noWeights:
351 if re.search(
"^"+pattern, line_in_noWeights.decode().lstrip()):
352 if (line_in.decode().rstrip().lstrip() != line_in_noWeights.decode().rstrip().lstrip()):
353 f_output.write(line_in_noWeights.decode())
356 f_output.write(line_in.decode())
357 line_in_noWeights = f_input_noWeights.readline()
361 line_in_noWeights = f_input_noWeights.readline()
363 line_in = f_input.readline()
365 impossible_to_fix =
True
367 if impossible_to_fix:
370 f_output.write(line_in.decode())
371 line_in = f_input.readline()
374 while line_in_noWeights:
375 if re.search(
"^"+pattern, line_in_noWeights.decode()):
376 impossible_to_fix =
True
378 if impossible_to_fix:
380 line_in_noWeights = f_input_noWeights.readline()
382 elif n_found == 0
and n_found_noWeights == n_events_noWeights
and n_events == n_events_noWeights:
384 with open(
"{}.text_replace_backup".format(lheFile),
"rb")
as f_input, open(
"{}.before_reweighting".format(lheFile),
"rb")
as f_input_noWeights:
385 line_in = f_input.readline()
386 line_in_noWeights = f_input_noWeights.readline()
387 while line_in_noWeights:
388 if re.search(
"^"+pattern, line_in_noWeights.decode().lstrip()):
390 if re.search(
"^</event>", line_in.decode().lstrip()):
391 f_output.write(line_in_noWeights.decode())
392 f_output.write(line_in.decode())
394 line_in = f_input.readline()
397 f_output.write(line_in.decode())
398 line_in = f_input.readline()
399 line_in_noWeights = f_input_noWeights.readline()
401 f_output.write(line_in.decode())
402 line_in = f_input.readline()
405 if n_found == 0
and n_found_noWeights == 0:
406 shutil.move(
"{}.text_replace_backup".format(lheFile), lheFile)
407 logger.info(
"No line with pattern '{}' was found in lhe file before or after reweighting, so need to fix it".format(pattern))
408 elif impossible_to_fix:
409 shutil.move(
"{}.text_replace_backup".format(lheFile), lheFile)
410 logger.info(
"Impossible to fix the possibly buggy comment lines with pattern {} in {} using the corresponding lines from {}.before_reweighting".format(pattern, lheFile, lheFile))
411 logger.info(
"Keeping those lines as they are in '{}".format(lheFile))
413 os.remove(
"{}.text_replace_backup".format(lheFile))
415 logger.info(
"{} line(s) starting with '{}' replaced in {} using the corresponding line(s) from {}.before_reweighting".format(n_replaced, pattern, lheFile, lheFile))
416 elif n_found != 0
and n_replaced == 0:
417 logger.info(
"No line starting with '{}' was replaced in {} ({} were found) since none seems buggy".format(pattern, lheFile, n_found))
418 elif n_added_back !=0:
419 logger.info(
"{} line(s) starting with '{}' added back in {} using the corresponding line(s) from {}.before_reweighting".format(n_added_back, pattern, lheFile, lheFile))
add_single_weight(process, weight, idx_weight, n_total, use_XML)
Add a single additional weight to an LHE file.