70def 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.
82 global _gbl_mode, _gbl_run
86 from RootUtils
import PyROOTFixes
89 if isinstance(filenames, str):
90 filenames = [filenames]
93 if file_type
is not None:
94 if file_type
not in (
'POOL',
'BS'):
95 raise NameError(
'Allowed values for \'file_type\' parameter are: "POOL" or "BS": you provided "' + file_type +
'"')
97 msg.info(
'Forced file_type: {0}'.format(file_type))
100 if mode
not in (
'tiny',
'lite',
'full',
'peeker',
'iov'):
101 raise NameError(
'Allowed values for "mode" parameter are: "tiny", "lite", "peeker", "iov" or "full"')
103 if meta_key_filter
is None:
108 if mode
in (
'full',
'iov'):
109 raise NameError(
'The following modes are not available in AnalysisBase: "iov" and "full"')
111 msg.info(
'Current mode used: {0}'.format(mode))
112 msg.info(
'Current filenames: {0}'.format(filenames))
114 if mode !=
'full' and mode !=
'iov' and len(meta_key_filter) > 0:
115 raise NameError(
'It is possible to use the meta_key_filter option only for full mode')
117 msg.info(
'Filter used: {0}'.format(meta_key_filter))
123 for filename
in filenames:
124 meta_dict[filename] = {}
125 current_file_type =
None
130 if os.path.isfile(filename):
132 if ignoreNonExistingLocalFiles
and not regex_URI_scheme.match(filename)
and gSystem.AccessPathName(filename):
133 msg.warning(
'Ignoring not accessible file: {}'.format(filename))
136 with open(filename,
'rb')
as binary_file:
137 magic_file = binary_file.read(4)
139 if magic_file ==
'root' or magic_file == b
'root':
140 current_file_type =
'POOL'
141 meta_dict[filename][
'file_type'] =
'POOL'
143 elif Project.determine()
in (
144 Project.AnalysisBase, Project.AthAnalysis):
146 f
"{filename} is not a ROOT file, assumed bytestream"
147 ", this is not supported in Analysis releases")
149 current_file_type =
'BS'
150 meta_dict[filename][
'file_type'] =
'BS'
153 meta_dict[filename][
'file_size'] = os.path.getsize(filename)
157 if regex_BS_files.match(filename):
158 current_file_type =
'BS'
159 meta_dict[filename][
'file_type'] =
'BS'
161 current_file_type =
'POOL'
162 meta_dict[filename][
'file_type'] =
'POOL'
165 meta_dict[filename][
'file_size'] =
None
168 current_file_type = file_type
171 if current_file_type ==
'POOL':
173 if ignoreNonExistingLocalFiles
and not regex_URI_scheme.match(filename)
and gSystem.AccessPathName(filename):
174 msg.warning(
'Ignoring not accessible file: {}'.format(filename))
179 current_file = ROOT.TFile.Open(
_get_pfn(filename) )
182 from PyUtils.PoolFile
import PoolOpts
183 collectionTree = current_file.Get(PoolOpts.TTreeNames.EventData)
184 if isinstance(collectionTree, ROOT.TTree):
185 meta_dict[filename][
'auto_flush'] = collectionTree.GetAutoFlush()
188 meta_dict[filename][
'file_guid'] =
_read_guid(filename)
191 meta_dict[filename][
'file_comp_alg'] = current_file.GetCompressionAlgorithm()
192 meta_dict[filename][
'file_comp_level'] = current_file.GetCompressionLevel()
195 isRNTuple(md:=current_file.Get(PoolOpts.RNTupleNames.MetaData))
199 "Reading in-file metadata from RNTuple is currently of limited support"
201 meta_dict[filename][
"metadata_items"] = {}
204 from ROOT
import RNTupleReader
206 from ROOT.Experimental
import RNTupleReader
208 reader = RNTupleReader.Open(md)
209 entry = reader.CreateEntry()
210 reader.LoadEntry(0, entry)
213 "xAOD::FileMetaData_v1",
214 "xAOD::FileMetaDataAuxInfo_v1",
215 "xAOD::TriggerMenuJsonAuxContainer_v1",
216 "DataVector<xAOD::TriggerMenuJson_v1>",
217 "xAOD::TruthMetaDataAuxContainer_v1",
218 "DataVector<xAOD::TruthMetaData_v1>",
219 "xAOD::CutBookkeeperContainer_v1",
220 "xAOD::CutBookkeeperAuxContainer_v1",
221 "xAOD::LumiBlockRangeAuxContainer_v1",
222 "DataVector<xAOD::LumiBlockRange_v1>",
225 dynamic_fmd_items = {}
229 for field
in reader.GetDescriptor().GetTopLevelFields():
230 normalizedName = field.GetFieldName()
231 if "index_ref" in normalizedName:
233 if regexIOVMetaDataContainer.match(field.GetTypeName()):
238 .
replace(
"IOVMetaDataContainer_p1_",
"")
241 meta_dict[filename][
"metadata_items"][normalizedName] = (
242 "IOVMetaDataContainer"
244 elif regexByteStreamMetadataContainer.match(field.GetTypeName()):
245 meta_dict[filename][
"metadata_items"][field.GetFieldName()] = (
246 "ByteStreamMetadataContainer"
248 elif regexEventStreamInfo.match(field.GetTypeName()):
249 meta_dict[filename][
"metadata_items"][field.GetFieldName()] = (
252 elif regexXAODFileMetaData.match(field.GetTypeName()):
253 meta_dict[filename][
"metadata_items"][
254 field.GetFieldName().
replace(
"xAOD__",
"xAOD::")
255 ] = field.GetTypeName()
256 elif regexXAODFileMetaDataAuxDyn.match(
257 normalizedName := field.GetFieldName()
263 if entry[field.GetFieldName()] ==
"\x00"
264 else entry[field.GetFieldName()]
266 dynamic_fmd_items[normalizedName.split(
".")[1]] = result
267 meta_dict[filename][
"metadata_items"][normalizedName] = (
271 elif regexXAODFileMetaDataAux.match(field.GetTypeName()):
272 meta_dict[filename][
"metadata_items"][
276 ] = field.GetTypeName()
277 elif regexXAODTruthMetaData.match(field.GetTypeName()):
278 meta_dict[filename][
"metadata_items"][
281 .
replace(
"DataVector_",
"DataVector<")
284 elif regexXAODTruthMetaDataAux.match(field.GetTypeName()):
285 meta_dict[filename][
"metadata_items"][
289 ] = field.GetTypeName()
290 elif regexXAODEventFormat.match(field.GetTypeName()):
291 meta_dict[filename][
"metadata_items"][
292 field.GetFieldName().
replace(
"xAOD__",
"xAOD::")
293 ] = field.GetTypeName()
294 elif regexXAODTriggerMenuJson.match(field.GetTypeName()):
295 meta_dict[filename][
"metadata_items"][
298 .
replace(
"DataVector_",
"DataVector<")
299 .
replace(
"__Trigger",
">_Trigger")
300 ] = field.GetTypeName()
301 elif regexXAODTriggerMenuJsonAux.match(field.GetTypeName()):
302 meta_dict[filename][
"metadata_items"][
306 ] = field.GetTypeName()
307 elif regexXAODCutBookkeeperContainer.match(field.GetTypeName()):
308 meta_dict[filename][
"metadata_items"][
311 .
replace(
"DataVector_",
"DataVector<")
312 .
replace(
"__CutBookkeeper",
">_CutBookkeeper")
313 ] = field.GetTypeName()
314 elif regexXAODCutBookkeeperContainerAux.match(field.GetTypeName()):
315 meta_dict[filename][
"metadata_items"][
319 ] = field.GetTypeName()
321 meta_dict[filename][
"metadata_items"][
322 field.GetFieldName().
replace(
"Aux:",
"Aux.")
323 ] = field.GetTypeName()
325 if field.GetTypeName()
in classes_with_aux:
327 auxes[field.GetFieldName()] = field.GetTypeName()
331 normalizedName, field.GetTypeName(), meta_filter
337 entry[field.GetFieldName()]
340 msg.warning(f
"missing type {field.GetTypeName()}")
343 meta_dict[filename][
"metadata_items"]
346 def _get_aux_base(aux_key: str) -> str:
349 key = key.replace(
"xAOD__TriggerMenuJsonAuxContainer_v1_",
"")
350 key = key.replace(
"xAOD__FileMetaDataAuxInfo_v1_",
"")
351 key = key.replace(
"xAOD__TruthMetaDataAuxContainer_v1_",
"")
353 if key.endswith(
"Aux:"):
355 elif key.endswith(
"Aux"):
358 key = key.strip(
"_:")
361 def _get_main_base(main_key: str) -> str:
364 if main_key.startswith(
"DataVector_xAOD__TriggerMenuJson_v1__"):
365 main_base = main_key.replace(
366 "DataVector_xAOD__TriggerMenuJson_v1__",
""
369 elif main_key.startswith(
"xAOD__FileMetaData_v1_"):
370 main_base = main_key.replace(
"xAOD__FileMetaData_v1_",
"")
372 elif main_key.startswith(
"DataVector_xAOD__TruthMetaData_v1__"):
373 main_base = main_key.replace(
374 "DataVector_xAOD__TruthMetaData_v1__",
""
378 def _find_associated_pairs(auxes: dict) -> list[tuple[str, str]]:
383 aux_map[_get_aux_base(k)] = k
387 base = _get_main_base(k)
393 for base, aux_key
in aux_map.items():
395 pairs.append((aux_key, main_map[base]))
398 for pair
in _find_associated_pairs(auxes):
406 for k, v
in trigger_menu_json_map.items()
410 .
replace(
"DataVector_",
"DataVector<")
411 .
replace(
"__Trigger",
">_Trigger")
418 key.replace(
"xAOD__",
"xAOD::")
419 if key.count(
"_") <= 1
420 else key.replace(
"xAOD__",
"xAOD::").rsplit(
"_", 2)[0]
428 .
replace(
"DataVector_",
"DataVector<")
429 .
replace(
"__Trigger",
">_Trigger")
436 if "TriggerMenuJson" in pair[0]:
437 if "RAWTriggerMenuJson" in return_obj:
440 if pair[0].startswith(
"Trigger")
441 else trigger_menu_json_map[pair[0]]
443 meta_dict[filename][key] = return_obj[
"RAWTriggerMenuJson"]
444 del return_obj[
"RAWTriggerMenuJson"]
445 if "TriggerConfigInfo" not in meta_dict[filename]:
446 meta_dict[filename][
"TriggerConfigInfo"] = {}
447 if "dbkey" in return_obj:
448 meta_dict[filename][
"TriggerConfigInfo"][
450 ] = {
"key": return_obj[
"dbkey"],
"name": return_obj[
"name"]}
451 del return_obj[
"dbkey"]
452 del return_obj[
"name"]
453 if "TriggerMenu" not in meta_dict[filename]:
454 meta_dict[filename][
"TriggerMenu"] = {}
455 meta_dict[filename][
"TriggerMenu"].update(return_obj)
456 elif "FileMetaData" in pair[0]:
457 if "FileMetaData" not in meta_dict[filename]:
458 meta_dict[filename][
"FileMetaData"] = dynamic_fmd_items
459 meta_dict[filename][
"FileMetaData"].update(return_obj)
460 elif "TruthMetaData" in pair[0]:
461 if pair == (
"TruthMetaDataAux:",
"TruthMetaData"):
462 if "TruthMetaData" not in meta_dict[filename]:
463 meta_dict[filename][
"TruthMetaData"] = {}
464 meta_dict[filename][
"TruthMetaData"].update(return_obj)
470 .
replace(
"DataVector_",
"DataVector<")
478 elif pair == (
"CutBookkeepersAux:",
"CutBookkeepers"):
479 meta_dict[filename][
"CutBookkeepers"] = return_obj
481 msg.debug(f
"Read metadata from RNTuple: {meta_dict[filename]}")
487 metadata_tree = current_file.Get(
'MetaData')
489 metadata_branches = metadata_tree.GetListOfBranches()
490 nr_of_branches = metadata_branches.GetEntriesFast()
493 meta_dict[filename][
'metadata_items'] = {}
498 persistent_instances = {}
499 dynamic_fmd_items = {}
503 metadata_tree.SetBranchStatus(
"*",
False)
505 for i
in range(0, nr_of_branches):
506 branch = metadata_branches.At(i)
507 name = branch.GetName()
508 if name ==
'index_ref':
512 class_name = branch.GetClassName()
514 if regexIOVMetaDataContainer.match(class_name):
515 name = name.replace(
'IOVMetaDataContainer_p1_',
'').
replace(
'_',
'/')
517 if regexIOVMetaDataContainer.match(class_name):
518 meta_dict[filename][
'metadata_items'][name] =
'IOVMetaDataContainer'
519 elif regexByteStreamMetadataContainer.match(class_name):
520 meta_dict[filename][
'metadata_items'][name] =
'ByteStreamMetadataContainer'
521 elif regexEventStreamInfo.match(class_name):
522 meta_dict[filename][
'metadata_items'][name] =
'EventStreamInfo'
523 elif regexXAODFileMetaData.match(class_name):
524 meta_dict[filename][
'metadata_items'][name] =
'FileMetaData'
525 elif regexXAODTruthMetaData.match(class_name):
526 meta_dict[filename][
'metadata_items'][name] =
'TruthMetaData'
528 type_name = class_name
531 type_name = branch.GetListOfLeaves()[0].GetTypeName()
534 meta_dict[filename][
'metadata_items'][name] = type_name
536 if len(meta_filter) > 0:
538 for filter_key, filter_class
in meta_filter.items():
539 if (filter_key.replace(
'/',
'_')
in name.replace(
'/',
'_')
or filter_key ==
'*')
and fnmatchcase(class_name, filter_class):
540 if 'CutBookkeepers' in filter_key:
541 keep = filter_key == name
552 if 'CutBookkeepers' in name
and name
not in [
'CutBookkeepers',
'CutBookkeepersAux.']:
556 metadata_tree.SetBranchStatus(f
"{name}*",
True)
559 if regexEventStreamInfo.match(class_name):
560 if class_name.endswith(
'_p1'):
561 persistent_instances[name] = ROOT.EventStreamInfo_p1()
562 elif class_name.endswith(
'_p2'):
563 persistent_instances[name] = ROOT.EventStreamInfo_p2()
565 persistent_instances[name] = ROOT.EventStreamInfo_p3()
566 elif regexIOVMetaDataContainer.match(class_name):
567 persistent_instances[name] = ROOT.IOVMetaDataContainer_p1()
568 elif regexXAODEventFormat.match(class_name):
569 persistent_instances[name] = ROOT.xAOD.EventFormat_v1()
570 elif regexXAODTriggerMenu.match(class_name)
and _check_project()
not in [
'AthGeneration']:
571 persistent_instances[name] = ROOT.xAOD.TriggerMenuContainer_v1()
572 elif regexXAODTriggerMenuAux.match(class_name)
and _check_project()
not in [
'AthGeneration']:
573 persistent_instances[name] = ROOT.xAOD.TriggerMenuAuxContainer_v1()
574 elif regexXAODTriggerMenuJson.match(class_name)
and _check_project()
not in [
'AthGeneration']:
575 persistent_instances[name] = ROOT.xAOD.TriggerMenuJsonContainer_v1()
576 elif regexXAODTriggerMenuJsonAux.match(class_name)
and _check_project()
not in [
'AthGeneration']:
577 persistent_instances[name] = ROOT.xAOD.TriggerMenuJsonAuxContainer_v1()
578 elif regexXAODCutBookkeeperContainer.match(class_name):
579 persistent_instances[name] = ROOT.xAOD.CutBookkeeperContainer_v1()
580 elif regexXAODCutBookkeeperContainerAux.match(class_name):
581 persistent_instances[name] = ROOT.xAOD.CutBookkeeperAuxContainer_v1()
582 elif regexXAODFileMetaData.match(class_name):
583 persistent_instances[name] = ROOT.xAOD.FileMetaData_v1()
584 elif regexXAODFileMetaDataAux.match(class_name):
585 persistent_instances[name] = ROOT.xAOD.FileMetaDataAuxInfo_v1()
586 elif regexXAODTruthMetaData.match(class_name):
587 persistent_instances[name] = ROOT.xAOD.TruthMetaDataContainer_v1()
588 elif regexXAODTruthMetaDataAux.match(class_name):
589 persistent_instances[name] = ROOT.xAOD.TruthMetaDataAuxContainer_v1()
591 if name
in persistent_instances:
592 branch.SetAddress(ROOT.AddressOf(persistent_instances[name]))
595 dynamicFMD = regexXAODFileMetaDataAuxDyn.match(name)
597 dynamicName = dynamicFMD.group().
split(
'.')[-1]
598 dynamicType = regex_cppname.match(class_name)
601 dynamic_fmd_items[dynamicName] = ROOT.std.string()
602 branch.SetAddress(ROOT.AddressOf(dynamic_fmd_items[dynamicName]))
604 dynamic_fmd_items[dynamicName] =
None
607 metadata_tree.GetEntry(0)
610 for key
in dynamic_fmd_items:
611 if dynamic_fmd_items[key]
is None:
613 if key.startswith(
"is"):
615 dynamic_fmd_items[key] = getattr(metadata_tree, key) !=
'\x00'
618 dynamic_fmd_items[key] = getattr(metadata_tree, key)
619 except AttributeError:
624 dynamic_fmd_items[key] = str(dynamic_fmd_items[key])
628 meta_dict[filename] = {}
631 for key, obj
in persistent_instances.items():
632 if key.startswith(
'EventStreamInfo'):
634 if data
and 'runNumbers' in data
and len(data[
'runNumbers']) == 1:
635 _gbl_run = data[
'runNumbers'][0]
636 msg.debug(
"Found RunNumber in EventStreamInfo: %d", _gbl_run)
639 for name, content
in persistent_instances.items():
641 if hasattr(content,
'm_folderName'):
642 key = content.m_folderName
645 has_r3_trig_meta = (
'TriggerMenuJson_HLT' in persistent_instances
or 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT' in persistent_instances)
647 if key.startswith(
'TriggerMenuJson_')
and not key.endswith(
'Aux.'):
648 aux = persistent_instances[key+
'Aux.']
649 elif key.startswith(
'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_')
and not key.endswith(
'Aux.'):
650 menuPart = key.split(
'_')[-1]
651 aux = persistent_instances[
'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_'+menuPart+
'Aux.']
652 elif key ==
'TriggerMenu' and 'TriggerMenuAux.' in persistent_instances
and not has_r3_trig_meta:
653 aux = persistent_instances[
'TriggerMenuAux.']
654 elif key ==
'DataVector<xAOD::TriggerMenu_v1>_TriggerMenu' and 'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.' in persistent_instances
and not has_r3_trig_meta:
655 aux = persistent_instances[
'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.']
656 elif (key ==
'CutBookkeepers'
657 and 'CutBookkeepersAux.' in persistent_instances):
658 aux = persistent_instances[
'CutBookkeepersAux.']
659 elif key ==
'CutBookkeepersAux.':
661 elif (key ==
'FileMetaData'
662 and 'FileMetaDataAux.' in persistent_instances):
663 aux = persistent_instances[
'FileMetaDataAux.']
664 elif (key ==
'xAOD::FileMetaData_v1_FileMetaData'
665 and 'xAOD::FileMetaDataAuxInfo_v1_FileMetaDataAux.' in persistent_instances):
666 aux = persistent_instances[
'xAOD::FileMetaDataAuxInfo_v1_FileMetaDataAux.']
667 elif (key ==
'TruthMetaData'
668 and 'TruthMetaDataAux.' in persistent_instances):
669 aux = persistent_instances[
'TruthMetaDataAux.']
670 elif key ==
'TruthMetaDataAux.':
672 elif 'Menu' in key
and key.endswith(
'Aux.'):
677 if 'TriggerMenuJson' in key
or (
'TriggerMenu' in key
and not has_r3_trig_meta):
678 if 'RAWTriggerMenuJson' in return_obj:
679 meta_dict[filename][key] = return_obj[
'RAWTriggerMenuJson']
680 del return_obj[
'RAWTriggerMenuJson']
681 if 'TriggerConfigInfo' not in meta_dict[filename]:
682 meta_dict[filename][
'TriggerConfigInfo'] = {}
683 if 'dbkey' in return_obj:
684 meta_dict[filename][
'TriggerConfigInfo'][key.split(
'_')[-1]] = {
685 'key' : return_obj[
'dbkey'],
686 'name': return_obj[
'name']
688 del return_obj[
'dbkey']
689 del return_obj[
'name']
690 if 'TriggerMenu' not in meta_dict[filename]:
691 meta_dict[filename][
'TriggerMenu'] = {}
692 meta_dict[filename][
'TriggerMenu'].update(return_obj)
693 elif "FileMetaData" in key:
694 if "FileMetaData" not in meta_dict[filename]:
695 meta_dict[filename][
"FileMetaData"] = dynamic_fmd_items
696 meta_dict[filename][
"FileMetaData"].update(return_obj)
698 meta_dict[filename][key] = return_obj
702 esi_dict = next(key
for key, value
in meta_dict[filename].items()
703 if isinstance(value, dict)
and "numberOfEvents" in value
and
704 meta_dict[filename][
"metadata_items"][key] ==
"EventStreamInfo")
705 msg.debug(f
"{esi_dict=}")
706 meta_dict[filename][
"nentries"] = meta_dict[filename][esi_dict][
"numberOfEvents"]
707 except StopIteration
as err:
708 msg.debug(f
"Caught {err=}, {type(err)=}, falling back on opening the DataHeader"
709 " Container to read the number of entries")
711 msg.debug(f
"{meta_dict[filename]['nentries']=}")
713 if unique_tag_info_values
and mode==
'iov':
714 unique_tag_info_values =
False
715 msg.info(
'disabling "unique_tag_info_values" option for "iov" mode')
722 if unique_tag_info_values:
723 msg.info(
'MetaReader is called with the parameter "unique_tag_info_values" set to True. '
724 'This is a workaround to remove all duplicate values from "/TagInfo" key')
725 if '/TagInfo' in meta_dict[filename]:
726 for key, value
in meta_dict[filename][
'/TagInfo'].items():
727 if isinstance(value, list)
and value:
728 if len(unique_values :=
set(value)) > 1:
730 f
"Found multiple values for {key}: {value}. "
731 "Looking for possible duplicates."
736 unique_amitags =
set()
737 for amitags
in unique_values:
739 "_".join([tag
for tag
in amitags.split(
"_")
if tag])
744 for atag
in unique_amitags:
745 if any(atag+
'_' in x
for x
in unique_amitags
if x != atag):
746 parent_tags += [atag]
747 for atag
in parent_tags:
749 if len(unique_amitags)>1:
750 msg.warning(f
"Removing parent AMI tag {atag}")
751 unique_amitags.remove(atag)
752 if len(unique_amitags) == 1:
755 value.insert(0,list(unique_amitags)[0])
756 elif key ==
"beam_energy":
758 unique_energies =
set()
759 for energy
in unique_values:
764 energy = float(energy)
767 unique_energies.add(energy)
768 if len(unique_energies) == 1:
770 elif key
in [
"AtlasRelease",
"IOVDbGlobalTag",
"AODFixVersion"]:
774 f
"Multiple values for {key} may mean the same, or "
775 "the input file was produced in multi-step job. "
776 f
"Ignoring all but the first entry: {key} = {value[0]}"
780 f
"{key} from /TagInfo contains more than 1 unique value: {value}"
783 meta_dict[filename][
'/TagInfo'][key] = value[0]
786 promote = mode ==
'lite' or mode ==
'peeker'
800 if isinstance(collectionTree, ROOT.TTree):
801 meta_dict[filename][
'itemList'] = [ (b.GetClassName(), b.GetName())
for b
in collectionTree.GetListOfBranches() ]
804 elif current_file_type ==
'BS':
806 if ignoreNonExistingLocalFiles
and not regex_URI_scheme.match(filename)
and not os.path.isfile(filename):
807 msg.warning(
'Ignoring not accessible file: {}'.format(filename))
813 bs = eformat.istream(filename)
814 meta_dict[filename][
'nentries'] = bs.total_events
817 data_reader = eformat.EventStorage.pickDataReader(filename)
818 assert data_reader,
'problem picking a data reader for file [%s]' % filename
821 meta_dict[filename][
'auto_flush'] = 1
823 if hasattr(data_reader,
'GUID'):
824 meta_dict[filename][
'file_guid'] = data_reader.GUID()
827 meta_dict[filename][
'file_comp_alg'] = 1
828 meta_dict[filename][
'file_comp_level'] = 1
836 for md
in data_reader.freeMetaDataStrings():
837 if md.startswith(
'Event type:'):
841 v.append(
'IS_SIMULATION')
848 v.append(
'IS_TESTBEAM')
850 if 'is physics' in md:
851 v.append(
'IS_PHYSICS')
853 v.append(
'IS_CALIBRATION')
855 bs_metadata[k] = tuple(v)
857 elif md.startswith(
'GeoAtlas:'):
859 v = md.split(
'GeoAtlas:')[1].
strip()
862 elif md.startswith(
'IOVDbGlobalTag:'):
864 v = md.split(
'IOVDbGlobalTag:')[1].
strip()
868 k, v = md.split(
'=', 1)
871 bs_metadata[
'detectorMask'] = data_reader.detectorMask()
872 bs_metadata[
'runNumbers'] = data_reader.runNumber()
873 bs_metadata[
'lumiBlockNumbers'] = data_reader.lumiblockNumber()
874 bs_metadata[
'projectTag'] = data_reader.projectTag()
875 bs_metadata[
'stream'] = data_reader.stream()
877 beamTypeNbr= data_reader.beamType()
882 if (beamTypeNbr==0): bs_metadata[
'beamType'] =
'cosmics'
883 elif (beamTypeNbr==1
or beamTypeNbr==2): bs_metadata[
'beamType'] =
'collisions'
884 else: bs_metadata[
'beamType'] =
'unknown'
886 bs_metadata[
'beamEnergy'] = data_reader.beamEnergy()
888 meta_dict[filename][
'eventTypes'] = bs_metadata.get(
'eventTypes', [])
889 meta_dict[filename][
'GeoAtlas'] = bs_metadata.get(
'geometry',
None)
890 meta_dict[filename][
'conditions_tag'] = bs_metadata.get(
'conditions_tag',
None)
891 meta_dict[filename][
'project_name'] = bs_metadata.get(
'projectTag',
None)
894 meta_dict[filename][
'detectorMask'] = [bs_metadata.get(
'detectorMask',
None)]
895 meta_dict[filename][
'runNumbers'] = [bs_metadata.get(
'runNumbers',
None)]
896 meta_dict[filename][
'lumiBlockNumbers'] = [bs_metadata.get(
'lumiBlockNumbers',
None)]
897 meta_dict[filename][
'beam_type'] = bs_metadata.get(
'beamType',
None)
898 meta_dict[filename][
'beam_energy'] = bs_metadata.get(
'beamEnergy',
None)
899 meta_dict[filename][
'stream'] = bs_metadata.get(
'stream',
None)
901 if not data_reader.good():
903 meta_dict[filename][
'runNumbers'].append(bs_metadata.get(
'run_number', 0))
904 meta_dict[filename][
'lumiBlockNumbers'].append(bs_metadata.get(
'LumiBlock', 0))
906 msg.debug(f
"{meta_dict[filename]=}")
907 msg.debug(f
"{len(bs)=}")
912 meta_dict[filename][
'processingTags'] = [tag.name
for tag
in evt.stream_tag()]
913 meta_dict[filename][
'evt_number'] = [evt.global_id()]
914 meta_dict[filename][
'run_type'] = [eformat.helper.run_type2string(evt.run_type())]
917 if meta_dict[filename][
'lumiBlockNumbers'] == [0]:
918 msg.debug(
'Taking the luminosity block info from the first event (%i)', evt.lumi_block())
919 meta_dict[filename][
'lumiBlockNumbers'] = [evt.lumi_block()]
922 if meta_dict[filename][
'runNumbers'] == [0]:
923 msg.debug(
'Taking the run number info from the first event (%i)', evt.run_no())
924 meta_dict[filename][
'runNumbers'] = [evt.run_no()]
925 except RuntimeError
as err:
926 msg.error(
"Issue while reading the first event of BS file %r: %r", filename, err)
928 msg.debug(f
"{meta_dict[filename]=}")
930 msg.warning(f
"Event-less BS {filename=}, will not read metadata information from the first event")
933 if len(bs_metadata.get(
'eventTypes',
'')) == 0:
934 evt_type = [
'IS_DATA',
'IS_ATLAS']
935 if bs_metadata.get(
'stream',
'').startswith(
'physics_'):
936 evt_type.append(
'IS_PHYSICS')
937 elif bs_metadata.get(
'stream',
'').startswith(
'calibration_'):
938 evt_type.append(
'IS_CALIBRATION')
939 elif bs_metadata.get(
'projectTag',
'').endswith(
'_calib'):
940 evt_type.append(
'IS_CALIBRATION')
942 evt_type.append(
'Unknown')
944 meta_dict[filename][
'eventTypes'] = evt_type
947 meta_dict[filename][
'bs_metadata'] = bs_metadata
951 msg.error(
'Unknown filetype for {0} - there is no metadata interface for type {1}'.format(filename, current_file_type))