ATLAS Offline Software
powheg_base.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
3 from AthenaCommon import Logging
4 from .configurable import Configurable
5 from ..utility import check_svn_revision, FileParser
6 import math
7 import os
8 import glob
9 
10 
11 logger = Logging.logging.getLogger("PowhegControl")
12 
13 
15  """! Base class for PowhegBox processes.
16 
17  All process types inherit from this class.
18 
19  @author James Robinson <james.robinson@cern.ch>
20  @author Stefan Richter <stefan.richter@cern.ch>
21  """
22 
23  def hoppet_info(self):
24  '''
25  Returns a list of strings to be treated as info messages in the log
26  They otherwise throw an error with HOPPET v. 1.2.0
27  Cf. AGENE-2016
28  '''
29  return ["-----------------------------------------------------------",
30  "Welcome to HOPPET v. 1.2.0",
31  "Higher Order Perturbative Parton Evolution Toolkit",
32  "Written by Gavin P. Salam (2001-2012)",
33  "with contributions from Juan Rojo",
34  "Frederic Dreyer and Alexander Karlberg",
35  "It is made available under the GNU public license,",
36  "with the additional request that if you use it or any",
37  "derivative of it in scientific work then you should cite:",
38  "G.P. Salam & J. Rojo, CPC 180(2009)120 (arXiv:0804.3755).",
39  "You are also encouraged to cite the original references,",
40  "for LO, NLO and NNLO splitting functions, the QCD",
41  "1, 2 and 3 loop beta functions and the coupling and",
42  "PDF and coupling mass threshold matching functions."]
43 
44  def hoppet_warning(self):
45  '''
46  Returns a list of strings to be treated as warning messages in the log
47  They otherwise throw an error
48  '''
49  return ["WARNING in InitMTMNNLO: using parametrisation (less accuracte) for A2PShg"]
50 
51  def openloops_error(self):
52  '''
53  Returns a list of strings to be treated as error messages in the log
54  They otherwise do not throw an error
55  '''
56  return ["[POWHEG-BOX+OpenLoops] Process not found!"]
57 
58  def __init__(self, base_directory, version, executable_name, cores, powheg_executable="pwhg_main", is_reweightable=True, warning_output = [], info_output = [], error_output = [], **kwargs):
59  """! Constructor.
60 
61  @param base_directory path to PowhegBox code.
62  @param version PowhegBox version.
63  @param executable_name folder containing appropriate PowhegBox executable.
64  @param powheg_executable name of the powheg executable.
65  @param warning_output list of patterns which if found in the output will be treated as warning in the log.
66  @param error_output list of patterns which if found in the output will be treated as error in the log.
67  @param info_output list of patterns which if found in the output will be treated as info in the log.
68  """
69  super(PowhegBase, self).__init__()
70 
71 
72  self.executable = os.path.join(base_directory, version, executable_name, powheg_executable)
73  # Check if the file exists, if not, prepend "bin" to the path
74  if not os.path.exists(self.executable):
75  self.executable = os.path.join(base_directory, version, executable_name, "bin", powheg_executable)
76  if os.path.exists(self.executable):
77  logger.info('Executable exists = {0}'.format(self.executable))
78  else:
79  logger.info('Executable does not exist = {0}'.format(self.executable))
80 
81 
82  os.environ["PYTHONPATH"] = os.path.join(base_directory, version, executable_name, "python") + ":" + os.environ.get("PYTHONPATH", "")
83 
84 
85  os.environ["LD_LIBRARY_PATH"] = os.path.join(base_directory, version, executable_name, "amplitudes", "obj-gnu") + ":" + os.environ.get("LD_LIBRARY_PATH", "")
86  os.environ["LD_LIBRARY_PATH"] = os.path.join(base_directory, version, executable_name, "QCDLoop-1.95", "ff", "obj-gnu") + ":" + os.environ.get("LD_LIBRARY_PATH", "")
87  os.environ["LD_LIBRARY_PATH"] = os.path.join(base_directory, version, executable_name, "Virtuals", "obj-gnu") + ":" + os.environ.get("LD_LIBRARY_PATH", "")
88  os.environ["LD_LIBRARY_PATH"] = os.path.join(base_directory, version, executable_name, "obj-gfortran") + ":" + os.environ.get("LD_LIBRARY_PATH", "")
89  os.environ["LD_LIBRARY_PATH"] = os.path.join(base_directory, version, executable_name, "obj-gfortran", "proclib") + ":" + os.environ.get("LD_LIBRARY_PATH", "")
90  os.environ["LD_LIBRARY_PATH"] = os.path.join(base_directory, version, executable_name, "obj-gnu") + ":" + os.environ.get("LD_LIBRARY_PATH", "")
91  os.environ["LD_LIBRARY_PATH"] = os.path.join(base_directory, version, executable_name, "obj-gnu", "proclib") + ":" + os.environ.get("LD_LIBRARY_PATH", "")
92 
93 
94 
95  directories = ['obj-gfortran', 'OpenLoops2', 'obj-gnu']
96  logger.info("OpenLoopsPath (before) = {0}".format(os.getenv('OpenLoopsPath')))
97  for directory in directories:
98  if os.path.isdir(os.path.join(base_directory, version, executable_name, directory, 'proclib')):
99  OLPath = os.path.join(base_directory, version, executable_name, directory)
100  os.environ['OpenLoopsPath'] = OLPath
101  logger.info("OpenLoopsPath (after) = {0}".format(os.getenv('OpenLoopsPath')))
102  break
103 
104 
105  self.process_revision = check_svn_revision(os.path.dirname(self.executable))
106 
107 
109  one_character_version = self.powheg_version.replace('V', '')[0]
110  POWHEGVER = '{v}_r{rev}'.format(v=one_character_version, rev=self.process_revision)
111  logger.info('MetaData: POWHEGVER = {0}'.format(POWHEGVER))
112  os.environ["POWHEGVER"] = POWHEGVER # does not export to parent shell, but might be sufficient inside job?
113 
114 
115  self.powhegbox_revision = check_svn_revision(os.path.dirname(os.path.dirname(self.executable)))
116 
117 
118  self.cores = cores
119 
120 
121  self.algorithms = []
122 
123 
124  self.externals = {}
125 
126 
128 
129  # Universal keywords that are set from the run arguments
130  self.add_keyword("ebeam1", kwargs.get("beam_energy", None))
131  self.add_keyword("ebeam2", kwargs.get("beam_energy", None))
132  self.add_keyword("iseed", int(kwargs.get("random_seed", None)))
133  self.add_keyword("numevts", kwargs.get("nEvents", None))
134 
135  # Add parameter validation functions
136  self.validation_functions.append("validate_integration_parameters")
137 
138 
139  self.is_reweightable = is_reweightable
140 
141 
143 
144 
146 
147 
148  self.warning_output = warning_output
149  self.info_output = info_output
150  self.error_output = error_output
151 
152 
155 
156  def add_algorithm(self, alg_or_process):
157  """! Add an algorithm or external process to the sequence.
158 
159  @param process Algorithm or external process to add.
160  """
161  # Either add to the list of algorithms to schedule
162  if isinstance(alg_or_process, str):
163  self.algorithms.append(alg_or_process)
164  # ... or add as an external process
165  else:
166  self.externals[alg_or_process.name] = alg_or_process
167 
168  @property
169  def files_for_cleanup(self):
170  """! Wildcarded list of files created by this process that can be deleted."""
171  raise AttributeError("Names of unneeded files are not known for this process!")
172 
173  @property
175  """! Wildcarded list of integration files that might be created by this process."""
176  raise AttributeError("Integration file names are not known for this process!")
177 
178  @property
180  """! Wildcarded list of integration files that are needed for this process."""
181  raise AttributeError("Integration file names are not known for this process!")
182 
183  @property
184  def powheg_version(self):
185  """! Version of PowhegBox process."""
186  raise AttributeError("Powheg version is not known!")
187 
188  @property
189  def default_PDFs(self):
190  """! Default PDFs for this process."""
191  raise AttributeError("Default PDFs are not known for this process!")
192 
193  @property
194  def default_scales(self):
195  """! Default scale variations for this process."""
196  raise AttributeError("Default scales are not known for this process!")
197 
198  def prepare_to_parallelise(self, n_cores):
199  """! Scale calculation parameters by n_cores."""
200  __nEvents_unscaled = self.parameters_by_keyword("numevts")[0].value
201  for keyword in ["ncall1", "ncall1rm", "ncall2", "ncall2rm", "nubound", "numevts"]:
202  for parameter in self.parameters_by_keyword(keyword):
203  if int(parameter.value) > 0:
204  parameter.value = int(math.ceil(float(parameter.value) / n_cores))
205  __nEvents_scaled = self.parameters_by_keyword("numevts")[0].value
206  logger.info("Scaling number of events per job from {} down to {}".format(__nEvents_unscaled, __nEvents_scaled))
207  # Freeze parallelstage parameters before printing list for user
208  [parameter.freeze() for parameter in self.parameters_by_name("parallelstage")]
209 
210  def stage_is_completed(self, stage):
211  """! Set whether the specified POWHEG-BOX generation stage is complete."""
212  # Perform manual check to allow re-use of grids in multicore mode
213  return False
214 
216  """! Validate any parameters which need it before preparing runcard."""
217  for function_name in self.validation_functions:
218  getattr(self, function_name)()
219 
221  """! Validate integration keywords by forcing to integer values."""
222  self.expose() # convenience call to simplify syntax
223  for name in ("foldcsi", "foldphi", "foldy", "itmx1", "itmx2", "ncall1", "ncall2", "nEvents"):
224  for parameter in self.parameters_by_name(name):
225  try:
226  parameter.value = int(parameter.value)
227  except TypeError:
228  logger.fatal("Failed to validate {} with value {}".format(name, parameter.value))
229  raise
230 
231  def check_decay_mode(self, decay_mode, allowed_decay_modes=None):
232  """! Check whether a decay mode is allowed an raise an exception if it is not."""
233  if allowed_decay_modes is None:
234  allowed_decay_modes = self.allowed_decay_modes
235  if decay_mode not in allowed_decay_modes:
236  logger.warning("Decay mode {} not recognised!".format(decay_mode))
237  logger.info("Allowed decay modes are:")
238  for allowed_decay_mode in allowed_decay_modes:
239  logger.info("... {}".format(allowed_decay_mode))
240  raise ValueError("Decay mode {} not recognised!".format(decay_mode))
241 
243 
244  search_strings = [] # list of filename patters to be searched for
245  found_files = [] # list of found files will be printed out for info
246  missing_patterns = [] # list of filename patters which hasn't been found but would be needed for pre-made integration grids
247  try:
248  search_strings = self.mandatory_integration_file_names
249  except AttributeError:
250  logger.fatal("No integration grid file name patterns defined for this process.")
251  raise
252  for s in search_strings:
253  found = glob.glob(s)
254  if found != []:
255  found_files += found
256  else:
257  missing_patterns.append(s)
258  if missing_patterns == []:
259  logger.info("Integration grid files found locally. Event generation shall continue, skipping the integration step.")
260  logger.info("Integration grid files found locally: {}".format(found_files))
261  else:
262  logger.info("Integration grid files needed were not found locally. Event generation shall continue, starting by the integration step.")
263  logger.info("Missing integration grid files with these patterns: {}".format(missing_patterns))
264  logger.info("Integration grid files found locally (if any): {}".format(found_files))
265 
266 
267  def modify_parameter(self, stage = 0):
268 
269  #skip modifying if dict is empty
270  if not bool(self.parameterStageDict):
271  return
272 
273  logger.info("Modifying parameters for the stages : {0}".format(self.parameterStageDict))
274 
275 
276  for key in self.parameterStageDict:
277  settingsList = self.parameterStageDict[key]
278  if abs(settingsList[2] - stage) <=1e-09:
279  self.set_parameter_in_config(key,settingsList[1])
280  else:
281  self.set_parameter_in_config(key,settingsList[0])
282 
283  def set_parameter_in_config(self, key, value):
284  FileParser("powheg.input").text_replace(key+".*", key+" {}".format(value))
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
python.processes.configurable.Configurable.expose
def expose(self)
Add all names to the interface of this object.
Definition: configurable.py:46
python.processes.powheg_base.PowhegBase.hoppet_info
def hoppet_info(self)
Definition: powheg_base.py:23
python.processes.powheg_base.PowhegBase.validate_parameters
def validate_parameters(self)
Validate any parameters which need it before preparing runcard.
Definition: powheg_base.py:215
python.utility.revision_checking.check_svn_revision
def check_svn_revision(path)
Definition: revision_checking.py:6
python.processes.powheg_base.PowhegBase.warning_output
warning_output
Special treatment for some log messages.
Definition: powheg_base.py:148
python.processes.powheg_base.PowhegBase.add_algorithm
def add_algorithm(self, alg_or_process)
Add an algorithm or external process to the sequence.
Definition: powheg_base.py:156
python.processes.powheg_base.PowhegBase.hoppet_warning
def hoppet_warning(self)
Definition: powheg_base.py:44
python.processes.powheg_base.PowhegBase
Base class for PowhegBox processes.
Definition: powheg_base.py:14
vtune_athena.format
format
Definition: vtune_athena.py:14
python.processes.configurable.Configurable.parameters_by_name
def parameters_by_name(self, name)
Retrieve all parameters that use a given name.
Definition: configurable.py:64
python.processes.powheg_base.PowhegBase.error_output
error_output
Definition: powheg_base.py:150
python.processes.powheg_base.PowhegBase.default_scales
def default_scales(self)
Default scale variations for this process.
Definition: powheg_base.py:194
python.processes.powheg_base.PowhegBase.check_using_integration_files
def check_using_integration_files(self)
Definition: powheg_base.py:242
python.processes.configurable.Configurable.add_keyword
def add_keyword(self, keyword, value=None, name=None, frozen=None, hidden=None, description=None, **kwargs)
Register configurable parameter that is exposed to the user.
Definition: configurable.py:21
python.processes.powheg_base.PowhegBase.integration_file_names
def integration_file_names(self)
Wildcarded list of integration files that might be created by this process.
Definition: powheg_base.py:174
python.processes.powheg_base.PowhegBase.parameterStageDict
parameterStageDict
Dictionary used to change parameters of the Powheg input.
Definition: powheg_base.py:154
python.processes.powheg_base.PowhegBase.use_XML_reweighting
use_XML_reweighting
Switch to determine whether XML reweighting should be used.
Definition: powheg_base.py:142
python.processes.powheg_base.PowhegBase.prepare_to_parallelise
def prepare_to_parallelise(self, n_cores)
Scale calculation parameters by n_cores.
Definition: powheg_base.py:198
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.processes.powheg_base.PowhegBase.openloops_error
def openloops_error(self)
Definition: powheg_base.py:51
python.processes.powheg_base.PowhegBase.set_parameter_in_config
def set_parameter_in_config(self, key, value)
Definition: powheg_base.py:283
python.processes.configurable.Configurable.parameters_by_keyword
def parameters_by_keyword(self, keyword)
Retrieve all parameters that use a given keyword.
Definition: configurable.py:57
python.processes.powheg_base.PowhegBase.powheg_version
def powheg_version(self)
Version of PowhegBox process.
Definition: powheg_base.py:184
python.processes.powheg_base.PowhegBase.process_revision
process_revision
Add to Python path "python" directory on POWHEG process directory.
Definition: powheg_base.py:105
python.processes.powheg_base.PowhegBase.__init__
def __init__(self, base_directory, version, executable_name, cores, powheg_executable="pwhg_main", is_reweightable=True, warning_output=[], info_output=[], error_output=[], **kwargs)
Constructor.
Definition: powheg_base.py:58
python.processes.powheg_base.PowhegBase.mandatory_integration_file_names
def mandatory_integration_file_names(self)
Wildcarded list of integration files that are needed for this process.
Definition: powheg_base.py:179
python.processes.powheg_base.PowhegBase.validation_functions
validation_functions
List of validation functions to run before preparing runcard.
Definition: powheg_base.py:127
python.processes.powheg_base.PowhegBase.check_decay_mode
def check_decay_mode(self, decay_mode, allowed_decay_modes=None)
Check whether a decay mode is allowed an raise an exception if it is not.
Definition: powheg_base.py:231
python.processes.powheg_base.PowhegBase.powhegbox_revision
powhegbox_revision
Log the PowhegBox version and process-code revision for AMI etc.
Definition: powheg_base.py:115
python.processes.powheg_base.PowhegBase.validate_integration_parameters
def validate_integration_parameters(self)
Validate integration keywords by forcing to integer values.
Definition: powheg_base.py:220
python.processes.powheg_base.PowhegBase.remove_oldStyle_rwt_comments
remove_oldStyle_rwt_comments
Switch to determine if the #rwgt and #pdf comments should be kept in lhe files despite using xml rewe...
Definition: powheg_base.py:145
python.processes.powheg_base.PowhegBase.info_output
info_output
Definition: powheg_base.py:149
python.processes.powheg_base.PowhegBase.algorithms
algorithms
List of additional algorithms to schedule.
Definition: powheg_base.py:121
python.processes.powheg_base.PowhegBase.is_reweightable
is_reweightable
Switch to determine whether reweighting is allowed.
Definition: powheg_base.py:139
python.processes.powheg_base.PowhegBase.externals
externals
List of external processes to schedule.
Definition: powheg_base.py:124
python.processes.powheg_base.PowhegBase.default_PDFs
def default_PDFs(self)
Default PDFs for this process.
Definition: powheg_base.py:189
python.processes.powheg_base.PowhegBase.cores
cores
Number of cores to use.
Definition: powheg_base.py:118
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.processes.powheg_base.PowhegBase.executable
executable
Powheg executable that will be used.
Definition: powheg_base.py:72
python.processes.powheg_base.PowhegBase.modify_parameter
def modify_parameter(self, stage=0)
Definition: powheg_base.py:267
python.processes.powheg_base.PowhegBase.files_for_cleanup
def files_for_cleanup(self)
Wildcarded list of files created by this process that can be deleted.
Definition: powheg_base.py:169
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
python.processes.powheg_base.PowhegBase.stage_is_completed
def stage_is_completed(self, stage)
Set whether the specified POWHEG-BOX generation stage is complete.
Definition: powheg_base.py:210
python.processes.configurable.Configurable
Class for any process which can be configured.
Definition: configurable.py:10
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65