510 This is to replace subsets of configuration flags like
513 newflags = flags.cloneAndReplace('Muon', 'Trigger.Offline.Muon')
516 _msg.debug(
"cloning flags and replacing %s by %s", subsetToReplace, replacementSubset)
521 subsetToReplace = subsetToReplace.strip(
".")
522 replacementSubset = replacementSubset.strip(
".")
525 if (subsetToReplace == replacementSubset):
526 raise RuntimeError(f
'Can not replace flags {subsetToReplace} with themselves')
529 for alias,src
in self.
_renames.items():
530 if src
is None:
continue
531 if src+
"." in subsetToReplace:
532 raise RuntimeError(f
'Can not replace flags {subsetToReplace} by {replacementSubset} because of already present replacement of {alias} by {src}')
535 newFlags = copy(self)
536 newFlags._renames = deepcopy(self.
_renames)
538 if replacementSubset
in newFlags._renames:
539 newFlags._renames[subsetToReplace] = newFlags._renames[replacementSubset]
541 newFlags._renames[subsetToReplace] = replacementSubset
544 if replacementSubset
not in newFlags._renames
or newFlags._renames[replacementSubset] == replacementSubset:
545 newFlags._renames[replacementSubset] =
None
547 del newFlags._renames[replacementSubset]
552 if replacementSubset
not in newFlags._renames:
553 newFlags._renames[replacementSubset] = replacementSubset
555 newFlags._hash =
None
580 def dump(self, pattern=".*", evaluate=False, formatStr="{:40} : {}
", maxLength=None):
582 compiled = re.compile(pattern)
583 def truncate(s):
return s[:maxLength] + (
"..." if maxLength
and len(s)>maxLength
else "")
584 reverse_renames = {value: key
for key, value
in self.
_renames.items()
if value
is not None}
587 if any([name.startswith(r)
for r
in reverse_renames.keys()
if r
is not None]):
588 for oldprefix, newprefix
in reverse_renames.items():
589 if name.startswith(oldprefix):
590 renamed = name.replace(oldprefix, newprefix)
592 if compiled.match(renamed):
598 print(formatStr.format(renamed,truncate(
"{} {}".format( val, rep )) ))
600 print(formatStr.format(renamed, truncate(
"{}".format(val)) ) )
601 except Exception
as e:
602 print(formatStr.format(renamed, truncate(
"Exception: {}".format( e )) ))
604 print(formatStr.format( renamed, truncate(
"{}".format(repr(self.
_flagdict[name] ) )) ))
607 print(
"Flag categories that can be loaded dynamically")
608 print(
"{:25} : {:>30} : {}".format(
"Category",
"Generator name",
"Defined in" ) )
609 for name,gen_and_prefix
in sorted(self.
_dynaflags.items()):
610 if compiled.match(name):
611 print(
"{:25} : {:>30} : {}".format( name, gen_and_prefix[0].__name__,
'/'.
join(gen_and_prefix[0].__code__.co_filename.split(
'/')[-2:]) ) )
613 print(
"Flag categories that are redirected by the cloneAndReplace")
614 for alias,src
in self.
_renames.items():
615 print(
"{:30} points to {:>30} ".format( alias, src
if src
else "nothing") )
687 def fillFromArgs(self, listOfArgs=None, parser=None, return_unknown=False):
689 Used to set flags from command-line parameters, like flags.fillFromArgs(sys.argv[1:])
691 if return_unknown=False, returns: args
692 otherwise returns: args, uknown_args
693 where unknown_args is the list of arguments that did not correspond to one of the flags
702 argList = listOfArgs
if listOfArgs
is not None else sys.argv[1:]
709 unrequiredActions = []
710 if "-h" in argList
or "--help" in argList:
712 if "-h" in argList: argList.remove(
"-h")
713 if "--help" in argList: argList.remove(
"--help")
715 for a
in parser._actions:
717 unrequiredActions.append(a)
719 (args,leftover)=parser.parse_known_args(argList)
720 for a
in unrequiredActions: a.required=
True
723 argList = [a
for a
in argList
if a
not in leftover]
727 """Check if dest is available in parser and has been set"""
728 return vars(args).
get(dest,
None)
is not None
731 self.Exec.DebugStage=args.debug
733 if arg_set(
'evtMax'):
734 self.Exec.MaxEvents=args.evtMax
736 if arg_set(
'interactive'):
737 self.Exec.Interactive=args.interactive
739 if arg_set(
'skipEvents'):
740 self.Exec.SkipEvents=args.skipEvents
742 if arg_set(
'filesInput'):
743 self.Input.Files = []
744 for f
in args.filesInput.split(
","):
747 self.Input.Files += found
if found
else [f]
749 if "-l" in argList
or "--loglevel" in argList:
750 from AthenaCommon
import Constants
751 self.Exec.OutputLevel = getattr(Constants, args.loglevel)
753 if arg_set(
'config_only')
and args.config_only
is not False:
754 from os
import environ
755 environ[
"PICKLECAFILE"] =
"" if args.config_only
is True else args.config_only
757 if arg_set(
'threads'):
758 self.Concurrency.NumThreads = args.threads
762 if args.concurrent_events
is None and self.Concurrency.NumConcurrentEvents==0:
763 self.Concurrency.NumConcurrentEvents = args.threads
765 if arg_set(
'concurrent_events'):
766 self.Concurrency.NumConcurrentEvents = args.concurrent_events
768 if arg_set(
'nprocs'):
769 self.Concurrency.NumProcs = args.nprocs
771 if arg_set(
'perfmon'):
772 from PerfMonComps.PerfMonConfigHelpers
import setPerfmonFlagsFromRunArgs
773 setPerfmonFlagsFromRunArgs(self, args)
776 self.Exec.MTEventService = args.mtes
778 if arg_set(
'mtes_channel'):
779 self.Exec.MTEventServiceChannel = args.mtes_channel
781 if arg_set(
'profile_python'):
782 from AthenaCommon.Debugging
import dumpPythonProfile
783 import atexit, cProfile, functools
784 cProfile._athena_python_profiler = cProfile.Profile()
785 cProfile._athena_python_profiler.enable()
788 atexit.register(functools.partial(dumpPythonProfile, args.profile_python))
791 self.Exec.MPI = args.mpi
799 if do_help
and '=' not in arg:
800 argList += arg.split(
".")
804 except (KeyError,ValueError)
as e:
806 unknown_args += [arg]
811 if parser.epilog
is None: parser.epilog=
""
812 parser.epilog +=
" Note: Specify additional flags in form <flagName>=<value>."
813 subparsers = {
"":[parser,parser.add_subparsers(help=argparse.SUPPRESS)]}
815 logging.root.setLevel(logging.ERROR)
816 os.environ[
"TDAQ_ERS_WARNING"] =
"null"
817 os.environ[
"TDAQ_ERS_ERROR"] =
"null"
819 ignoreLevel = ROOT.gErrorIgnoreLevel
820 ROOT.gErrorIgnoreLevel=ROOT.kFatal
822 def getParser(category):
823 if category
not in subparsers.keys():
824 cat1,cat2 = category.rsplit(
".",1)
if "." in category
else (
"",category)
825 p,subp = getParser(cat1)
826 if subp.help==argparse.SUPPRESS:
827 subp.help =
"Flag subcategories:"
828 newp = subp.add_parser(cat2,help=
"{} flags".format(category),
829 formatter_class = argparse.ArgumentDefaultsHelpFormatter,usage=argparse.SUPPRESS)
830 newp._positionals.title =
"flags"
831 subparsers[category] = [newp,newp.add_subparsers(help=argparse.SUPPRESS)]
832 return subparsers[category]
835 category,flagName = name.rsplit(
".",1)
if "." in name
else (
"",name)
838 val = repr(flag.get(self))
841 if flag._help != argparse.SUPPRESS:
843 if flag._help
is not None:
844 helptext = f
": {flag._help}"
845 if flag._type
is not None:
846 helptext += f
' [type: {flag._type.__name__}]'
847 if val
is not None and helptext ==
"":
849 getParser(category)[0].add_argument(name, nargs=
'?', default=val, help=helptext)
851 parser._positionals.title =
'flags and positional arguments'
852 parser.parse_known_args(argList + [
"--help"])
853 ROOT.gErrorIgnoreLevel=ignoreLevel
858 return args,unknown_args