diff --git a/Control/AthenaConfiguration/share/confTool.py b/Control/AthenaConfiguration/share/confTool.py index 29534568ce180be9722c9301da2e2bdec4fc89c5..d71a22292d007d810f27d632efbedcd8d86b3a6a 100755 --- a/Control/AthenaConfiguration/share/confTool.py +++ b/Control/AthenaConfiguration/share/confTool.py @@ -22,7 +22,9 @@ def parse_args(): parser = argparse.ArgumentParser( description="Utility to transform/display athena configurations" ) - parser.add_argument("-p", "--printConf", action="store_true", help="Prints") + parser.add_argument( + "-p", "--printConf", action="store_true", help="Prints" + ) parser.add_argument( "--printComps", action="store_true", help="Prints only the components" ) @@ -82,14 +84,18 @@ def main(args): if args.toJSON: if len(args.file) != 1: - sys.exit("ERROR, can convert single file at a time, got: %s" % args.file) + sys.exit( + "ERROR, can convert single file at a time, got: %s" % args.file + ) conf = _loadSingleFile(args.file[0], args) with open(args.toJSON, "w") as oFile: json.dump(conf, oFile, indent=2, ensure_ascii=True) if args.toPickle: if len(args.file) != 1: - sys.exit("ERROR, can convert single file at a time, got: %s" % args.file) + sys.exit( + "ERROR, can convert single file at a time, got: %s" % args.file + ) conf = _loadSingleFile(args.file[0], args) with open(args.toPickle, "wb") as oFile: for item in conf: @@ -97,7 +103,10 @@ def main(args): if args.diff: if len(args.file) != 2: - sys.exit("ERROR, can diff exactly two files at a time, got: %s" % args.file) + sys.exit( + "ERROR, can diff exactly two files at a time, got: %s" + % args.file + ) configRef = _loadSingleFile(args.file[0], args) configChk = _loadSingleFile(args.file[1], args) flattenedRef = {} @@ -108,8 +117,22 @@ def main(args): for chk in configChk: if isinstance(chk, dict): flattenedChk.update(chk) + + if args.ignoreIrrelevant: + args.ignoreList = [ + "StoreGateSvc", + "OutputLevel", + "MuonEDMHelperSvc", + "ExtraInputs", + "ExtraOutputs", + "DetStore", + "EvtStore", + "NeededResources", + ] + print(f"Components to ignore: {args.ignoreList}") _compareConfig(flattenedRef, flattenedChk, args) + def _loadSingleFile(fname, args): conf = [] if fname.endswith(".pkl"): @@ -118,14 +141,17 @@ def _loadSingleFile(fname, args): cfg = pickle.load(input_file) if isinstance(cfg, ComponentAccumulator): # new configuration props = cfg.gatherProps() - jos_props = props[2] # to make json compatible with old configuration + # to make json compatible with old configuration + jos_props = props[2] to_json = {} for comp, name, value in jos_props: to_json.setdefault(comp, {})[name] = value to_json[comp][name] = value conf = [to_json, props[0], props[1]] - elif isinstance(cfg, (collections.defaultdict, dict)): # old configuration + elif isinstance( + cfg, (collections.defaultdict, dict) + ): # old configuration cfg.update(pickle.load(input_file)) conf.append(pickle.load(input_file)) conf.append(cfg) @@ -165,7 +191,11 @@ def _loadSingleFile(fname, args): item for elem in args.comps for item in elem ] # creates flat list of wanted components conf = [ - {key: value for (key, value) in dic.items() if is_component_from_list(key)} + { + key: value + for (key, value) in dic.items() + if is_component_from_list(key) + } for dic in conf if isinstance(dic, dict) ] @@ -233,6 +263,16 @@ def _compareConfig(configRef, configChk, args): ) +def _parseNumericalValues(v1, v2): + values = (v1, v2) + if any(isinstance(val, float) for val in values): + return float(v1), float(v2) + elif all(isinstance(val, int) for val in values): + return int(v1), int(v2) + else: + return values + + def _compareComponent(compRef, compChk, prefix, args, component): if isinstance(compRef, dict): @@ -240,18 +280,17 @@ def _compareComponent(compRef, compChk, prefix, args, component): allProps = list(set(compRef.keys()) | set(compChk.keys())) allProps.sort() - ignoreList = ["StoreGateSvc", "OutputLevel", "MuonEDMHelperSvc"] for prop in allProps: if prop not in compRef.keys(): print( - "%s%s = %s: \033[94m exists only in Chk \033[0m \033[91m<< !!!\033[0m" + "%s%s = %s: \033[94m exists only in 2nd file \033[0m \033[91m<< !!!\033[0m" % (prefix, prop, compChk[prop]) ) continue if prop not in compChk.keys(): print( - "%s%s = %s: \033[92m exists only in Ref \033[0m \033[91m<< !!!\033[0m" + "%s%s = %s: \033[92m exists only in 1st file \033[0m \033[91m<< !!!\033[0m" % (prefix, prop, compRef[prop]) ) continue @@ -259,9 +298,13 @@ def _compareComponent(compRef, compChk, prefix, args, component): refVal = compRef[prop] chkVal = compChk[prop] - if args.ignoreIrrelevant and chkVal in ignoreList: + if args.ignoreIrrelevant and any( + element in args.ignoreList for element in [chkVal, prop] + ): continue + refVal, chkVal = _parseNumericalValues(refVal, chkVal) + if str(chkVal) == str(refVal): if not args.printIdenticalPerParameter: continue @@ -283,7 +326,9 @@ def _compareComponent(compRef, compChk, prefix, args, component): except ValueError: pass # literal_eval exception when parsing particular strings - if refVal and (isinstance(refVal, list) or isinstance(refVal, dict)): + if refVal and ( + isinstance(refVal, list) or isinstance(refVal, dict) + ): if component == "IOVDbSvc" and prop == "Folders": _compareIOVDbFolders(refVal, chkVal, "\t", args) else: @@ -304,18 +349,20 @@ def _compareComponent(compRef, compChk, prefix, args, component): if diffRef: print( - "%s exists only in Ref : \033[92m %s \033[0m \033[91m<< !!!\033[0m" + "%s exists only in 1st file : \033[92m %s \033[0m \033[91m<< !!!\033[0m" % (prefix, str(diffRef)) ) if diffChk: print( - "%s exists only in Chk : \033[94m %s \033[0m \033[91m<< !!!\033[0m" + "%s exists only in 2nd file : \033[94m %s \033[0m \033[91m<< !!!\033[0m" % (prefix, str(diffChk)) ) if len(compRef) == len(compChk): if sorted(compRef) == sorted(compChk): - print("%s : \033[91m ^^ Different order ^^ !!!\033[0m" % (prefix)) + print( + "%s : \033[91m ^^ Different order ^^ !!!\033[0m" % (prefix) + ) else: for i, (refVal, chkVal) in enumerate(zip(compRef, compChk)): if refVal != chkVal: