CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Classes | Functions
mergeLHE Namespace Reference

Classes

class  BaseLHEMerger
 
class  DefaultLHEMerger
 
class  ExternalCppLHEMerger
 
class  MG5LOLHEMerger
 

Functions

def main
 

Function Documentation

def mergeLHE.main (   argv = None)
Main routine of the script.

Arguments:
- `argv`: arguments passed to the main routine

Definition at line 325 of file mergeLHE.py.

References submitPVResolutionJobs.count, and join().

326 def main(argv = None):
327  """Main routine of the script.
328 
329  Arguments:
330  - `argv`: arguments passed to the main routine
331  """
332 
333  if argv == None:
334  argv = sys.argv[1:]
335 
336  parser = argparse.ArgumentParser(
337  description=("A universal script that merges multiple LHE files for all possible conditions and in the most "
338  "natural way.\n"
339  "A detailed description of the merging step (in the default mode):\n"
340  " 1. Header:\n"
341  " a. assert consistency of the headers (allow difference for the info of e.g. #event, seed);\n"
342  " b. if not MG LO LHEs, will simply use the header from the first LHE; otherwise, reset the "
343  "<MGGenerationInfo> from the headers by merging the #event & xsec info;\n"
344  " 2. Init block: if all <init> blocks are the same, use the same as output; otherwise (the MG LO "
345  "case), merge them by recalculating the # of subprocess (LRPUP) and XSECUP, XERRUP, XMAXUP per "
346  "each subprocess.\n"
347  " 3. Event block: concatenate all event blocks. If for MG LO LHEs, recalculate the per-event "
348  "XWGTUP and all <wgt> tags based on the new XSECUP, #event, and 'event_norm' read from the MG "
349  "run card.\n"
350  "For further development of this script please always validate the merging result on the test "
351  "routines: https://github.com/colizz/mergelhe_validate\n"
352  "Example usage:\n"
353  " mergeLHE.py -i 'thread*/*.lhe,another_file/another.lhe' -o output.lhe"),
354  formatter_class=argparse.RawTextHelpFormatter)
355  parser.add_argument("-i", "--input-files", type=str,
356  help="Input LHE file paths separated by commas. Shell-type wildcards are supported.")
357  parser.add_argument("-o", "--output-file",
358  default='output.lhe', type=str,
359  help="Output LHE file path.")
360  parser.add_argument("--force-mglo-merger", action='store_true',
361  help=("Force to use the merger script dedicated for MG5 LO LHEs, as introduced in "
362  "https://github.com/cms-sw/genproductions/blob/master/bin/MadGraph5_aMCatNLO/Utilities/merge.pl"))
363  parser.add_argument("--force-cpp-merger", action='store_true',
364  help=("Force to use the external mergeLheFiles.cpp file to merge LHE files, as introduced in "
365  "https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideSubgroupMC#1_2_Using_pLHE_campaigns"))
366  parser.add_argument("-b", "--bypass-check", action='store_true',
367  help=("Bypass the compatibility check for the headers. If true, the header and init block "
368  "will be just a duplicate from the first input file, and events are concatenated without "
369  "modification."))
370  parser.add_argument("--debug", action='store_true',
371  help="Use the debug mode.")
372  args = parser.parse_args(argv)
373 
374  logging.basicConfig(
375  format='[%(levelname)s] %(message)s',
376  level=logging.INFO if not args.debug else DEBUG)
377  logging.info('>>> launch mergeLHE.py in %s' % os.path.abspath(os.getcwd()))
378 
379  # Extract input LHE files from the path
380  assert len(args.input_files), \
381  ('Please specify your input LHE files by -i/--input-files. '
382  'Run \'mergeLHE.py -h\' for details.')
383  input_files = [] # each individual input file
384  for path in args.input_files.split(','):
385  find_files = glob.glob(path)
386  if len(find_files) == 0:
387  logging.info('Warning: cannot find files in %s' % path)
388  input_files += find_files
389  input_files.sort()
390  logging.info('>>> Merge %d files: [%s]' % (len(input_files), ', '.join(input_files)))
391  logging.info('>>> Write to output: %s ' % args.output_file)
392 
393  if not os.path.exists(os.path.dirname(os.path.realpath(args.output_file))):
394  os.makedirs(os.path.dirname(os.path.realpath(args.output_file)))
395 
396  # Check arguments
397  assert len(input_files) > 0, 'Input LHE files should be more than 0.'
398  if len(input_files) == 1:
399  logging.warning('Input LHE only has 1 file. Will copy this file to the destination.')
400  import shutil
401  shutil.copy(input_files[0], args.output_file)
402  return
403  assert [args.force_mglo_merger, args.force_cpp_merger].count(True) <= 1, \
404  "Can only specify at most one from --force-mglo-merger or --force-cpp-merger."
405 
406  # Determine the merging scheme
407  if args.force_mglo_merger:
408  lhe_merger = MG5LOLHEMerger(input_files, args.output_file)
409  elif args.force_cpp_merger:
410  lhe_merger = ExternalCppLHEMerger(input_files, args.output_file)
411  else:
412  lhe_merger = DefaultLHEMerger(input_files, args.output_file, bypass_check=args.bypass_check)
413 
414  # Do merging
415  lhe_merger.merge()
416 
def main
Definition: mergeLHE.py:325
static std::string join(char **cmd)
Definition: RemoteFile.cc:19