CMS 3D CMS Logo

Classes | Functions
mergeLHE Namespace Reference

Classes

class  BaseLHEMerger
 
class  DefaultLHEMerger
 
class  ExternalCppLHEMerger
 
class  MG5LOLHEMerger
 

Functions

def main (argv=None)
 

Function Documentation

◆ main()

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().

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