523 This is to replace subsets of configuration flags like
526 newflags = flags.cloneAndReplace('Muon', 'Trigger.Offline.Muon')
529 _msg.debug(
"cloning flags and replacing %s by %s", subsetToReplace, replacementSubset)
534 subsetToReplace = subsetToReplace.strip(
".")
535 replacementSubset = replacementSubset.strip(
".")
538 if (subsetToReplace == replacementSubset):
539 raise RuntimeError(f
'Can not replace flags {subsetToReplace} with themselves')
542 for alias,src
in self.
_renames.items():
543 if src
is None:
continue
544 if src+
"." in subsetToReplace:
545 raise RuntimeError(f
'Can not replace flags {subsetToReplace} by {replacementSubset} because of already present replacement of {alias} by {src}')
548 newFlags = copy(self)
549 newFlags._renames = deepcopy(self.
_renames)
551 if replacementSubset
in newFlags._renames:
552 newFlags._renames[subsetToReplace] = newFlags._renames[replacementSubset]
554 newFlags._renames[subsetToReplace] = replacementSubset
557 if replacementSubset
not in newFlags._renames
or newFlags._renames[replacementSubset] == replacementSubset:
558 newFlags._renames[replacementSubset] =
None
560 del newFlags._renames[replacementSubset]
565 if replacementSubset
not in newFlags._renames:
566 newFlags._renames[replacementSubset] = replacementSubset
568 newFlags._hash =
None
593 def dump(self, pattern=".*", evaluate=False, formatStr="{:40} : {}
", maxLength=None):
595 compiled = re.compile(pattern)
596 def truncate(s):
return s[:maxLength] + (
"..." if maxLength
and len(s)>maxLength
else "")
597 reverse_renames = {value: key
for key, value
in self.
_renames.items()
if value
is not None}
600 if any([name.startswith(r)
for r
in reverse_renames.keys()
if r
is not None]):
601 for oldprefix, newprefix
in reverse_renames.items():
602 if name.startswith(oldprefix):
603 renamed = name.replace(oldprefix, newprefix)
605 if compiled.match(renamed):
611 print(formatStr.format(renamed,truncate(
"{} {}".format( val, rep )) ))
613 print(formatStr.format(renamed, truncate(
"{}".format(val)) ) )
614 except Exception
as e:
615 print(formatStr.format(renamed, truncate(
"Exception: {}".format( e )) ))
617 print(formatStr.format( renamed, truncate(
"{}".format(repr(self.
_flagdict[name] ) )) ))
620 print(
"Flag categories that can be loaded dynamically")
621 print(
"{:25} : {:>30} : {}".format(
"Category",
"Generator name",
"Defined in" ) )
622 for name,gen_and_prefix
in sorted(self.
_dynaflags.items()):
623 if compiled.match(name):
624 print(
"{:25} : {:>30} : {}".format( name, gen_and_prefix[0].__name__,
'/'.
join(gen_and_prefix[0].__code__.co_filename.split(
'/')[-2:]) ) )
626 print(
"Flag categories that are redirected by the cloneAndReplace")
627 for alias,src
in self.
_renames.items():
628 print(
"{:30} points to {:>30} ".format( alias, src
if src
else "nothing") )
700 def fillFromArgs(self, listOfArgs=None, parser=None, return_unknown=False):
702 Used to set flags from command-line parameters, like flags.fillFromArgs(sys.argv[1:])
704 if return_unknown=False, returns: args
705 otherwise returns: args, uknown_args
706 where unknown_args is the list of arguments that did not correspond to one of the flags
715 argList = listOfArgs
if listOfArgs
is not None else sys.argv[1:]
722 unrequiredActions = []
723 if "-h" in argList
or "--help" in argList:
725 if "-h" in argList: argList.remove(
"-h")
726 if "--help" in argList: argList.remove(
"--help")
728 for a
in parser._actions:
730 unrequiredActions.append(a)
732 (args,leftover)=parser.parse_known_args(argList)
733 for a
in unrequiredActions: a.required=
True
736 argList = [a
for a
in argList
if a
not in leftover]
740 """Check if dest is available in parser and has been set"""
741 return vars(args).
get(dest,
None)
is not None
744 self.Exec.DebugStage=args.debug
746 if arg_set(
'evtMax'):
747 self.Exec.MaxEvents=args.evtMax
749 if arg_set(
'interactive'):
750 self.Exec.Interactive=args.interactive
752 if arg_set(
'skipEvents'):
753 self.Exec.SkipEvents=args.skipEvents
755 if arg_set(
'filesInput'):
756 self.Input.Files = []
757 for f
in args.filesInput.split(
","):
760 self.Input.Files += found
if found
else [f]
762 if "-l" in argList
or "--loglevel" in argList:
763 from AthenaCommon
import Constants
764 self.Exec.OutputLevel = getattr(Constants, args.loglevel)
766 if arg_set(
'config_only')
and args.config_only
is not False:
767 from os
import environ
768 environ[
"PICKLECAFILE"] =
"" if args.config_only
is True else args.config_only
770 if arg_set(
'threads'):
771 self.Concurrency.NumThreads = args.threads
775 if args.concurrent_events
is None and self.Concurrency.NumConcurrentEvents==0:
776 self.Concurrency.NumConcurrentEvents = args.threads
778 if arg_set(
'concurrent_events'):
779 self.Concurrency.NumConcurrentEvents = args.concurrent_events
781 if arg_set(
'nprocs'):
782 self.Concurrency.NumProcs = args.nprocs
784 if arg_set(
'perfmon'):
785 from PerfMonComps.PerfMonConfigHelpers
import setPerfmonFlagsFromRunArgs
786 setPerfmonFlagsFromRunArgs(self, args)
789 self.Exec.MTEventService = args.mtes
791 if arg_set(
'mtes_channel'):
792 self.Exec.MTEventServiceChannel = args.mtes_channel
794 if arg_set(
'profile_python'):
795 from AthenaCommon.Debugging
import dumpPythonProfile
796 import atexit, cProfile, functools
797 cProfile._athena_python_profiler = cProfile.Profile()
798 cProfile._athena_python_profiler.enable()
801 atexit.register(functools.partial(dumpPythonProfile, args.profile_python))
804 self.Exec.MPI = args.mpi
812 if do_help
and '=' not in arg:
813 argList += arg.split(
".")
817 except KeyError
as e:
819 unknown_args += [arg]
824 if parser.epilog
is None: parser.epilog=
""
825 parser.epilog +=
" Note: Specify additional flags in form <flagName>=<value>."
826 subparsers = {
"":[parser,parser.add_subparsers(help=argparse.SUPPRESS)]}
828 logging.root.setLevel(logging.ERROR)
829 os.environ[
"TDAQ_ERS_WARNING"] =
"null"
830 os.environ[
"TDAQ_ERS_ERROR"] =
"null"
831 def getParser(category):
832 if category
not in subparsers.keys():
833 cat1,cat2 = category.rsplit(
".",1)
if "." in category
else (
"",category)
834 p,subp = getParser(cat1)
835 if subp.help==argparse.SUPPRESS:
836 subp.help =
"Flag subcategories:"
837 newp = subp.add_parser(cat2,help=
"{} flags".format(category),
838 formatter_class = argparse.ArgumentDefaultsHelpFormatter,usage=argparse.SUPPRESS)
839 newp._positionals.title =
"flags"
840 subparsers[category] = [newp,newp.add_subparsers(help=argparse.SUPPRESS)]
841 return subparsers[category]
844 category,flagName = name.rsplit(
".",1)
if "." in name
else (
"",name)
847 val = repr(flag.get(self))
850 if flag._help != argparse.SUPPRESS:
852 if flag._help
is not None:
853 helptext = f
": {flag._help}"
854 if flag._type
is not None:
855 helptext += f
' [type: {flag._type.__name__}]'
856 if val
is not None and helptext ==
"":
858 getParser(category)[0].add_argument(name, nargs=
'?', default=val, help=helptext)
860 parser._positionals.title =
'flags and positional arguments'
861 parser.parse_known_args(argList + [
"--help"])
866 return args,unknown_args