53 def read_metadata(filenames, file_type = None, mode = 'lite', promote = None, meta_key_filter = None,
54 unique_tag_info_values = True, ignoreNonExistingLocalFiles=False):
56 This tool is independent of Athena framework and returns the metadata from a given file.
57 :param filenames: the input file from which metadata needs to be extracted.
58 :param file_type: the type of file. POOL or BS (bytestream: RAW, DRAW) files.
59 :param mode: if true, will return all metadata associated with the filename. By default, is false and this will
60 return a "tiny" version which have only the following keys: 'file_guid', 'file_size', 'file_type', 'nentries'.
61 :return: a dictionary of metadata for the given input file.
68 from RootUtils
import PyROOTFixes
71 if isinstance(filenames, str):
72 filenames = [filenames]
75 if file_type
is not None:
76 if file_type
not in (
'POOL',
'BS'):
77 raise NameError(
'Allowed values for \'file_type\' parameter are: "POOL" or "BS": you provided "' + file_type +
'"')
79 msg.info(
'Forced file_type: {0}'.
format(file_type))
82 if mode
not in (
'tiny',
'lite',
'full',
'peeker',
'iov'):
83 raise NameError(
'Allowed values for "mode" parameter are: "tiny", "lite", "peeker", "iov" or "full"')
85 if meta_key_filter
is None:
90 if mode
in (
'full',
'iov'):
91 raise NameError(
'The following modes are not available in AnalysisBase: "iov" and "full"')
93 msg.info(
'Current mode used: {0}'.
format(mode))
94 msg.info(
'Current filenames: {0}'.
format(filenames))
96 if mode !=
'full' and mode !=
'iov' and len(meta_key_filter) > 0:
97 raise NameError(
'It is possible to use the meta_key_filter option only for full mode')
99 msg.info(
'Filter used: {0}'.
format(meta_key_filter))
105 for filename
in filenames:
106 meta_dict[filename] = {}
107 current_file_type =
None
110 if os.path.isfile(filename):
112 if ignoreNonExistingLocalFiles
and not regex_URI_scheme.match(filename)
and gSystem.AccessPathName(filename):
113 msg.warn(
'Ignoring not accessible file: {}'.
format(filename))
116 with open(filename,
'rb')
as binary_file:
117 magic_file = binary_file.read(4)
119 if magic_file ==
'root' or magic_file == b
'root':
120 current_file_type =
'POOL'
121 meta_dict[filename][
'file_type'] =
'POOL'
124 current_file_type =
'BS'
125 meta_dict[filename][
'file_type'] =
'BS'
128 meta_dict[filename][
'file_size'] = os.path.getsize(filename)
132 if regex_BS_files.match(filename):
133 current_file_type =
'BS'
134 meta_dict[filename][
'file_type'] =
'BS'
136 current_file_type =
'POOL'
137 meta_dict[filename][
'file_type'] =
'POOL'
140 meta_dict[filename][
'file_size'] =
None
143 current_file_type = file_type
146 if current_file_type ==
'POOL':
148 if ignoreNonExistingLocalFiles
and not regex_URI_scheme.match(filename)
and gSystem.AccessPathName(filename):
149 msg.warn(
'Ignoring not accessible file: {}'.
format(filename))
154 current_file = ROOT.TFile.Open(
_get_pfn(filename) )
157 from PyUtils.PoolFile
import PoolOpts
158 collectionTree = current_file.Get(PoolOpts.TTreeNames.EventData)
159 if isinstance(collectionTree, ROOT.TTree):
160 meta_dict[filename][
'auto_flush'] = collectionTree.GetAutoFlush()
163 meta_dict[filename][
'file_guid'] =
_read_guid(filename)
166 meta_dict[filename][
'file_comp_alg'] = current_file.GetCompressionAlgorithm()
167 meta_dict[filename][
'file_comp_level'] = current_file.GetCompressionLevel()
169 if isRNTuple( current_file.Get(PoolOpts.RNTupleNames.MetaData) ):
171 "Reading in-file metadata from RNTuple is currently of limited support"
175 def get_raw_md(filename):
176 """Helper function to read the raw metadata from RNTuple.
177 We use subprocess because output from RNTupleReader uses
178 std::ostream for output, which is not captured by PyROOT.
180 Returns the raw metadata as a json-like string, but one cannot
181 assume it is valid json.
183 Known issues of invalid json constructs:
184 - double quotes are not escaped in string values
185 - single-quoted strings
186 - nested json objects and lists inside single-quoted strings
192 from ROOT.Experimental import RNTupleReader
193 from ROOT import TFile
197 file_handle = TFile.Open(infile)
198 md = file_handle.Get("MetaData")
199 reader = RNTupleReader.Open(md)
202 read_md("{filename}")
204 result = subprocess.run(
205 [sys.executable,
"-c", raw_md],
209 raw_data =
"".
join(result.stdout.split())
210 return raw_data.replace(
"\x00",
'""')
212 def extract_keys(json_like_string, keys):
213 """Helper for extracting key-value pairs from json-like string"""
218 if key ==
"m_eventTypes":
219 pattern = rf
'"{key}":(\[\{{.*?\}}\])'
220 elif "beamEnergy" in key:
221 pattern = rf
'"{key}":(\b[+]?([0-9]*\.[0-9]+|[0-9]+\.?[0-9]*)[eE][+]?([0-9]+)\b)'
223 pattern = rf
'"{key}"\s*:\s*(\[[^\]]*\]|"[^"]*"|\d+)'
224 match = re.search(pattern, json_like_string)
227 result[key] = json.loads(match.group(1))
228 except json.JSONDecodeError:
236 "m_lumiBlockNumbers",
242 "FileMetaDataAuxDyn:amiTag",
243 "FileMetaDataAuxDyn:AODFixVersion",
244 "FileMetaDataAuxDyn:AODCalibVersion",
245 "FileMetaDataAuxDyn:beamEnergy",
246 "FileMetaDataAuxDyn:beamType",
247 "FileMetaDataAuxDyn:conditionsTag",
248 "FileMetaDataAuxDyn:dataYear",
249 "FileMetaDataAuxDyn:generatorsInfo",
250 "FileMetaDataAuxDyn:geometryVersion",
251 "FileMetaDataAuxDyn:isDataOverlay",
252 "FileMetaDataAuxDyn:mcCampaign",
253 "FileMetaDataAuxDyn:mcProcID",
254 "FileMetaDataAuxDyn:simFlavour",
259 result = extract_keys(get_raw_md(filename), keys_to_extract)
262 from CLIDComps.clidGenerator
import clidGenerator
264 cgen = clidGenerator(
"")
265 for item
in result[
"m_itemList"]:
266 item_list.append((cgen.getNameFromClid(item[
"_0"]), item[
"_1"].
encode(
"utf-8")))
267 meta_dict[filename][
"itemList"] = item_list
269 for event_type
in result[
"m_eventTypes"]:
271 key.removeprefix(
"m_"): value
272 for key, value
in event_type.items()
276 event_types.extend(fields[
"type"])
277 meta_dict[filename][
"eventTypes"] = event_types
278 meta_dict[filename][
"numberOfEvents"] = result[
"m_numberOfEvents"]
279 meta_dict[filename][
"runNumbers"] = result[
"m_runNumbers"]
280 meta_dict[filename][
"lumiBlockNumbers"] = result[
"m_lumiBlockNumbers"]
281 meta_dict[filename][
"processingTags"] = result[
"m_processingTags"]
283 meta_dict[filename][
"EventFormat"] = {}
285 for branch_name, class_name
in dict(
287 result[
"m_branchNames"],
288 result[
"m_classNames"],
291 ef_items[branch_name] = class_name
292 meta_dict[filename][
"EventFormat"] = ef_items
294 meta_dict[filename][
"FileMetaData"] = {}
295 for key
in keys_to_extract:
297 meta_dict[filename][
"FileMetaData"][key.split(
":")[1]] = (
300 except (IndexError, KeyError):
302 msg.debug(f
"Read metadata from RNTuple: {meta_dict[filename]}")
308 metadata_tree = current_file.Get(
'MetaData')
310 metadata_branches = metadata_tree.GetListOfBranches()
311 nr_of_branches = metadata_branches.GetEntriesFast()
314 meta_dict[filename][
'metadata_items'] = {}
323 '/TagInfo':
'IOVMetaDataContainer_p1',
324 'IOVMetaDataContainer_p1__TagInfo':
'IOVMetaDataContainer_p1',
325 '*':
'EventStreamInfo_p*'
330 'FileMetaDataAux.':
'xAOD::FileMetaDataAuxInfo_v1',
336 'TriggerMenu':
'DataVector<xAOD::TriggerMenu_v1>',
337 'TriggerMenuAux.':
'xAOD::TriggerMenuAuxContainer_v1',
338 'DataVector<xAOD::TriggerMenu_v1>_TriggerMenu':
'DataVector<xAOD::TriggerMenu_v1>',
339 'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.':
'xAOD::TriggerMenuAuxContainer_v1',
340 'TriggerMenuJson_HLT':
'DataVector<xAOD::TriggerMenuJson_v1>',
341 'TriggerMenuJson_HLTAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
342 'TriggerMenuJson_HLTMonitoring':
'DataVector<xAOD::TriggerMenuJson_v1>',
343 'TriggerMenuJson_HLTMonitoringAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
344 'TriggerMenuJson_HLTPS':
'DataVector<xAOD::TriggerMenuJson_v1>',
345 'TriggerMenuJson_HLTPSAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
346 'TriggerMenuJson_L1':
'DataVector<xAOD::TriggerMenuJson_v1>',
347 'TriggerMenuJson_L1Aux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
348 'TriggerMenuJson_L1PS':
'DataVector<xAOD::TriggerMenuJson_v1>',
349 'TriggerMenuJson_L1PSAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
350 'CutBookkeepers':
'xAOD::CutBookkeeperContainer_v1',
351 'CutBookkeepersAux.':
'xAOD::CutBookkeeperAuxContainer_v1',
353 'FileMetaDataAux.':
'xAOD::FileMetaDataAuxInfo_v1',
354 'TruthMetaData':
'*',
355 'TruthMetaDataAux.':
'xAOD::TruthMetaDataAuxContainer_v1',
356 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT':
'DataVector<xAOD::TriggerMenuJson_v1>',
357 'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
358 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTMonitoring':
'DataVector<xAOD::TriggerMenuJson_v1>',
359 'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTMonitoringAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
360 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLTPS':
'DataVector<xAOD::TriggerMenuJson_v1>',
361 'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_HLTPSAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
362 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1':
'DataVector<xAOD::TriggerMenuJson_v1>',
363 'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_L1Aux.':
'xAOD::TriggerMenuJsonAuxContainer_v1',
364 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_L1PS':
'DataVector<xAOD::TriggerMenuJson_v1>',
365 'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_L1PSAux.':
'xAOD::TriggerMenuJsonAuxContainer_v1'
370 '/TagInfo':
'IOVMetaDataContainer_p1',
371 'IOVMetaDataContainer_p1__TagInfo':
'IOVMetaDataContainer_p1',
372 '/Simulation/Parameters':
'IOVMetaDataContainer_p1',
373 '/Digitization/Parameters':
'IOVMetaDataContainer_p1',
374 '/EXT/DCS/MAGNETS/SENSORDATA':
'IOVMetaDataContainer_p1',
375 '*':
'EventStreamInfo_p*'
378 if (mode ==
'full' or mode ==
'iov')
and meta_key_filter:
379 meta_filter = {f:
'*' for f
in meta_key_filter}
381 persistent_instances = {}
382 dynamic_fmd_items = {}
386 metadata_tree.SetBranchStatus(
"*",
False)
388 for i
in range(0, nr_of_branches):
389 branch = metadata_branches.At(i)
390 name = branch.GetName()
391 if name ==
'index_ref':
395 class_name = branch.GetClassName()
397 if regexIOVMetaDataContainer.match(class_name):
398 name = name.replace(
'IOVMetaDataContainer_p1_',
'').
replace(
'_',
'/')
400 if regexIOVMetaDataContainer.match(class_name):
401 meta_dict[filename][
'metadata_items'][name] =
'IOVMetaDataContainer'
402 elif regexByteStreamMetadataContainer.match(class_name):
403 meta_dict[filename][
'metadata_items'][name] =
'ByteStreamMetadataContainer'
404 elif regexEventStreamInfo.match(class_name):
405 meta_dict[filename][
'metadata_items'][name] =
'EventStreamInfo'
406 elif regexXAODFileMetaData.match(class_name):
407 meta_dict[filename][
'metadata_items'][name] =
'FileMetaData'
408 elif regexXAODTruthMetaData.match(class_name):
409 meta_dict[filename][
'metadata_items'][name] =
'TruthMetaData'
411 type_name = class_name
414 type_name = branch.GetListOfLeaves()[0].GetTypeName()
417 meta_dict[filename][
'metadata_items'][name] = type_name
419 if len(meta_filter) > 0:
421 for filter_key, filter_class
in meta_filter.items():
422 if (filter_key.replace(
'/',
'_')
in name.replace(
'/',
'_')
or filter_key ==
'*')
and fnmatchcase(class_name, filter_class):
423 if 'CutBookkeepers' in filter_key:
424 keep = filter_key == name
435 if 'CutBookkeepers' in name
and name
not in [
'CutBookkeepers',
'CutBookkeepersAux.']:
439 metadata_tree.SetBranchStatus(f
"{name}*",
True)
442 if regexEventStreamInfo.match(class_name):
443 if class_name.endswith(
'_p1'):
444 persistent_instances[name] = ROOT.EventStreamInfo_p1()
445 elif class_name.endswith(
'_p2'):
446 persistent_instances[name] = ROOT.EventStreamInfo_p2()
448 persistent_instances[name] = ROOT.EventStreamInfo_p3()
449 elif regexIOVMetaDataContainer.match(class_name):
450 persistent_instances[name] = ROOT.IOVMetaDataContainer_p1()
451 elif regexXAODEventFormat.match(class_name):
452 persistent_instances[name] = ROOT.xAOD.EventFormat_v1()
453 elif regexXAODTriggerMenu.match(class_name)
and _check_project()
not in [
'AthGeneration']:
454 persistent_instances[name] = ROOT.xAOD.TriggerMenuContainer_v1()
455 elif regexXAODTriggerMenuAux.match(class_name)
and _check_project()
not in [
'AthGeneration']:
456 persistent_instances[name] = ROOT.xAOD.TriggerMenuAuxContainer_v1()
457 elif regexXAODTriggerMenuJson.match(class_name)
and _check_project()
not in [
'AthGeneration']:
458 persistent_instances[name] = ROOT.xAOD.TriggerMenuJsonContainer_v1()
459 elif regexXAODTriggerMenuJsonAux.match(class_name)
and _check_project()
not in [
'AthGeneration']:
460 persistent_instances[name] = ROOT.xAOD.TriggerMenuJsonAuxContainer_v1()
461 elif regexXAODCutBookkeeperContainer.match(class_name):
462 persistent_instances[name] = ROOT.xAOD.CutBookkeeperContainer_v1()
463 elif regexXAODCutBookkeeperContainerAux.match(class_name):
464 persistent_instances[name] = ROOT.xAOD.CutBookkeeperAuxContainer_v1()
465 elif regexXAODFileMetaData.match(class_name):
466 persistent_instances[name] = ROOT.xAOD.FileMetaData_v1()
467 elif regexXAODFileMetaDataAux.match(class_name):
468 persistent_instances[name] = ROOT.xAOD.FileMetaDataAuxInfo_v1()
469 elif regexXAODTruthMetaData.match(class_name):
470 persistent_instances[name] = ROOT.xAOD.TruthMetaDataContainer_v1()
471 elif regexXAODTruthMetaDataAux.match(class_name):
472 persistent_instances[name] = ROOT.xAOD.TruthMetaDataAuxContainer_v1()
474 if name
in persistent_instances:
475 branch.SetAddress(ROOT.AddressOf(persistent_instances[name]))
478 dynamicFMD = regexXAODFileMetaDataAuxDyn.match(name)
480 dynamicName = dynamicFMD.group().
split(
'.')[-1]
481 dynamicType = regex_cppname.match(class_name)
484 dynamic_fmd_items[dynamicName] = ROOT.std.string()
485 branch.SetAddress(ROOT.AddressOf(dynamic_fmd_items[dynamicName]))
487 dynamic_fmd_items[dynamicName] =
None
490 metadata_tree.GetEntry(0)
493 for key
in dynamic_fmd_items:
494 if dynamic_fmd_items[key]
is None:
496 if key.startswith(
"is"):
498 dynamic_fmd_items[key] = getattr(metadata_tree, key) !=
'\x00'
501 dynamic_fmd_items[key] = getattr(metadata_tree, key)
502 except AttributeError:
507 dynamic_fmd_items[key] =
str(dynamic_fmd_items[key])
511 meta_dict[filename] = {}
514 for name, content
in persistent_instances.items():
516 if hasattr(content,
'm_folderName'):
517 key = content.m_folderName
520 has_r3_trig_meta = (
'TriggerMenuJson_HLT' in persistent_instances
or 'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_HLT' in persistent_instances)
522 if key.startswith(
'TriggerMenuJson_')
and not key.endswith(
'Aux.'):
523 aux = persistent_instances[key+
'Aux.']
524 elif key.startswith(
'DataVector<xAOD::TriggerMenuJson_v1>_TriggerMenuJson_')
and not key.endswith(
'Aux.'):
525 menuPart = key.split(
'_')[-1]
526 aux = persistent_instances[
'xAOD::TriggerMenuJsonAuxContainer_v1_TriggerMenuJson_'+menuPart+
'Aux.']
527 elif key ==
'TriggerMenu' and 'TriggerMenuAux.' in persistent_instances
and not has_r3_trig_meta:
528 aux = persistent_instances[
'TriggerMenuAux.']
529 elif key ==
'DataVector<xAOD::TriggerMenu_v1>_TriggerMenu' and 'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.' in persistent_instances
and not has_r3_trig_meta:
530 aux = persistent_instances[
'xAOD::TriggerMenuAuxContainer_v1_TriggerMenuAux.']
531 elif (key ==
'CutBookkeepers'
532 and 'CutBookkeepersAux.' in persistent_instances):
533 aux = persistent_instances[
'CutBookkeepersAux.']
534 elif key ==
'CutBookkeepersAux.':
536 elif (key ==
'FileMetaData'
537 and 'FileMetaDataAux.' in persistent_instances):
538 aux = persistent_instances[
'FileMetaDataAux.']
539 elif (key ==
'xAOD::FileMetaData_v1_FileMetaData'
540 and 'xAOD::FileMetaDataAuxInfo_v1_FileMetaDataAux.' in persistent_instances):
541 aux = persistent_instances[
'xAOD::FileMetaDataAuxInfo_v1_FileMetaDataAux.']
542 elif (key ==
'TruthMetaData'
543 and 'TruthMetaDataAux.' in persistent_instances):
544 aux = persistent_instances[
'TruthMetaDataAux.']
545 elif key ==
'TruthMetaDataAux.':
547 elif 'Menu' in key
and key.endswith(
'Aux.'):
552 if 'TriggerMenuJson' in key
or (
'TriggerMenu' in key
and not has_r3_trig_meta):
553 if 'RAWTriggerMenuJson' in return_obj:
554 meta_dict[filename][key] = return_obj[
'RAWTriggerMenuJson']
555 del return_obj[
'RAWTriggerMenuJson']
556 if 'TriggerConfigInfo' not in meta_dict[filename]:
557 meta_dict[filename][
'TriggerConfigInfo'] = {}
558 if 'dbkey' in return_obj:
559 meta_dict[filename][
'TriggerConfigInfo'][key.split(
'_')[-1]] = {
560 'key' : return_obj[
'dbkey'],
561 'name': return_obj[
'name']
563 del return_obj[
'dbkey']
564 del return_obj[
'name']
565 if 'TriggerMenu' not in meta_dict[filename]:
566 meta_dict[filename][
'TriggerMenu'] = {}
567 meta_dict[filename][
'TriggerMenu'].update(return_obj)
568 elif "FileMetaData" in key:
569 if "FileMetaData" not in meta_dict[filename]:
570 meta_dict[filename][
"FileMetaData"] = dynamic_fmd_items
571 meta_dict[filename][
"FileMetaData"].update(return_obj)
573 meta_dict[filename][key] = return_obj
577 esi_dict =
next(key
for key, value
in meta_dict[filename].
items()
578 if isinstance(value, dict)
and "numberOfEvents" in value
and
579 meta_dict[filename][
"metadata_items"][key] ==
"EventStreamInfo")
580 msg.debug(f
"{esi_dict=}")
581 meta_dict[filename][
"nentries"] = meta_dict[filename][esi_dict][
"numberOfEvents"]
582 except StopIteration
as err:
583 msg.debug(f
"Caught {err=}, {type(err)=}, falling back on opening the DataHeader"
584 " Container to read the number of entries")
586 msg.debug(f
"{meta_dict[filename]['nentries']=}")
588 if unique_tag_info_values
and mode==
'iov':
589 unique_tag_info_values =
False
590 msg.info(
'disabling "unique_tag_info_values" option for "iov" mode')
597 if unique_tag_info_values:
598 msg.info(
'MetaReader is called with the parameter "unique_tag_info_values" set to True. '
599 'This is a workaround to remove all duplicate values from "/TagInfo" key')
600 if '/TagInfo' in meta_dict[filename]:
601 for key, value
in meta_dict[filename][
'/TagInfo'].
items():
602 if isinstance(value, list)
and value:
603 if len(unique_values :=
set(value)) > 1:
605 f
"Found multiple values for {key}: {value}. "
606 "Looking for possible duplicates."
611 unique_amitags =
set()
612 for amitags
in unique_values:
614 "_".
join({tag
for tag
in amitags.split(
"_")
if tag})
616 if len(unique_amitags) == 1:
618 elif key ==
"beam_energy":
620 unique_energies =
set()
621 for energy
in unique_values:
626 energy =
float(energy)
629 unique_energies.add(energy)
630 if len(unique_energies) == 1:
632 elif key
in [
"AtlasRelease",
"IOVDbGlobalTag",
"AODFixVersion"]:
636 f
"Multiple values for {key} may mean the same, or "
637 "the input file was produced in multi-step job. "
638 f
"Ignoring all but the first entry: {key} = {value[0]}"
642 f
"{key} from /TagInfo contains more than 1 unique value: {value}"
645 meta_dict[filename][
'/TagInfo'][key] = value[0]
648 promote = mode ==
'lite' or mode ==
'peeker'
662 if isinstance(collectionTree, ROOT.TTree):
663 meta_dict[filename][
'itemList'] = [ (b.GetClassName(), b.GetName())
for b
in collectionTree.GetListOfBranches() ]
666 elif current_file_type ==
'BS':
668 if ignoreNonExistingLocalFiles
and not regex_URI_scheme.match(filename)
and not os.path.isfile(filename):
669 msg.warn(
'Ignoring not accessible file: {}'.
format(filename))
675 bs = eformat.istream(filename)
676 meta_dict[filename][
'nentries'] = bs.total_events
679 data_reader = eformat.EventStorage.pickDataReader(filename)
680 assert data_reader,
'problem picking a data reader for file [%s]' % filename
683 meta_dict[filename][
'auto_flush'] = 1
685 if hasattr(data_reader,
'GUID'):
686 meta_dict[filename][
'file_guid'] = data_reader.GUID()
689 meta_dict[filename][
'file_comp_alg'] = 1
690 meta_dict[filename][
'file_comp_level'] = 1
698 for md
in data_reader.freeMetaDataStrings():
699 if md.startswith(
'Event type:'):
703 v.append(
'IS_SIMULATION')
710 v.append(
'IS_TESTBEAM')
712 if 'is physics' in md:
713 v.append(
'IS_PHYSICS')
715 v.append(
'IS_CALIBRATION')
717 bs_metadata[k] = tuple(v)
719 elif md.startswith(
'GeoAtlas:'):
721 v = md.split(
'GeoAtlas:')[1].strip()
724 elif md.startswith(
'IOVDbGlobalTag:'):
726 v = md.split(
'IOVDbGlobalTag:')[1].strip()
733 bs_metadata[
'detectorMask'] = data_reader.detectorMask()
734 bs_metadata[
'runNumbers'] = data_reader.runNumber()
735 bs_metadata[
'lumiBlockNumbers'] = data_reader.lumiblockNumber()
736 bs_metadata[
'projectTag'] = data_reader.projectTag()
737 bs_metadata[
'stream'] = data_reader.stream()
739 beamTypeNbr= data_reader.beamType()
744 if (beamTypeNbr==0): bs_metadata[
'beamType'] =
'cosmics'
745 elif (beamTypeNbr==1
or beamTypeNbr==2): bs_metadata[
'beamType'] =
'collisions'
746 else: bs_metadata[
'beamType'] =
'unknown'
748 bs_metadata[
'beamEnergy'] = data_reader.beamEnergy()
750 meta_dict[filename][
'eventTypes'] = bs_metadata.get(
'eventTypes', [])
751 meta_dict[filename][
'GeoAtlas'] = bs_metadata.get(
'geometry',
None)
752 meta_dict[filename][
'conditions_tag'] = bs_metadata.get(
'conditions_tag',
None)
753 meta_dict[filename][
'project_name'] = bs_metadata.get(
'projectTag',
None)
756 meta_dict[filename][
'detectorMask'] = [bs_metadata.get(
'detectorMask',
None)]
757 meta_dict[filename][
'runNumbers'] = [bs_metadata.get(
'runNumbers',
None)]
758 meta_dict[filename][
'lumiBlockNumbers'] = [bs_metadata.get(
'lumiBlockNumbers',
None)]
759 meta_dict[filename][
'beam_type'] = bs_metadata.get(
'beamType',
None)
760 meta_dict[filename][
'beam_energy'] = bs_metadata.get(
'beamEnergy',
None)
761 meta_dict[filename][
'stream'] = bs_metadata.get(
'stream',
None)
763 if not data_reader.good():
765 meta_dict[filename][
'runNumbers'].
append(bs_metadata.get(
'run_number', 0))
766 meta_dict[filename][
'lumiBlockNumbers'].
append(bs_metadata.get(
'LumiBlock', 0))
768 msg.debug(f
"{meta_dict[filename]=}")
769 msg.debug(f
"{len(bs)=}")
774 meta_dict[filename][
'processingTags'] = [tag.name
for tag
in evt.stream_tag()]
775 meta_dict[filename][
'evt_number'] = [evt.global_id()]
776 meta_dict[filename][
'run_type'] = [eformat.helper.run_type2string(evt.run_type())]
779 if meta_dict[filename][
'lumiBlockNumbers'] == [0]:
780 msg.debug(
'Taking the luminosity block info from the first event (%i)', evt.lumi_block())
781 meta_dict[filename][
'lumiBlockNumbers'] = [evt.lumi_block()]
784 if meta_dict[filename][
'runNumbers'] == [0]:
785 msg.debug(
'Taking the run number info from the first event (%i)', evt.run_no())
786 meta_dict[filename][
'runNumbers'] = [evt.run_no()]
787 except RuntimeError
as err:
788 msg.error(
"Issue while reading the first event of BS file %r: %r", filename, err)
790 msg.debug(f
"{meta_dict[filename]=}")
792 msg.warn(f
"Event-less BS {filename=}, will not read metadata information from the first event")
795 if len(bs_metadata.get(
'eventTypes',
'')) == 0:
796 evt_type = [
'IS_DATA',
'IS_ATLAS']
797 if bs_metadata.get(
'stream',
'').startswith(
'physics_'):
798 evt_type.append(
'IS_PHYSICS')
799 elif bs_metadata.get(
'stream',
'').startswith(
'calibration_'):
800 evt_type.append(
'IS_CALIBRATION')
801 elif bs_metadata.get(
'projectTag',
'').endswith(
'_calib'):
802 evt_type.append(
'IS_CALIBRATION')
804 evt_type.append(
'Unknown')
806 meta_dict[filename][
'eventTypes'] = evt_type
809 meta_dict[filename][
'bs_metadata'] = bs_metadata
813 msg.error(
'Unknown filetype for {0} - there is no metadata interface for type {1}'.
format(filename, current_file_type))