5 from fnmatch 
import fnmatchcase
 
    6 from AthenaCommon.Logging 
import logging
 
    7 from AthenaConfiguration.AthConfigFlags 
import isGaudiEnv
 
    8 from PyUtils.PoolFile 
import isRNTuple
 
    9 from ROOT 
import gSystem
 
   10 from AthenaConfiguration.Enums 
import Project
 
   13 msg = logging.getLogger(
'MetaReader')
 
   16 regexEventStreamInfo = re.compile(
r'^EventStreamInfo(_p\d+)?$')
 
   17 regexIOVMetaDataContainer = re.compile(
r'^IOVMetaDataContainer(_p\d+)?$')
 
   18 regexByteStreamMetadataContainer = re.compile(
r'^ByteStreamMetadataContainer(_p\d+)?$')
 
   19 regexXAODCutBookkeeperContainer = re.compile(
r'^xAOD::CutBookkeeperContainer(_v\d+)?$')
 
   20 regexXAODCutBookkeeperContainerAux = re.compile(
r'^xAOD::CutBookkeeperAuxContainer(_v\d+)?$')
 
   21 regexXAODEventFormat = re.compile(
r'^xAOD::EventFormat(_v\d+)?$')
 
   22 regexXAODFileMetaData = re.compile(
r'^xAOD::FileMetaData(_v\d+)?$')
 
   23 regexXAODFileMetaDataAux = re.compile(
r'^xAOD::FileMetaDataAuxInfo(_v\d+)?$')
 
   24 regexXAODFileMetaDataAuxDyn = re.compile(
r'^(xAOD::)?FileMetaData.*AuxDyn(\.[a-zA-Z0-9]+)?$')
 
   25 regexXAODTriggerMenu = re.compile(
r'^DataVector<xAOD::TriggerMenu(_v\d+)?>$') 
 
   26 regexXAODTriggerMenuAux = re.compile(
r'^xAOD::TriggerMenuAuxContainer(_v\d+)?$') 
 
   27 regexXAODTriggerMenuJson = re.compile(
r'^DataVector<xAOD::TriggerMenuJson(_v\d+)?>$') 
 
   28 regexXAODTriggerMenuJsonAux = re.compile(
r'^xAOD::TriggerMenuJsonAuxContainer(_v\d+)?$') 
 
   29 regexXAODTruthMetaData = re.compile(
r'^DataVector<xAOD::TruthMetaData(_v\d+)?>$')
 
   30 regexXAODTruthMetaDataAux = re.compile(
r'^xAOD::TruthMetaDataAuxContainer(_v\d+)?$')
 
   31 regex_cppname = re.compile(
r'^([\w:]+)(<.*>)?$')
 
   33 regex_persistent_class = re.compile(
r'^([a-zA-Z]+(_[pv]\d+)?::)*[a-zA-Z]+_[pv]\d+$')
 
   34 regex_BS_files = re.compile(
r'^(\w+):.*((\.D?RAW\..*)|(\.data$))')
 
   35 regex_URI_scheme = re.compile(
r'^([A-Za-z0-9\+\.\-]+)\:')
 
   37 lite_primary_keys_to_keep = [
 
   38     'lumiBlockNumbers', 
'runNumbers', 
'mc_event_number', 
'mc_channel_number',
 
   39     'eventTypes', 
'processingTags', 
'itemList']
 
   40 lite_TagInfo_keys_to_keep = [
 
   41     'beam_energy', 
'beam_type', 
'GeoAtlas', 
'IOVDbGlobalTag',
 
   42     'AODFixVersion', 
'project_name', 
'mc_campaign', 
'keywords']
 
   46     'TriggerMenu', 
'TriggerMenuJson_BG', 
'TriggerMenuJson_HLT', 
'TriggerMenuJson_HLTMonitoring', 
'TriggerMenuJson_HLTPS', 
'TriggerMenuJson_L1', 
'TriggerMenuJson_L1PS',
 
   47     '/TRIGGER/HLT/Groups', 
'/TRIGGER/HLT/HltConfigKeys', 
'/TRIGGER/HLT/Menu', 
'/TRIGGER/HLT/PrescaleKey', 
'/TRIGGER/HLT/Prescales',
 
   48     '/TRIGGER/LVL1/ItemDef', 
'/TRIGGER/LVL1/Lvl1ConfigKey', 
'/TRIGGER/LVL1/Menu', 
'/TRIGGER/LVL1/Prescales', 
'/TRIGGER/LVL1/Thresholds',
 
   49     'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenu', 
'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_BG', 
'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT',
 
   50     'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTMonitoring', 
'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTPS',
 
   51     'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1', 
'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1PS',
 
   54 trigger_menu_json_map = {
 
   55     "xAOD__TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_L1PSAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1PS",
 
   56     "xAOD__TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_BGAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_BG",
 
   57     "xAOD__TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT",
 
   58     "xAOD__TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTMonitoringAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTMonitoring",
 
   59     "xAOD__TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTPSAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTPS",
 
   60     "xAOD__TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_L1Aux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1",
 
   61     "TriggerMenuJson_L1PSAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1PS",
 
   62     "TriggerMenuJson_BGAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_BG",
 
   63     "TriggerMenuJson_HLTAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT",
 
   64     "TriggerMenuJson_HLTMonitoringAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTMonitoring",
 
   65     "TriggerMenuJson_HLTPSAux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTPS",
 
   66     "TriggerMenuJson_L1Aux:": 
"DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1",
 
   70 def read_metadata(filenames, file_type = None, mode = 'lite', promote = None, meta_key_filter = None,
 
   71                   unique_tag_info_values = True, ignoreNonExistingLocalFiles=False):
 
   73     This tool is independent of Athena framework and returns the metadata from a given file. 
   74     :param filenames: the input file from which metadata needs to be extracted. 
   75     :param file_type: the type of file. POOL or BS (bytestream: RAW, DRAW) files. 
   76     :param mode: if true, will return all metadata associated with the filename. By default, is false and this will 
   77     return a "tiny" version which have only the following keys: 'file_guid', 'file_size', 'file_type', 'nentries'. 
   78     :return: a dictionary of metadata for the given input file. 
   85     from RootUtils 
import PyROOTFixes  
 
   88     if isinstance(filenames, str):
 
   89         filenames = [filenames]
 
   92     if file_type 
is not None:
 
   93         if file_type 
not in (
'POOL', 
'BS'):
 
   94             raise NameError(
'Allowed values for \'file_type\' parameter are: "POOL" or "BS": you provided "' + file_type + 
'"')
 
   96             msg.info(
'Forced file_type: {0}'.
format(file_type))
 
   99     if mode 
not in (
'tiny', 
'lite', 
'full', 
'peeker', 
'iov'):
 
  100         raise NameError(
'Allowed values for "mode" parameter are: "tiny", "lite", "peeker", "iov" or "full"')
 
  102     if meta_key_filter 
is None:
 
  107         if mode 
in (
'full', 
'iov'):
 
  108             raise NameError(
'The following modes are not available in AnalysisBase: "iov" and "full"')
 
  110     msg.info(
'Current mode used: {0}'.
format(mode))
 
  111     msg.info(
'Current filenames: {0}'.
format(filenames))
 
  113     if mode != 
'full' and mode !=
'iov' and len(meta_key_filter) > 0:
 
  114         raise NameError(
'It is possible to use the meta_key_filter option only for full mode')
 
  116         msg.info(
'Filter used: {0}'.
format(meta_key_filter))
 
  122     for filename 
in filenames:
 
  123         meta_dict[filename] = {}
 
  124         current_file_type = 
None 
  127             if os.path.isfile(filename):
 
  129                 if ignoreNonExistingLocalFiles 
and not regex_URI_scheme.match(filename) 
and gSystem.AccessPathName(filename): 
 
  130                     msg.warn(
'Ignoring not accessible file: {}'.
format(filename))
 
  133                 with open(filename, 
'rb') 
as binary_file:
 
  134                     magic_file = binary_file.read(4)
 
  136                     if magic_file == 
'root' or magic_file == b
'root':
 
  137                         current_file_type = 
'POOL' 
  138                         meta_dict[filename][
'file_type'] = 
'POOL' 
  140                     elif Project.determine() 
in (
 
  141                             Project.AnalysisBase, Project.AthAnalysis):
 
  143                             f
"{filename} is not a ROOT file, assumed bytestream" 
  144                             ", this is not supported in Analysis releases")
 
  146                         current_file_type = 
'BS' 
  147                         meta_dict[filename][
'file_type'] = 
'BS' 
  150                     meta_dict[filename][
'file_size'] = os.path.getsize(filename)
 
  154                 if regex_BS_files.match(filename):
 
  155                     current_file_type = 
'BS' 
  156                     meta_dict[filename][
'file_type'] = 
'BS' 
  158                     current_file_type = 
'POOL' 
  159                     meta_dict[filename][
'file_type'] = 
'POOL' 
  162                 meta_dict[filename][
'file_size'] = 
None   
  165             current_file_type = file_type
 
  168         if current_file_type == 
'POOL':
 
  170             if ignoreNonExistingLocalFiles 
and not regex_URI_scheme.match(filename) 
and gSystem.AccessPathName(filename): 
 
  171                 msg.warn(
'Ignoring not accessible file: {}'.
format(filename))
 
  176             current_file = ROOT.TFile.Open( 
_get_pfn(filename) )
 
  179             from PyUtils.PoolFile 
import PoolOpts
 
  180             collectionTree = current_file.Get(PoolOpts.TTreeNames.EventData)
 
  181             if isinstance(collectionTree, ROOT.TTree):
 
  182                 meta_dict[filename][
'auto_flush'] = collectionTree.GetAutoFlush()
 
  185             meta_dict[filename][
'file_guid'] = 
_read_guid(filename)
 
  188             meta_dict[filename][
'file_comp_alg'] = current_file.GetCompressionAlgorithm()
 
  189             meta_dict[filename][
'file_comp_level'] = current_file.GetCompressionLevel()
 
  192                 isRNTuple(md:=current_file.Get(PoolOpts.RNTupleNames.MetaData))
 
  196                     "Reading in-file metadata from RNTuple is currently of limited support" 
  198                 meta_dict[filename][
"metadata_items"] = {}
 
  201                     from ROOT 
import RNTupleReader
 
  203                     from ROOT.Experimental 
import RNTupleReader
 
  205                 reader = RNTupleReader.Open(md)
 
  206                 entry = reader.CreateEntry()
 
  207                 reader.LoadEntry(0, entry)
 
  210                     "xAOD::FileMetaData_v1",
 
  211                     "xAOD::FileMetaDataAuxInfo_v1",
 
  212                     "xAOD::TriggerMenuJsonAuxContainer_v1",
 
  213                     "DataVector<xAOD::TriggerMenuJson_v1>",
 
  214                     "xAOD::TruthMetaDataAuxContainer_v1",
 
  215                     "DataVector<xAOD::TruthMetaData_v1>",
 
  216                     "xAOD::CutBookkeeperContainer_v1",
 
  217                     "xAOD::CutBookkeeperAuxContainer_v1",
 
  218                     "xAOD::LumiBlockRangeAuxContainer_v1",
 
  219                     "DataVector<xAOD::LumiBlockRange_v1>",
 
  222                 dynamic_fmd_items = {}
 
  226                 for field 
in reader.GetDescriptor().GetTopLevelFields():
 
  227                     normalizedName = field.GetFieldName()
 
  228                     if "index_ref" in normalizedName:
 
  230                     if regexIOVMetaDataContainer.match(field.GetTypeName()):
 
  235                             .
replace(
"IOVMetaDataContainer_p1_", 
"")
 
  238                         meta_dict[filename][
"metadata_items"][normalizedName] = (
 
  239                             "IOVMetaDataContainer" 
  241                     elif regexByteStreamMetadataContainer.match(field.GetTypeName()):
 
  242                         meta_dict[filename][
"metadata_items"][field.GetFieldName()] = (
 
  243                             "ByteStreamMetadataContainer" 
  245                     elif regexEventStreamInfo.match(field.GetTypeName()):
 
  246                         meta_dict[filename][
"metadata_items"][field.GetFieldName()] = (
 
  249                     elif regexXAODFileMetaData.match(field.GetTypeName()):
 
  250                         meta_dict[filename][
"metadata_items"][
 
  251                             field.GetFieldName().
replace(
"xAOD__", 
"xAOD::")
 
  252                         ] = field.GetTypeName()
 
  253                     elif regexXAODFileMetaDataAuxDyn.match(
 
  254                         normalizedName := field.GetFieldName()
 
  260                             if entry[field.GetFieldName()] == 
"\x00" 
  261                             else entry[field.GetFieldName()]
 
  263                         dynamic_fmd_items[normalizedName.split(
".")[1]] = result
 
  264                         meta_dict[filename][
"metadata_items"][normalizedName] = (
 
  268                     elif regexXAODFileMetaDataAux.match(field.GetTypeName()):
 
  269                         meta_dict[filename][
"metadata_items"][
 
  273                         ] = field.GetTypeName()
 
  274                     elif regexXAODTruthMetaData.match(field.GetTypeName()):
 
  275                         meta_dict[filename][
"metadata_items"][
 
  278                             .
replace(
"DataVector_", 
"DataVector<")
 
  281                     elif regexXAODTruthMetaDataAux.match(field.GetTypeName()):
 
  282                         meta_dict[filename][
"metadata_items"][
 
  286                         ] = field.GetTypeName()
 
  287                     elif regexXAODEventFormat.match(field.GetTypeName()):
 
  288                         meta_dict[filename][
"metadata_items"][
 
  289                             field.GetFieldName().
replace(
"xAOD__", 
"xAOD::")
 
  290                         ] = field.GetTypeName()
 
  291                     elif regexXAODTriggerMenuJson.match(field.GetTypeName()):
 
  292                         meta_dict[filename][
"metadata_items"][
 
  295                             .
replace(
"DataVector_", 
"DataVector<")
 
  296                             .
replace(
"__Trigger", 
">_Trigger")
 
  297                         ] = field.GetTypeName()
 
  298                     elif regexXAODTriggerMenuJsonAux.match(field.GetTypeName()):
 
  299                         meta_dict[filename][
"metadata_items"][
 
  303                         ] = field.GetTypeName()
 
  304                     elif regexXAODCutBookkeeperContainer.match(field.GetTypeName()):
 
  305                         meta_dict[filename][
"metadata_items"][
 
  308                             .
replace(
"DataVector_", 
"DataVector<")
 
  309                             .
replace(
"__CutBookkeeper", 
">_CutBookkeeper")
 
  310                         ] = field.GetTypeName()
 
  311                     elif regexXAODCutBookkeeperContainerAux.match(field.GetTypeName()):
 
  312                         meta_dict[filename][
"metadata_items"][
 
  316                         ] = field.GetTypeName()
 
  318                         meta_dict[filename][
"metadata_items"][
 
  319                             field.GetFieldName().
replace(
"Aux:", 
"Aux.")
 
  320                         ] = field.GetTypeName()
 
  322                     if field.GetTypeName() 
in classes_with_aux:
 
  324                         auxes[field.GetFieldName()] = field.GetTypeName()
 
  328                         normalizedName, field.GetTypeName(), meta_filter
 
  334                             entry[field.GetFieldName()]
 
  337                         msg.warning(f
"missing type {field.GetTypeName()}")
 
  340                     meta_dict[filename][
"metadata_items"]
 
  343                 def _get_aux_base(aux_key: str) -> str:
 
  346                     key = key.replace(
"xAOD__TriggerMenuJsonAuxContainer_v1_", 
"")
 
  347                     key = key.replace(
"xAOD__FileMetaDataAuxInfo_v1_", 
"")
 
  348                     key = key.replace(
"xAOD__TruthMetaDataAuxContainer_v1_", 
"")
 
  350                     if key.endswith(
"Aux:"):
 
  352                     elif key.endswith(
"Aux"):
 
  355                     key = key.strip(
"_:")
 
  358                 def _get_main_base(main_key: str) -> str:
 
  361                     if main_key.startswith(
"DataVector_xAOD__TriggerMenuJson_v1__"):
 
  362                         main_base = main_key.replace(
 
  363                             "DataVector_xAOD__TriggerMenuJson_v1__", 
"" 
  366                     elif main_key.startswith(
"xAOD__FileMetaData_v1_"):
 
  367                         main_base = main_key.replace(
"xAOD__FileMetaData_v1_", 
"")
 
  369                     elif main_key.startswith(
"DataVector_xAOD__TruthMetaData_v1__"):
 
  370                         main_base = main_key.replace(
 
  371                             "DataVector_xAOD__TruthMetaData_v1__", 
"" 
  375                 def _find_associated_pairs(auxes: dict) -> list[tuple[str, str]]:
 
  380                             aux_map[_get_aux_base(k)] = k
 
  384                         base = _get_main_base(k)
 
  390                     for base, aux_key 
in aux_map.items():
 
  392                             pairs.append((aux_key, main_map[base]))
 
  395                 for pair 
in _find_associated_pairs(auxes):
 
  403                             for k, v 
in trigger_menu_json_map.items()
 
  407                             .
replace(
"DataVector_", 
"DataVector<")
 
  408                             .
replace(
"__Trigger", 
">_Trigger")
 
  415                             key.replace(
"xAOD__", 
"xAOD::")
 
  416                             if key.count(
"_") <= 1
 
  417                             else key.replace(
"xAOD__", 
"xAOD::").rsplit(
"_", 2)[0]
 
  425                         .
replace(
"DataVector_", 
"DataVector<")
 
  426                         .
replace(
"__Trigger", 
">_Trigger")
 
  433                     if "TriggerMenuJson" in pair[0]:
 
  434                         if "RAWTriggerMenuJson" in return_obj:
 
  437                                 if pair[0].startswith(
"Trigger")
 
  438                                 else trigger_menu_json_map[pair[0]]
 
  440                             meta_dict[filename][key] = return_obj[
"RAWTriggerMenuJson"]
 
  441                             del return_obj[
"RAWTriggerMenuJson"]
 
  442                         if "TriggerConfigInfo" not in meta_dict[filename]:
 
  443                             meta_dict[filename][
"TriggerConfigInfo"] = {}
 
  444                         if "dbkey" in return_obj:
 
  445                             meta_dict[filename][
"TriggerConfigInfo"][
 
  447                             ] = {
"key": return_obj[
"dbkey"], 
"name": return_obj[
"name"]}
 
  448                             del return_obj[
"dbkey"]
 
  449                             del return_obj[
"name"]
 
  450                         if "TriggerMenu" not in meta_dict[filename]:
 
  451                             meta_dict[filename][
"TriggerMenu"] = {}
 
  452                         meta_dict[filename][
"TriggerMenu"].update(return_obj)
 
  453                     elif "FileMetaData" in pair[0]:
 
  454                         if "FileMetaData" not in meta_dict[filename]:
 
  455                             meta_dict[filename][
"FileMetaData"] = dynamic_fmd_items
 
  456                         meta_dict[filename][
"FileMetaData"].update(return_obj)
 
  457                     elif "TruthMetaData" in pair[0]:
 
  458                         if pair == (
"TruthMetaDataAux:", 
"TruthMetaData"):
 
  459                             if "TruthMetaData" not in meta_dict[filename]:
 
  460                                 meta_dict[filename][
"TruthMetaData"] = {}
 
  461                             meta_dict[filename][
"TruthMetaData"].update(return_obj)
 
  467                                 .
replace(
"DataVector_", 
"DataVector<")
 
  475                     elif pair == (
"CutBookkeepersAux:", 
"CutBookkeepers"):
 
  476                         meta_dict[filename][
"CutBookkeepers"] = return_obj
 
  478                 msg.debug(f
"Read metadata from RNTuple: {meta_dict[filename]}")
 
  484                     metadata_tree = current_file.Get(
'MetaData')
 
  486                     metadata_branches = metadata_tree.GetListOfBranches()
 
  487                     nr_of_branches = metadata_branches.GetEntriesFast()
 
  490                     meta_dict[filename][
'metadata_items'] = {}
 
  495                     persistent_instances = {}
 
  496                     dynamic_fmd_items = {}
 
  500                         metadata_tree.SetBranchStatus(
"*", 
False)
 
  502                     for i 
in range(0, nr_of_branches):
 
  503                         branch = metadata_branches.At(i)
 
  504                         name = branch.GetName()
 
  505                         if name == 
'index_ref':
 
  509                         class_name = branch.GetClassName()
 
  511                         if regexIOVMetaDataContainer.match(class_name):
 
  512                             name = name.replace(
'IOVMetaDataContainer_p1_', 
'').
replace(
'_', 
'/')
 
  514                         if regexIOVMetaDataContainer.match(class_name):
 
  515                             meta_dict[filename][
'metadata_items'][name] = 
'IOVMetaDataContainer' 
  516                         elif regexByteStreamMetadataContainer.match(class_name):
 
  517                             meta_dict[filename][
'metadata_items'][name] = 
'ByteStreamMetadataContainer' 
  518                         elif regexEventStreamInfo.match(class_name):
 
  519                             meta_dict[filename][
'metadata_items'][name] = 
'EventStreamInfo' 
  520                         elif regexXAODFileMetaData.match(class_name):
 
  521                             meta_dict[filename][
'metadata_items'][name] = 
'FileMetaData' 
  522                         elif regexXAODTruthMetaData.match(class_name):
 
  523                             meta_dict[filename][
'metadata_items'][name] = 
'TruthMetaData' 
  525                             type_name = class_name
 
  528                                     type_name = branch.GetListOfLeaves()[0].GetTypeName()
 
  531                             meta_dict[filename][
'metadata_items'][name] = type_name
 
  533                         if len(meta_filter) > 0:
 
  535                             for filter_key, filter_class 
in meta_filter.items():
 
  536                                 if (filter_key.replace(
'/', 
'_') 
in name.replace(
'/', 
'_') 
or filter_key == 
'*') 
and fnmatchcase(class_name, filter_class):
 
  537                                     if 'CutBookkeepers' in filter_key:
 
  538                                         keep = filter_key == name
 
  549                             if 'CutBookkeepers' in name 
and name 
not in [
'CutBookkeepers', 
'CutBookkeepersAux.']:
 
  553                             metadata_tree.SetBranchStatus(f
"{name}*", 
True)
 
  556                         if regexEventStreamInfo.match(class_name):
 
  557                             if class_name.endswith(
'_p1'):
 
  558                                 persistent_instances[name] = ROOT.EventStreamInfo_p1()
 
  559                             elif class_name.endswith(
'_p2'):
 
  560                                 persistent_instances[name] = ROOT.EventStreamInfo_p2()
 
  562                                 persistent_instances[name] = ROOT.EventStreamInfo_p3()
 
  563                         elif regexIOVMetaDataContainer.match(class_name):
 
  564                             persistent_instances[name] = ROOT.IOVMetaDataContainer_p1()
 
  565                         elif regexXAODEventFormat.match(class_name):
 
  566                             persistent_instances[name] = ROOT.xAOD.EventFormat_v1()
 
  567                         elif regexXAODTriggerMenu.match(class_name) 
and _check_project() 
not in [
'AthGeneration']:
 
  568                             persistent_instances[name] = ROOT.xAOD.TriggerMenuContainer_v1()
 
  569                         elif regexXAODTriggerMenuAux.match(class_name) 
and _check_project() 
not in [
'AthGeneration']:
 
  570                             persistent_instances[name] = ROOT.xAOD.TriggerMenuAuxContainer_v1()
 
  571                         elif regexXAODTriggerMenuJson.match(class_name) 
and _check_project() 
not in [
'AthGeneration']:
 
  572                             persistent_instances[name] = ROOT.xAOD.TriggerMenuJsonContainer_v1()
 
  573                         elif regexXAODTriggerMenuJsonAux.match(class_name) 
and _check_project() 
not in [
'AthGeneration']:
 
  574                             persistent_instances[name] = ROOT.xAOD.TriggerMenuJsonAuxContainer_v1()
 
  575                         elif regexXAODCutBookkeeperContainer.match(class_name):
 
  576                             persistent_instances[name] = ROOT.xAOD.CutBookkeeperContainer_v1()
 
  577                         elif regexXAODCutBookkeeperContainerAux.match(class_name):
 
  578                             persistent_instances[name] = ROOT.xAOD.CutBookkeeperAuxContainer_v1()
 
  579                         elif regexXAODFileMetaData.match(class_name):
 
  580                             persistent_instances[name] = ROOT.xAOD.FileMetaData_v1()
 
  581                         elif regexXAODFileMetaDataAux.match(class_name):
 
  582                             persistent_instances[name] = ROOT.xAOD.FileMetaDataAuxInfo_v1()
 
  583                         elif regexXAODTruthMetaData.match(class_name):
 
  584                             persistent_instances[name] = ROOT.xAOD.TruthMetaDataContainer_v1()
 
  585                         elif regexXAODTruthMetaDataAux.match(class_name):
 
  586                             persistent_instances[name] = ROOT.xAOD.TruthMetaDataAuxContainer_v1()
 
  588                         if name 
in persistent_instances:
 
  589                             branch.SetAddress(ROOT.AddressOf(persistent_instances[name]))
 
  592                         dynamicFMD = regexXAODFileMetaDataAuxDyn.match(name)
 
  594                             dynamicName = dynamicFMD.group().
split(
'.')[-1]
 
  595                             dynamicType = regex_cppname.match(class_name)
 
  598                                 dynamic_fmd_items[dynamicName] = ROOT.std.string()
 
  599                                 branch.SetAddress(ROOT.AddressOf(dynamic_fmd_items[dynamicName]))
 
  601                                 dynamic_fmd_items[dynamicName] = 
None 
  604                     metadata_tree.GetEntry(0)
 
  607                     for key 
in dynamic_fmd_items:
 
  608                         if dynamic_fmd_items[key] 
is None:
 
  610                                 if key.startswith(
"is"):
 
  612                                     dynamic_fmd_items[key] = getattr(metadata_tree, key) != 
'\x00' 
  615                                     dynamic_fmd_items[key] = getattr(metadata_tree, key)
 
  616                             except AttributeError:
 
  621                             dynamic_fmd_items[key] = 
str(dynamic_fmd_items[key])
 
  625                         meta_dict[filename] = {}
 
  628                     for name, content 
in persistent_instances.items():
 
  630                         if hasattr(content, 
'm_folderName'):
 
  631                             key = content.m_folderName
 
  634                         has_r3_trig_meta = (
'TriggerMenuJson_HLT' in persistent_instances 
or 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT' in persistent_instances)
 
  636                         if key.startswith(
'TriggerMenuJson_') 
and not key.endswith(
'Aux.'): 
 
  637                             aux = persistent_instances[key+
'Aux.']
 
  638                         elif key.startswith(
'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_') 
and not key.endswith(
'Aux.'): 
 
  639                             menuPart = key.split(
'_')[-1]
 
  640                             aux = persistent_instances[
'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_'+menuPart+
'Aux.']    
 
  641                         elif key == 
'TriggerMenu' and 'TriggerMenuAux.' in persistent_instances 
and not has_r3_trig_meta: 
 
  642                             aux = persistent_instances[
'TriggerMenuAux.']
 
  643                         elif key == 
'DataVector<xAOD::TriggerMenu_v1>_TriggerMenu' and 'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.' in persistent_instances 
and not has_r3_trig_meta: 
 
  644                             aux = persistent_instances[
'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.']
 
  645                         elif (key == 
'CutBookkeepers' 
  646                             and 'CutBookkeepersAux.' in persistent_instances):
 
  647                             aux = persistent_instances[
'CutBookkeepersAux.']
 
  648                         elif key == 
'CutBookkeepersAux.':
 
  650                         elif (key == 
'FileMetaData' 
  651                             and 'FileMetaDataAux.' in persistent_instances):
 
  652                             aux = persistent_instances[
'FileMetaDataAux.']
 
  653                         elif (key == 
'xAOD::FileMetaData_v1_FileMetaData' 
  654                             and 'xAOD::FileMetaDataAuxInfo_v1_FileMetaDataAux.' in persistent_instances):
 
  655                             aux = persistent_instances[
'xAOD::FileMetaDataAuxInfo_v1_FileMetaDataAux.']
 
  656                         elif (key == 
'TruthMetaData' 
  657                             and 'TruthMetaDataAux.' in persistent_instances):
 
  658                             aux = persistent_instances[
'TruthMetaDataAux.']
 
  659                         elif key == 
'TruthMetaDataAux.':
 
  661                         elif 'Menu' in key 
and key.endswith(
'Aux.'):
 
  666                         if 'TriggerMenuJson' in key  
or (
'TriggerMenu' in key 
and not has_r3_trig_meta):
 
  667                             if 'RAWTriggerMenuJson' in return_obj:
 
  668                                 meta_dict[filename][key] = return_obj[
'RAWTriggerMenuJson']
 
  669                                 del return_obj[
'RAWTriggerMenuJson']
 
  670                             if 'TriggerConfigInfo' not in meta_dict[filename]:
 
  671                                 meta_dict[filename][
'TriggerConfigInfo'] = {}
 
  672                             if 'dbkey' in return_obj:
 
  673                                 meta_dict[filename][
'TriggerConfigInfo'][key.split(
'_')[-1]] = {
 
  674                                     'key' : return_obj[
'dbkey'],
 
  675                                     'name': return_obj[
'name']
 
  677                                 del return_obj[
'dbkey']
 
  678                                 del return_obj[
'name']
 
  679                             if 'TriggerMenu' not in meta_dict[filename]:
 
  680                                 meta_dict[filename][
'TriggerMenu'] = {}
 
  681                             meta_dict[filename][
'TriggerMenu'].update(return_obj)
 
  682                         elif "FileMetaData" in key:
 
  683                             if "FileMetaData" not in meta_dict[filename]:
 
  684                                 meta_dict[filename][
"FileMetaData"] = dynamic_fmd_items
 
  685                             meta_dict[filename][
"FileMetaData"].update(return_obj)
 
  687                             meta_dict[filename][key] = return_obj
 
  691                 esi_dict = 
next(key 
for key, value 
in meta_dict[filename].
items()
 
  692                                 if isinstance(value, dict) 
and "numberOfEvents" in value 
and 
  693                                 meta_dict[filename][
"metadata_items"][key] == 
"EventStreamInfo")
 
  694                 msg.debug(f
"{esi_dict=}")
 
  695                 meta_dict[filename][
"nentries"] = meta_dict[filename][esi_dict][
"numberOfEvents"]
 
  696             except StopIteration 
as err:
 
  697                 msg.debug(f
"Caught {err=}, {type(err)=}, falling back on opening the DataHeader" 
  698                           " Container to read the number of entries")
 
  700                 msg.debug(f
"{meta_dict[filename]['nentries']=}")
 
  702             if unique_tag_info_values 
and mode==
'iov':
 
  703                 unique_tag_info_values = 
False 
  704                 msg.info(
'disabling "unique_tag_info_values" option for "iov" mode')
 
  711             if unique_tag_info_values:
 
  712                 msg.info(
'MetaReader is called with the parameter "unique_tag_info_values" set to True. ' 
  713                          'This is a workaround to remove all duplicate values from "/TagInfo" key')
 
  714                 if '/TagInfo' in meta_dict[filename]:
 
  715                     for key, value 
in meta_dict[filename][
'/TagInfo'].
items():
 
  716                         if isinstance(value, list) 
and value:
 
  717                             if len(unique_values := 
set(value)) > 1:
 
  719                                     f
"Found multiple values for {key}: {value}. " 
  720                                     "Looking for possible duplicates." 
  725                                     unique_amitags = 
set()
 
  726                                     for amitags 
in unique_values:
 
  728                                             "_".
join({tag 
for tag 
in amitags.split(
"_") 
if tag})
 
  730                                     if len(unique_amitags) == 1:
 
  732                                 elif key == 
"beam_energy":
 
  734                                     unique_energies = 
set()
 
  735                                     for energy 
in unique_values:
 
  740                                                 energy = 
float(energy)
 
  743                                         unique_energies.add(energy)
 
  744                                     if len(unique_energies) == 1:
 
  746                                 elif key 
in [
"AtlasRelease", 
"IOVDbGlobalTag", 
"AODFixVersion"]:
 
  750                                         f
"Multiple values for {key} may mean the same, or " 
  751                                         "the input file was produced in multi-step job. " 
  752                                         f
"Ignoring all but the first entry: {key} = {value[0]}" 
  756                                         f
"{key} from /TagInfo contains more than 1 unique value: {value}" 
  759                             meta_dict[filename][
'/TagInfo'][key] = value[0]
 
  762                 promote = mode == 
'lite' or mode == 
'peeker' 
  776                 if isinstance(collectionTree, ROOT.TTree):
 
  777                     meta_dict[filename][
'itemList'] = [ (b.GetClassName(), b.GetName()) 
for b 
in collectionTree.GetListOfBranches() ]
 
  780         elif current_file_type == 
'BS':
 
  782             if ignoreNonExistingLocalFiles 
and not regex_URI_scheme.match(filename) 
and not os.path.isfile(filename): 
 
  783                 msg.warn(
'Ignoring not accessible file: {}'.
format(filename))
 
  789             bs = eformat.istream(filename)
 
  790             meta_dict[filename][
'nentries'] = bs.total_events
 
  793             data_reader = eformat.EventStorage.pickDataReader(filename)
 
  794             assert data_reader, 
'problem picking a data reader for file [%s]' % filename
 
  797             meta_dict[filename][
'auto_flush'] = 1
 
  799             if hasattr(data_reader, 
'GUID'):
 
  800                 meta_dict[filename][
'file_guid'] = data_reader.GUID()
 
  803             meta_dict[filename][
'file_comp_alg'] = 1
 
  804             meta_dict[filename][
'file_comp_level'] = 1
 
  812                 for md 
in data_reader.freeMetaDataStrings():
 
  813                     if md.startswith(
'Event type:'):
 
  817                             v.append(
'IS_SIMULATION')
 
  824                             v.append(
'IS_TESTBEAM')
 
  826                         if 'is physics' in md:
 
  827                             v.append(
'IS_PHYSICS')
 
  829                             v.append(
'IS_CALIBRATION')
 
  831                         bs_metadata[k] = tuple(v)
 
  833                     elif md.startswith(
'GeoAtlas:'):
 
  835                         v = md.split(
'GeoAtlas:')[1].strip()
 
  838                     elif md.startswith(
'IOVDbGlobalTag:'):
 
  840                         v = md.split(
'IOVDbGlobalTag:')[1].strip()
 
  847                 bs_metadata[
'detectorMask'] = data_reader.detectorMask()
 
  848                 bs_metadata[
'runNumbers'] = data_reader.runNumber()
 
  849                 bs_metadata[
'lumiBlockNumbers'] = data_reader.lumiblockNumber()
 
  850                 bs_metadata[
'projectTag'] = data_reader.projectTag()
 
  851                 bs_metadata[
'stream'] = data_reader.stream()
 
  853                 beamTypeNbr= data_reader.beamType()
 
  858                 if (beamTypeNbr==0): bs_metadata[
'beamType'] = 
'cosmics' 
  859                 elif (beamTypeNbr==1 
or beamTypeNbr==2):  bs_metadata[
'beamType'] = 
'collisions' 
  860                 else: bs_metadata[
'beamType'] = 
'unknown' 
  862                 bs_metadata[
'beamEnergy'] = data_reader.beamEnergy()
 
  864                 meta_dict[filename][
'eventTypes'] = bs_metadata.get(
'eventTypes', [])
 
  865                 meta_dict[filename][
'GeoAtlas'] = bs_metadata.get(
'geometry', 
None)
 
  866                 meta_dict[filename][
'conditions_tag'] = bs_metadata.get(
'conditions_tag', 
None)
 
  867                 meta_dict[filename][
'project_name'] = bs_metadata.get(
'projectTag', 
None)
 
  870                 meta_dict[filename][
'detectorMask'] = [bs_metadata.get(
'detectorMask', 
None)]
 
  871                 meta_dict[filename][
'runNumbers'] = [bs_metadata.get(
'runNumbers', 
None)]
 
  872                 meta_dict[filename][
'lumiBlockNumbers'] = [bs_metadata.get(
'lumiBlockNumbers', 
None)]
 
  873                 meta_dict[filename][
'beam_type'] = bs_metadata.get(
'beamType', 
None)
 
  874                 meta_dict[filename][
'beam_energy'] = bs_metadata.get(
'beamEnergy', 
None)
 
  875                 meta_dict[filename][
'stream'] = bs_metadata.get(
'stream', 
None)
 
  877                 if not data_reader.good():
 
  879                     meta_dict[filename][
'runNumbers'].
append(bs_metadata.get(
'run_number', 0))
 
  880                     meta_dict[filename][
'lumiBlockNumbers'].
append(bs_metadata.get(
'LumiBlock', 0))
 
  882                 msg.debug(f
"{meta_dict[filename]=}")
 
  883                 msg.debug(f
"{len(bs)=}")
 
  888                         meta_dict[filename][
'processingTags'] = [tag.name 
for tag 
in evt.stream_tag()]
 
  889                         meta_dict[filename][
'evt_number'] = [evt.global_id()]
 
  890                         meta_dict[filename][
'run_type'] = [eformat.helper.run_type2string(evt.run_type())]
 
  893                         if meta_dict[filename][
'lumiBlockNumbers'] == [0]:
 
  894                             msg.debug(
'Taking the luminosity block info from the first event (%i)', evt.lumi_block())
 
  895                             meta_dict[filename][
'lumiBlockNumbers'] = [evt.lumi_block()]
 
  898                         if meta_dict[filename][
'runNumbers'] == [0]:
 
  899                             msg.debug(
'Taking the run number info from the first event (%i)', evt.run_no())
 
  900                             meta_dict[filename][
'runNumbers'] = [evt.run_no()]
 
  901                     except RuntimeError 
as err:
 
  902                         msg.error(
"Issue while reading the first event of BS file %r: %r", filename, err)
 
  904                         msg.debug(f
"{meta_dict[filename]=}")
 
  906                     msg.warn(f
"Event-less BS {filename=}, will not read metadata information from the first event")
 
  909                 if len(bs_metadata.get(
'eventTypes', 
'')) == 0:  
 
  910                     evt_type = [
'IS_DATA', 
'IS_ATLAS']
 
  911                     if bs_metadata.get(
'stream', 
'').startswith(
'physics_'):
 
  912                         evt_type.append(
'IS_PHYSICS')
 
  913                     elif bs_metadata.get(
'stream', 
'').startswith(
'calibration_'):
 
  914                         evt_type.append(
'IS_CALIBRATION')
 
  915                     elif bs_metadata.get(
'projectTag', 
'').endswith(
'_calib'):
 
  916                         evt_type.append(
'IS_CALIBRATION')
 
  918                         evt_type.append(
'Unknown')
 
  920                     meta_dict[filename][
'eventTypes'] = evt_type
 
  923                     meta_dict[filename][
'bs_metadata'] = bs_metadata
 
  927             msg.error(
'Unknown filetype for {0} - there is no metadata interface for type {1}'.
format(filename, current_file_type))
 
  935     if 'AthSimulation_DIR' in os.environ:
 
  936         return 'AthSimulation' 
  937     if 'AthGeneration_DIR' in os.environ:
 
  938         return 'AthGeneration' 
  944     Extract the actual filename if LFN or PFN notation is used 
  950         import subprocess, os
 
  951         os.environ[
'POOL_OUTMSG_LEVEL'] = 
'Error' 
  952         output = subprocess.check_output([
'FClistPFN',
'-l',filename[4:]],text=
True).
split(
'\n')
 
  955         msg.error( 
'FClistPFN({0}) returned unexpected number of lines:'.
format(filename) )
 
  956         msg.error( 
'\n'.
join(output) )
 
  962     Extracts the "guid" (Globally Unique Identifier) in POOL files and Grid catalogs) value from a POOL file. 
  963     :param filename: the input file 
  964     :return: the guid value, None if unavailable 
  967     root_file = ROOT.TFile.Open( 
_get_pfn(filename) )
 
  968     params = root_file.Get(
'##Params')
 
  970         from ROOT 
import RNTuple 
as rnt
 
  972         from ROOT.Experimental 
import RNTuple 
as rnt
 
  975     if not isinstance(params, ROOT.TTree) 
and not isinstance(params, rnt) 
and not isinstance(params, ROOT.TDirectory):
 
  976         raise NotImplementedError(f
"Cannot extract GUID from object {params!r} of type {type(params)!r}")
 
  978     regex = re.compile(
r'\[NAME=(\w+)\]\[VALUE=(.*)\]', re.ASCII)
 
  981     if isinstance(params, ROOT.TTree):
 
  983             param = entry.GetLeaf(
'db_string').GetValueString()
 
  984             result = regex.match(param)
 
  985             if result 
and result.group(1) == 
'FID' :
 
  987                 fid = result.group(2)
 
  988     elif isinstance(params, rnt):
 
  990             from ROOT 
import RNTupleReader
 
  992             from ROOT.Experimental 
import RNTupleReader
 
  993         reader = RNTupleReader.Open(params)
 
  995             entry = reader.CreateEntry()
 
  996         except AttributeError:
 
  997             entry = reader.GetModel().CreateEntry()
 
  998         for idx 
in range(reader.GetNEntries()):
 
  999             reader.LoadEntry(idx, entry)
 
 1001                 result = regex.match(
str(entry[
'db_string']))
 
 1002             except (AttributeError, TypeError) 
as err:
 
 1005                 msg.error(f
"Cannot read FID from ##Params in RNTuple w/ ROOT error: {err}")
 
 1007             if result 
and result.group(1) == 
'FID' :
 
 1009                 fid = result.group(2)
 
 1010     elif isinstance(params, ROOT.TDirectory):
 
 1011         for key 
in params.GetListOfKeys():
 
 1012             param = params.Get(key.GetName())
 
 1013             result = regex.match(
str(param))
 
 1014             if result 
and result.group(1) == 
'FID' :
 
 1016                 fid = result.group(2)
 
 1024     for meth 
in dir(obj):
 
 1025         if not meth.startswith(
'_'):
 
 1026             if meth.startswith(
'm_'):
 
 1028                 field_name = 
str(meth)[2:]
 
 1029                 field_value = getattr(obj, meth)
 
 1038     if hasattr(cl, 
'__cpp_name__'):
 
 1039         result = regex_cppname.match(cl.__cpp_name__)
 
 1041             cpp_type = result.group(1)
 
 1042             if cpp_type == 
'vector' or cpp_type == 
'std::vector':
 
 1044             elif cpp_type == 
'set' or cpp_type == 
'std::set':
 
 1046             elif cpp_type == 
'pair' or cpp_type == 
'std::pair':
 
 1052             elif cpp_type == 
'string' or cpp_type == 
'std::string':
 
 1055             elif cl.__cpp_name__ == 
"_Bit_reference":
 
 1059             elif cl.__cpp_name__ == 
'IOVMetaDataContainer_p1':
 
 1062             elif cl.__cpp_name__ == 
'IOVPayloadContainer_p1':
 
 1064                 if _gbl_mode == 
'iov':
 
 1069             elif cl.__cpp_name__ == 
'xAOD::EventFormat_v1':
 
 1071             elif cl.__cpp_name__ == 
'xAOD::CutBookkeeperContainer_v1':
 
 1073             elif cl.__cpp_name__ == 
'xAOD::FileMetaData_v1':
 
 1075             elif cl.__cpp_name__ == 
'DataVector<xAOD::TruthMetaData_v1>':
 
 1078             elif cl.__cpp_name__ == 
'DataVector<xAOD::TriggerMenu_v1>' :
 
 1081             elif cl.__cpp_name__ == 
'DataVector<xAOD::TriggerMenuJson_v1>' :
 
 1084             elif (cl.__cpp_name__ == 
'EventStreamInfo_p1' or 
 1085                   cl.__cpp_name__ == 
'EventStreamInfo_p2' or 
 1086                   cl.__cpp_name__ == 
'EventStreamInfo_p3'):
 
 1089             elif (cl.__cpp_name__ == 
'EventType_p1' or 
 1090                   cl.__cpp_name__ == 
'EventType_p3'):
 
 1096             elif regex_persistent_class.match(cl.__cpp_name__):
 
 1103     type_idx = attr_idx.typeIndex()
 
 1104     obj_idx = attr_idx.objIndex()
 
 1109         attr_value = 
bool(iov_container.m_bool[obj_idx])
 
 1111         attr_value = 
int(iov_container.m_char[obj_idx])
 
 1113         attr_value = 
int(iov_container.m_unsignedChar[obj_idx])
 
 1115         attr_value = 
int(iov_container.m_short[obj_idx])
 
 1117         attr_value = 
int(iov_container.m_unsignedShort[obj_idx])
 
 1119         attr_value = 
int(iov_container.m_int[obj_idx])
 
 1121         attr_value = 
int(iov_container.m_unsignedInt[obj_idx])
 
 1123         attr_value = 
int(iov_container.m_long[obj_idx])
 
 1125         attr_value = 
int(iov_container.m_unsignedLong[obj_idx])
 
 1127         attr_value = 
int(iov_container.m_longLong[obj_idx])
 
 1128     elif type_idx == 10:
 
 1129         attr_value = 
int(iov_container.m_unsignedLongLong[obj_idx])
 
 1130     elif type_idx == 11:
 
 1131         attr_value = 
float(iov_container.m_float[obj_idx])
 
 1132     elif type_idx == 12:
 
 1133         attr_value = 
float(iov_container.m_double[obj_idx])
 
 1134     elif type_idx == 13:
 
 1137     elif type_idx == 14:
 
 1138         attr_value = 
str(iov_container.m_string[obj_idx])
 
 1140         if attr_value.startswith(
'IOVMetaDataContainer_p1_'):
 
 1141             attr_value = attr_value.replace(
'IOVMetaDataContainer_p1_', 
'')
 
 1142         if attr_value.startswith(
'_'):
 
 1143             attr_value = attr_value.replace(
'_', 
'/')
 
 1145     elif type_idx == 15:
 
 1146         attr_value = 
int(iov_container.m_date[obj_idx])
 
 1147     elif type_idx == 16:
 
 1148         attr_value = 
int(iov_container.m_timeStamp[obj_idx])
 
 1150         raise ValueError(
'Unknown type id {0} for attribute {1}'.
format(type_idx, attr_name))
 
 1158      for idx 
in idx_range:
 
 1159          attr_idx = iov_container.m_attrIndexes[idx]
 
 1160          name_idx = attr_idx.nameIndex()
 
 1161          attr_name = iov_container.m_attrName[name_idx]
 
 1164          if attr_name 
not in result:
 
 1165              result[attr_name] = [attr_value]
 
 1167              result[attr_name].
append(attr_value)
 
 1169      max_element_count = 0
 
 1170      for content 
in result.values():
 
 1171          if len(content) > max_element_count:
 
 1172              max_element_count = len(content)
 
 1174      if max_element_count <= 1:
 
 1175          for name, content 
in result.items():
 
 1176              if len(content) > 0:
 
 1177                  result[name] = content[0]
 
 1187         return "({h}:{l})".
format(h=t>>32, l=t&(2^32-1))
 
 1189     def extract_list_collection(iov_container, listCollection ):
 
 1192         for list 
in listCollection.m_attrLists:
 
 1194             lname = 
'List {ln}: iov=[{s} ,{e}];  Channel#={ch}'.
format(
 
 1195                 ln=ln, s=iovtostr(list.m_range.m_start),
 
 1196                 e=iovtostr(list.m_range.m_stop),
 
 1197                 ch=list.m_channelNumber )
 
 1203     for listCollection 
in iov_container.m_payloadVec:
 
 1205         pname = 
'IOV range {n}: [{s}, {e}]'.
format(n=pn, s=iovtostr(listCollection.m_start),
 
 1206                                                    e=iovtostr(listCollection.m_stop))
 
 1207         result[ pname ] = extract_list_collection(iov_container, listCollection )
 
 1218     result[
'eventTypes'] = []
 
 1219     for eventType 
in value.m_eventTypes:
 
 1222     result[
'numberOfEvents'] = value.m_numberOfEvents
 
 1223     result[
'runNumbers'] = 
list(value.m_runNumbers)
 
 1224     result[
'lumiBlockNumbers'] = 
list(value.m_lumiBlockNumbers)
 
 1225     result[
'processingTags'] = [
str(v) 
for v 
in value.m_processingTags]
 
 1226     result[
'itemList'] = []
 
 1229     from CLIDComps.clidGenerator 
import clidGenerator
 
 1230     cgen = clidGenerator(
"")
 
 1231     for clid, sgkey 
in value.m_itemList:
 
 1232         if isinstance(sgkey, bytes):
 
 1233             sgkey = sgkey.decode()
 
 1234         result[
'itemList'].
append((cgen.getNameFromClid(clid), sgkey))
 
 1242     for ef_element 
in value:
 
 1243         result[ef_element.first] = ef_element.second.className()
 
 1249     """Extract CutBookkeeper content into dictionary 
 1251     This function takes the CutBookkeeperContainer_v1 and CutBookkeeperAuxContainer_v1 objects. 
 1252     It makes sure the the interface object uses the auxiliary object as store. 
 1254             interface (CutBookkeeperContainer_v1):     the interface class 
 1255             aux       (CutBookkeeperAuxContainer_v1):  auxiliary container object 
 1257             dict: with the cycle number and last stream 
 1259     if not interface 
or not aux:
 
 1261     interface.setStore(aux)
 
 1266     for cbk 
in interface:
 
 1267         current_cycle = 
int(cbk.cycle())
 
 1268         if current_cycle > max_cycle:
 
 1269             max_cycle = current_cycle
 
 1270             input_stream = 
str(cbk.inputStream())
 
 1273         'currentCutCycle': max_cycle,
 
 1274         'currentCutInputStream': input_stream,
 
 1280     """Turn static FileMetaData content into dictionary 
 1282     This function takes the FileMetaData_v1 and FileMetaDataAuxInfo_v1 objects. 
 1283     It makes sure the the interface object uses the auxiliary object as store. 
 1284     Next the two static variables of FileMetaDataAuxInfo_v1 are retrieved and 
 1285     added to the dictionary that is returned. 
 1287             interface (FileMetaData_v1):        the interface class 
 1288             aux       (FileMetaDataAuxInfo_v1): auxiliary container object 
 1290             dict: with the production release and dataType 
 1293     if not interface 
or not aux:
 
 1295     interface.setStore(aux)
 
 1297         "productionRelease": ROOT.std.string(),
 
 1298         "dataType": ROOT.std.string(),
 
 1299         "runNumbers": ROOT.std.vector(
'unsigned int')(),
 
 1300         "lumiBlocks": ROOT.std.vector(
'unsigned int')(),
 
 1303     for k, v 
in metaContent.items():
 
 1305             interface.value(getattr(interface, k), v)
 
 1306         except AttributeError:
 
 1307             interface.value(k, v)
 
 1309     result = {k: 
str(v) 
for k, v 
in metaContent.items() 
if type(v) 
is ROOT.std.string}
 
 1310     result.update({k: 
list(v) 
for k, v 
in metaContent.items() 
if type(v) 
is ROOT.std.vector(
'unsigned int')})
 
 1316     BadAuxVarException = ROOT.SG.ExcBadAuxVar
 
 1317     """Extract TruthMetaData content into dictionary 
 1319     This function takes the TruthMetaDataContainer_v1 and TruthMetaDataAuxContainer_v1 objects. 
 1320     It makes sure the the interface object uses the auxiliary object as store. 
 1322             interface (TruthMetaDataContainer_v1):     the interface class 
 1323             aux       (TruthMetaDataAuxContainer_v1):  auxiliary container object 
 1327     if not interface 
or not aux:
 
 1329     interface.setStore(aux)
 
 1333     for tmd 
in interface:
 
 1334         result[
'mcChannelNumber'] = tmd.mcChannelNumber()
 
 1337             result[
'weightNames'] = 
list(tmd.weightNames())
 
 1338         except BadAuxVarException:
 
 1339             result[
'weightNames'] = []
 
 1342             result[
'lhefGenerator'] = 
str(tmd.lhefGenerator())
 
 1343         except BadAuxVarException:
 
 1344             result[
'lhefGenerator'] = 
'' 
 1347             result[
'generators'] = 
str(tmd.generators())
 
 1348         except BadAuxVarException:
 
 1349             result[
'generators'] = 
'' 
 1352             result[
'evgenProcess'] = 
str(tmd.evgenProcess())
 
 1353         except BadAuxVarException:
 
 1354             result[
'evgenProcess'] = 
'' 
 1357             result[
'evgenTune'] = 
str(tmd.evgenTune())
 
 1358         except BadAuxVarException:
 
 1359             result[
'evgenTune'] = 
'' 
 1362             result[
'hardPDF'] = 
str(tmd.hardPDF())
 
 1363         except BadAuxVarException:
 
 1364             result[
'hardPDF'] = 
'' 
 1367             result[
'softPDF'] = 
str(tmd.softPDF())
 
 1368         except BadAuxVarException:
 
 1369             result[
'softPDF'] = 
'' 
 1374 """ Note: Deprecated. Legacy support for Run 2 AODs produced in release 21 or in release 22 prior to April 2021 
 1384         interface.setStore( aux )
 
 1385         if interface.size() > 0:
 
 1388             firstMenu = interface.at(0)
 
 1389             L1Items   = [ 
_convert_value(item) 
for item 
in firstMenu.itemNames() ]
 
 1390             HLTChains = [ 
_convert_value(chain) 
for chain 
in firstMenu.chainNames() ]
 
 1391     except Exception 
as err: 
 
 1392         msg.warn(
'Problem reading xAOD::TriggerMenu:')
 
 1395     result[
'L1Items'] = L1Items
 
 1396     result[
'HLTChains'] = HLTChains
 
 1404         interface.setStore( aux )
 
 1405         if interface.size() > 0:
 
 1408             firstMenu = interface.at(0)
 
 1410             decoded = json.loads(firstMenu.payload())
 
 1411             result[
'RAWTriggerMenuJson'] = firstMenu.payload()
 
 1412             result[
'name'] = firstMenu.name()
 
 1413             result[
'dbkey'] = firstMenu.key()
 
 1414             if decoded[
'filetype'] == 
'hltmenu':
 
 1415                 result[
'HLTChains'] = [ 
_convert_value(chain) 
for chain 
in decoded[
'chains'] ] 
 
 1416             elif decoded[
'filetype'] == 
'l1menu':
 
 1417                 result[
'L1Items'] = [ 
_convert_value(item) 
for item 
in decoded[
'items'] ] 
 
 1418             elif decoded[
'filetype'] 
in [
'bunchgroupset', 
'hltprescale', 
'l1prescale', 
'hltmonitoringsummary']:
 
 1422                 msg.warn(
'Got an xAOD::TriggerMenuJson called {0} but only expecting hltmenu or l1menu'.
format(decoded[
'filetype']))
 
 1425     except Exception 
as err: 
 
 1426         msg.warn(
'Problem reading xAOD::TriggerMenuJson')
 
 1431     if 'user_type' in value:
 
 1432         items = value[
'user_type'].
split(
'#')[3:]
 
 1433         for i 
in range(0, len(items), 2):
 
 1441         if key == 
'bit_mask':
 
 1444             bitmask_length = len(val)
 
 1446             is_simulation = 
False 
 1448             is_calibration = 
False 
 1450             if bitmask_length > 0:  
 
 1451                 is_simulation = val[0]
 
 1453             if bitmask_length > 1:  
 
 1454                 is_testbeam = val[1]
 
 1456             if bitmask_length > 2:  
 
 1457                 is_calibration = val[2]
 
 1460                 'IS_SIMULATION' if is_simulation 
else 'IS_DATA',
 
 1461                 'IS_TESTBEAM' if is_testbeam 
else 'IS_ATLAS',
 
 1462                 'IS_CALIBRATION' if is_calibration 
else 'IS_PHYSICS' 
 1465     value[
'type'] = types
 
 1470     for filename, file_content 
in meta_dict.items():
 
 1471         for key 
in file_content:
 
 1472             if key 
in meta_dict[filename][
'metadata_items'] 
and regexEventStreamInfo.match(meta_dict[filename][
'metadata_items'][key]):
 
 1473                 for item 
in list(meta_dict[filename][key]):
 
 1474                     if item 
not in lite_primary_keys_to_keep:
 
 1475                         meta_dict[filename][key].pop(item)
 
 1477         if '/TagInfo' in file_content:
 
 1480             for item 
in list(meta_dict[filename][
'/TagInfo']):
 
 1481                 if item 
not in lite_TagInfo_keys_to_keep:
 
 1482                     meta_dict[filename][
'/TagInfo'].pop(item)
 
 1487     for filename, file_content 
in meta_dict.items():
 
 1488         for key 
in file_content:
 
 1489             if key 
in meta_dict[filename][
'metadata_items'] 
and regexEventStreamInfo.match(meta_dict[filename][
'metadata_items'][key]):
 
 1494                     'mc_channel_number',
 
 1499                 for item 
in list(meta_dict[filename][key]):
 
 1500                     if item 
not in keys_to_keep:
 
 1501                         meta_dict[filename][key].pop(item)
 
 1503         if '/TagInfo' in file_content:
 
 1512                 'triggerStreamOfFile',
 
 1514                 'specialConfiguration',
 
 1521             for item 
in list(meta_dict[filename][
'/TagInfo']):
 
 1522                 if item 
not in keys_to_keep:
 
 1523                     meta_dict[filename][
'/TagInfo'].pop(item)
 
 1525         if '/Simulation/Parameters' in file_content:
 
 1530                 'RegenerationIncrement',
 
 1532                 'SimulationFlavour',
 
 1535                 'SimulatedDetectors',
 
 1538             for item 
in list(meta_dict[filename][
'/Simulation/Parameters']):
 
 1539                 if item 
not in keys_to_keep:
 
 1540                     meta_dict[filename][
'/Simulation/Parameters'].pop(item)
 
 1542         if '/Digitization/Parameters' in file_content:
 
 1544                 'numberOfCollisions',
 
 1545                 'intraTrainBunchSpacing',
 
 1546                 'BeamIntensityPattern' 
 1550                 'DigitizedDetectors',
 
 1552             for item 
in list(meta_dict[filename][
'/Digitization/Parameters']):
 
 1553                 if item 
not in keys_to_keep:
 
 1554                     meta_dict[filename][
'/Digitization/Parameters'].pop(item)
 
 1556         if 'CutBookkeepers' in file_content:
 
 1559                 'currentCutInputStream',
 
 1561             for item 
in list(meta_dict[filename][
'CutBookkeepers']):
 
 1562                 if item 
not in keys_to_keep:
 
 1563                     meta_dict[filename][
'CutBookkeepers'].pop(item)
 
 1565         if 'TruthMetaData' in file_content:
 
 1570             for item 
in list(meta_dict[filename][
'TruthMetaData']):
 
 1571                 if item 
not in keys_to_keep:
 
 1572                     meta_dict[filename][
'TruthMetaData'].pop(item)
 
 1578     for filename, file_content 
in meta_dict.items():
 
 1579         md = meta_dict[filename]
 
 1580         for key 
in file_content:
 
 1581             if key 
in md[
'metadata_items'] 
and regexEventStreamInfo.match(md[
'metadata_items'][key]):
 
 1584                 if 'eventTypes' in md 
and len(md[
'eventTypes']):
 
 1585                     et = md[
'eventTypes'][0]
 
 1586                     md[
'mc_event_number'] = et.get(
'mc_event_number', md[
'runNumbers'][0])
 
 1587                     if 'mc_channel_number' in et:
 
 1588                         md[
'mc_channel_number'] = et.get(
'mc_channel_number', 
None)
 
 1589                     md[
'eventTypes'] = et[
'type']
 
 1592                     if 'GeoAtlas' in et:
 
 1593                         md[
'GeoAtlas']       = et.get(
'GeoAtlas', 
None)
 
 1594                     if 'IOVDbGlobalTag' in et:
 
 1595                         md[
'IOVDbGlobalTag'] = et.get(
'IOVDbGlobalTag', 
None)
 
 1597                 if 'lumiBlockNumbers' in md[key]:
 
 1598                     md[
'lumiBlockNumbers'] = md[key][
'lumiBlockNumbers']
 
 1600                 if 'processingTags' in md[key]:
 
 1601                     md[
'processingTags'] = md[key][
'processingTags']
 
 1603                 meta_dict[filename].pop(key)
 
 1606             if not isGaudiEnv() 
and key 
in md[
'metadata_items'] 
and 'FileMetaData' in key:
 
 1607                 if 'beamType' in md[key]:
 
 1608                     md[
'beam_type'] = md[key][
'beamType']
 
 1610                 if 'runNumbers' in md[key]:
 
 1611                     md[
'runNumbers'] = md[key][
'runNumbers']
 
 1613                 if 'mcProcID' in md[key]:
 
 1614                     md[
'mc_channel_number'] = 
int(md[key][
'mcProcID'])
 
 1616                 if 'mcCampaign' in md[key]:
 
 1617                     md[
'mc_campaign'] = md[key][
'mcCampaign']
 
 1619                 if 'dataYear' in md[key]:
 
 1620                     md[
'data_year'] = 
int(md[key][
'dataYear'])
 
 1622                 if 'lumiBlocks' in md[key]:
 
 1623                     md[
'lumiBlockNumbers'] = md[key][
'lumiBlocks']
 
 1625                 if mode == 
'peeker' and 'amiTag' in md[key]:
 
 1626                     md[
'AMITag'] = md[key][
'amiTag']
 
 1628                 if 'beamEnergy' in md[key]:
 
 1629                     md[
'beam_energy'] = 
int(md[key][
'beamEnergy'])
 
 1631                 if 'geometryVersion' in md[key]:
 
 1632                     md[
'GeoAtlas'] = md[key][
'geometryVersion']
 
 1635                 md[
'eventTypes'] = []
 
 1636                 if mode == 
'peeker' and 'simFlavour' in md[key]:
 
 1637                     md[
'SimulationFlavour'] = md[key][
'simFlavour']
 
 1639                 if mode == 
'peeker' and 'isDataOverlay' in md[key]:
 
 1640                     md[
'IsDataOverlay'] = md[key][
'isDataOverlay']
 
 1642                 if 'dataType' in md[key]:
 
 1643                     md[
'processingTags'] = [md[key][
'dataType']]
 
 1646                     (
'simFlavour' in md[key] 
and (
'FullG4' in md[key][
'simFlavour'] 
or 'ATLFAST' in md[key][
'simFlavour']))
 
 1647                     or 'DAOD_TRUTH' in md[key][
'dataType']
 
 1649                     md[
'eventTypes'].
append(
'IS_SIMULATION')
 
 1651                     md[
'eventTypes'].
append(
'IS_DATA')
 
 1654                     'GeoAtlas' in md 
and 'ATLAS' in md[
'GeoAtlas']
 
 1655                     or 'DAOD_TRUTH' in md[key][
'dataType']
 
 1657                     md[
'eventTypes'].
append(
'IS_ATLAS')
 
 1659                     md[
'eventTypes'].
append(
'IS_PHYSICS')
 
 1661                     md[
'eventTypes'].
append(
'IS_TESTBEAM')
 
 1663                 if mode == 
'peeker':
 
 1664                     if 'productionRelease' in md[key]:
 
 1665                         md[
'AtlasRelease'] = md[key][
'productionRelease']
 
 1667                     if 'generatorsInfo' in md[key]:
 
 1668                         md[
'generators']  = md[key][
'generatorsInfo']
 
 1671                     meta_dict[filename].pop(key)
 
 1674         if '/TagInfo' in file_content:
 
 1675             md.update(md[
'/TagInfo'])
 
 1678         if '/Generation/Parameters' in file_content:
 
 1679             md.update(md[
'/Generation/Parameters'])
 
 1680             md.pop(
'/Generation/Parameters')
 
 1682         if '/Simulation/Parameters' in file_content:
 
 1683             md.update(md[
'/Simulation/Parameters'])
 
 1684             md.pop(
'/Simulation/Parameters')
 
 1686         if '/Digitization/Parameters' in file_content:
 
 1687             md.update(md[
'/Digitization/Parameters'])
 
 1688             md.pop(
'/Digitization/Parameters')
 
 1690         if 'CutBookkeepers' in file_content:
 
 1691             md.update(md[
'CutBookkeepers'])
 
 1692             md.pop(
'CutBookkeepers')
 
 1699     This function will rearrange the itemList values to match the format of 'eventdata_items', 'eventdata_itemsList' 
 1700     or 'eventdata_itemsDic' generated with the legacy file peeker tool 
 1701     :param metadata: a dictionary obtained using read_metadata method. 
 1702                      The mode for read_metadata must be 'peeker of 'full' 
 1703     :param layout: the mode in which the data will be converted: 
 1704                 * for 'eventdata_items' use: layout= None 
 1705                 * for 'eventdata_itemsList' use: layout= '#join' 
 1706                 * for 'eventdata_itemsDic' use: layout= 'dict' 
 1712     if 'itemList' in metadata:
 
 1713         item_list = metadata[
'itemList']
 
 1718         for key 
in metadata:
 
 1719             if 'metadata_items' in metadata 
and key 
in metadata[
'metadata_items'] 
and metadata[
'metadata_items'][key] == 
'EventStreamInfo_p3':
 
 1722         if current_key 
is not None:
 
 1723             item_list = metadata[current_key][
'itemList']
 
 1725     if item_list 
is not None:
 
 1730         elif layout == 
'#join':
 
 1731             return [k + 
'#' + v 
for k, v 
in item_list 
if k]
 
 1734         elif layout == 
'dict':
 
 1735             from collections 
import defaultdict
 
 1736             dic = defaultdict(list)
 
 1738             for k, v 
in item_list:
 
 1745     """Extract number of entries from DataHeader. 
 1747     infile  ROOT TFile object or filename string 
 1748     return  Number of entries as returned by DataHeader object in infile, 
 1749             None in absence of DataHeader object 
 1752     from PyUtils.PoolFile 
import PoolOpts
 
 1753     if not isinstance(infile, ROOT.TFile):
 
 1754         infile = ROOT.TFile.Open(infile)
 
 1756     for name 
in {PoolOpts.TTreeNames.DataHeader, PoolOpts.RNTupleNames.DataHeader}:
 
 1757         obj = infile.Get(name)
 
 1758         msg.debug(f
"dataheader_nentries: {name=}, {obj=}, {type(obj)=}")
 
 1761         if isinstance(obj, ROOT.TTree):
 
 1762             return obj.GetEntriesFast()
 
 1765             if ROOT.gROOT.GetVersionInt() < 63100:
 
 1766                 raise RuntimeError(
"ROOT ver. 6.31/01 or greater needed to read RNTuple files")
 
 1769                     return ROOT.Experimental.RNTupleReader.Open(obj).GetNEntries()
 
 1770                 except AttributeError:
 
 1771                     return ROOT.RNTupleReader.Open(obj).GetNEntries()
 
 1773                 raise NotImplementedError(f
"Keys of type {type(obj)!r} not supported")
 
 1776     """Return a dictionary of metadata filters based on the mode and 
 1777     optional meta_key_filter. 
 1780     if meta_key_filter 
is None:
 
 1781         meta_key_filter = []
 
 1790                 '/TagInfo': 
'IOVMetaDataContainer_p1',
 
 1791                 'IOVMetaDataContainer_p1__TagInfo': 
'IOVMetaDataContainer_p1',
 
 1792                 '*': 
'EventStreamInfo_p*' 
 1796                 'FileMetaData': 
'*',
 
 1797                 'FileMetaDataAux.': 
'xAOD::FileMetaDataAuxInfo_v1',
 
 1801     if mode == 
'peeker':
 
 1802         meta_filter.update({
 
 1803             'TriggerMenu': 
'DataVector<xAOD::TriggerMenu_v1>', 
 
 1804             'TriggerMenuAux.': 
'xAOD::TriggerMenuAuxContainer_v1',
 
 1805             'DataVector<xAOD::TriggerMenu_v1>_TriggerMenu': 
'DataVector<xAOD::TriggerMenu_v1>', 
 
 1806             'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.': 
'xAOD::TriggerMenuAuxContainer_v1',
 
 1807             'TriggerMenuJson_HLT': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1808             'TriggerMenuJson_HLTAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1809             'TriggerMenuJson_HLTMonitoring': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1810             'TriggerMenuJson_HLTMonitoringAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1811             'TriggerMenuJson_HLTPS': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1812             'TriggerMenuJson_HLTPSAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1813             'TriggerMenuJson_L1': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1814             'TriggerMenuJson_L1Aux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1815             'TriggerMenuJson_L1PS': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1816             'TriggerMenuJson_L1PSAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1817             'CutBookkeepers': 
'xAOD::CutBookkeeperContainer_v1',
 
 1818             'CutBookkeepersAux.': 
'xAOD::CutBookkeeperAuxContainer_v1',
 
 1819             'FileMetaData': 
'*',
 
 1820             'FileMetaDataAux.': 
'xAOD::FileMetaDataAuxInfo_v1',
 
 1821             'TruthMetaData': 
'*',
 
 1822             'TruthMetaDataAux.': 
'xAOD::TruthMetaDataAuxContainer_v1',
 
 1823             'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1824             'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1825             'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTMonitoring': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1826             'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTMonitoringAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1827             'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTPS': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1828             'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTPSAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1829             'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1830             'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_L1Aux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1',
 
 1831             'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1PS': 
'DataVector<xAOD::TriggerMenuJson_v1>', 
 
 1832             'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_L1PSAux.': 
'xAOD::TriggerMenuJsonAuxContainer_v1' 
 1836             meta_filter.update({
 
 1837                 '/TagInfo': 
'IOVMetaDataContainer_p1',
 
 1838                 'IOVMetaDataContainer_p1__TagInfo': 
'IOVMetaDataContainer_p1',
 
 1839                 '/Simulation/Parameters': 
'IOVMetaDataContainer_p1',
 
 1840                 '/Digitization/Parameters': 
'IOVMetaDataContainer_p1',
 
 1841                 '/EXT/DCS/MAGNETS/SENSORDATA': 
'IOVMetaDataContainer_p1',
 
 1842                 '*': 
'EventStreamInfo_p*' 
 1845     if (mode == 
'full' or mode == 
'iov') 
and meta_key_filter:
 
 1846         meta_filter = {f: 
'*' for f 
in meta_key_filter}
 
 1852     Convert canonical/C++ STL types in the metadata_items dictionary back to their 
 1853     ROOT equivalents for backward compatibility. 
 1854     - 'float' => 'Float_t' 
 1855     - 'char' => 'Char_t' 
 1856     - 'std::string' => 'string' 
 1857     - 'xAOD::FileMetaData_v1' => 'FileMetaData' 
 1858     - 'xAOD::FileMetaDataAuxInfo_v1' => 'FileMetaDataAux' 
 1859     (add more as needed) 
 1864         "std::string": 
"string",
 
 1865         "std::uint32_t": 
"UInt_t",
 
 1866         "xAOD::FileMetaData_v1": 
"FileMetaData",
 
 1869     for k, v 
in metadata_dict.items():
 
 1871         for old, new 
in type_map.items():
 
 1874             elif new_v.endswith(
"." + old):
 
 1875                 new_v = new_v.rsplit(
".", 1)[0] + 
"." + new
 
 1876         denormalized[k] = new_v
 
 1882     Helper function to determine if metadata should be kept based on meta_filter. 
 1884     if len(meta_filter) == 0:
 
 1887     for filter_key, filter_class 
in meta_filter.items():
 
 1889             filter_key.replace(
"/", 
"_") 
in normalizedName.replace(
"/", 
"_")
 
 1890             or filter_key == 
"*" 
 1891         ) 
and fnmatchcase(typeName, filter_class):
 
 1892             if "CutBookkeepers" in filter_key:
 
 1893                 keep = filter_key == normalizedName