17#include <TChainElement.h>
20#include <TFriendElement.h>
22#include <TMethodCall.h>
33#ifndef XAOD_STANDALONE
92 "Did not call finishWritingTo() before destroying the TEvent object!");
108 if (pattern.size()) {
117 return StatusCode::SUCCESS;
131 std::string_view treeName) {
134 if (
file ==
nullptr) {
136 return StatusCode::SUCCESS;
163 ATH_MSG_ERROR(
"Couldn't find metadata tree on input. Object is unusable!");
164 return StatusCode::FAILURE;
171 return StatusCode::FAILURE;
176 ATH_MSG_WARNING(
"Was expecting a metadata tree with size 1, instead of "
178 ATH_MSG_WARNING(
"The input file was most probably produced by hadd...");
184 static const std::string eventFormatTypeName =
186 ::TClass* cl = ::TClass::GetClass(eventFormatTypeName.c_str());
193 auto readEventFormatMetadata =
194 [&](std::string_view thisTreeName) -> StatusCode {
196 TTree* metaTree =
file->Get<TTree>(thisTreeName.data());
197 if (metaTree ==
nullptr) {
198 ATH_MSG_ERROR(
"Couldn't find metadata tree \"" << thisTreeName
200 return StatusCode::FAILURE;
203 if (metaTree->LoadTree(0) < 0) {
205 << thisTreeName <<
"\"");
206 return StatusCode::FAILURE;
210 const std::string eventFormatBranchName =
212 if (!metaTree->GetBranch(eventFormatBranchName.c_str())) {
216 ATH_MSG_INFO(
"Input file provides no event or metadata");
217 return StatusCode::RECOVERABLE;
224 metaTree->SetBranchAddress(eventFormatBranchName.c_str(), &format, &br);
226 ATH_MSG_ERROR(
"Failed to connect to xAOD::EventFormat object");
227 return StatusCode::FAILURE;
232 for (
const auto &[key, element] : *format) {
243 return StatusCode::SUCCESS;
249 if (
sc.isRecoverable()) {
252 return StatusCode::SUCCESS;
259 std::set<std::string> lOtherMetaTreeNames = {};
260 TList* lKeys =
file->GetListOfKeys();
263 for (
int iKey = 0; iKey < lKeys->GetEntries(); iKey++) {
265 std::string keyName = lKeys->At(iKey)->GetName();
272 const char* className = ((::TKey* )lKeys->At(iKey))->GetClassName();
273 static constexpr Bool_t LOAD = kFALSE;
274 static constexpr Bool_t SILENT = kTRUE;
275 ::TClass* cl = ::TClass::GetClass(className, LOAD, SILENT);
276 if ((cl !=
nullptr) && cl->InheritsFrom(::TTree::Class())) {
278 lOtherMetaTreeNames.insert(std::move(keyName));
285 for (
const std::string &metaTreeName : lOtherMetaTreeNames) {
286 ATH_CHECK(readEventFormatMetadata(metaTreeName));
309 stats.setNEvents(stats.nEvents() +
m_inTree->GetEntries());
315 listener->handle(beginIncident);
324 listener->handle(endIncident);
328 return StatusCode::SUCCESS;
351 if (useTreeCache && (!
m_inChain->GetCacheSize())) {
361 ATH_MSG_ERROR(
"Couldn't get the list of files from the input TChain");
362 return StatusCode::FAILURE;
364 if (!
files->GetEntries()) {
365 ATH_MSG_ERROR(
"No files are present in the received TChain");
366 return StatusCode::FAILURE;
368 const ::TChainElement* chEl =
369 dynamic_cast<const ::TChainElement*
>(
files->At(0));
372 return StatusCode::FAILURE;
375 std::unique_ptr<TFile> dummyFile{TFile::Open(chEl->GetTitle())};
378 return StatusCode::FAILURE;
393 return StatusCode::SUCCESS;
403 ::TFile*
file =
tree->GetCurrentFile();
421 return StatusCode::SUCCESS;
433 std::string_view treeName) {
438 return StatusCode::FAILURE;
443 ATH_MSG_ERROR(
"Object already writing to a file. Close that file first!");
444 return StatusCode::FAILURE;
452 m_outTree = std::make_unique<TTree>(treeName.data(),
"xAOD event tree");
462 return StatusCode::SUCCESS;
485 ATH_MSG_ERROR(
"The object doesn't seem to be connected to an output file!");
486 return StatusCode::FAILURE;
496 listener->handle(incident);
510 return StatusCode::SUCCESS;
516 metatree->SetAutoSave(10000);
517 metatree->SetAutoFlush(-30000000);
518 metatree->SetDirectory(
file);
527 ::Error(
"xAOD::TEvent::finishWritingTo",
528 XAOD_MESSAGE(
"Class name parsing fails for %s ! "),
e.what());
529 return StatusCode::FAILURE;
535 std::vector<std::pair<std::string, TObjectManager* >> outputMetaObjects;
539 if (objMgr ==
nullptr) {
541 return StatusCode::FAILURE;
543 outputMetaObjects.emplace_back(key, objMgr);
548 for (
auto &[key, mgr] : outputMetaObjects) {
552 const ::Int_t splitLevel = (key.ends_with(
"Aux.") ? 1 : 0);
554 *(mgr->branchPtr()) =
555 metatree->Branch(key.c_str(), mgr->holder()->getClass()->GetName(),
556 mgr->holder()->getPtr(), 32000, splitLevel);
557 if (!mgr->branch()) {
559 << mgr->holder()->getClass()->GetName() <<
"/" << key
561 return StatusCode::FAILURE;
565 static constexpr bool METADATA =
true;
570 if (metatree->Fill() <= 0) {
571 ATH_MSG_ERROR(
"Failed to write event format metadata into the output");
572 metatree->SetDirectory(
nullptr);
573 return StatusCode::FAILURE;
578 metatree->SetDirectory(
nullptr);
584 return StatusCode::SUCCESS;
623 static constexpr bool TOP_STORE =
true;
624 if (
record(std::make_unique<TAuxStore>(key, TOP_STORE, mode), key)
626 ATH_MSG_ERROR(
"Couldn't connect TAuxStore object to the output");
695 const ::Long64_t fileEntry =
m_inChain->LoadTree(entry);
698 <<
" from the input chain");
712 static constexpr bool USE_TREE_CACHE =
false;
737 <<
" from the input file");
753 static const std::string dynStorePostfix =
"Aux.Dynamic";
754 if (key.ends_with(dynStorePostfix)) {
762 static constexpr bool SILENT =
true;
763 static constexpr bool METADATA =
false;
770 result += mgr->getEntry(getall);
778 listener->handle(incident);
797 return m_inChain->GetListOfFiles()->GetEntries();
833 ::Long64_t entry = 0;
834 for (::Long64_t i = 0; i <
file; ++i) {
875 std::string unsetObjects;
876 std::vector<std::pair<std::string, TVirtualManager* >> outputObjectsCopy;
879 outputObjectsCopy.emplace_back(key, mgr.get());
881 for (
auto &[key, mgr] : outputObjectsCopy) {
883 if (!mgr->create()) {
886 if (unsetObjects.size()) {
887 unsetObjects +=
", ";
889 unsetObjects.append(
"\"" + key +
"\"");
895 static constexpr bool METADATA =
false;
898 "in the output for object \""
905 if (unsetObjects.size()) {
906 ATH_MSG_ERROR(
"The following objects were not set in the current event: "
914 ATH_MSG_ERROR(
"Output tree filling failed with return value: " << ret);
934 std::vector<std::string> &vkeys,
935 bool metadata)
const {
937 std::set<std::string>
keys;
941 std::vector<TObjArray* > fullListOfBranches = {};
947 fullListOfBranches.push_back(
m_inMetaTree->GetListOfBranches());
953 fullListOfBranches.push_back(
m_inTree->GetListOfBranches());
958 TList* fList =
m_inTree->GetListOfFriends();
960 for (TObject* feObj : *fList) {
963 auto* pElement =
dynamic_cast<TFriendElement*
>(feObj);
964 if (pElement ==
nullptr) {
967 TTree* friendTree = pElement->GetTree();
969 fullListOfBranches.push_back(friendTree->GetListOfBranches());
977 for (
const TObjArray* in : fullListOfBranches) {
979 for (
const TObject* obj : *in) {
981 if (obj ==
nullptr) {
984 const TBranch* element =
dynamic_cast<const TBranch*
>(obj);
987 return StatusCode::FAILURE;
989 const std::string objClassName = element->GetClassName();
990 std::string key = obj->GetName();
993 if (objClassName == targetClassName) {
994 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
996 keys.insert(std::move(key));
1003 ATH_MSG_DEBUG(
"Scanning input objects for \"" << targetClassName <<
"\"");
1004 for (
const auto &[key, vmgr] : inAux) {
1008 if (mgr ==
nullptr) {
1011 const std::string &objClassName = mgr->holder()->getClass()->GetName();
1014 if (objClassName == targetClassName) {
1015 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1023 const TObjArray* out =
m_outTree->GetListOfBranches();
1026 for (
const TObject* obj : *out) {
1027 if (obj ==
nullptr) {
1030 const TBranch* element =
dynamic_cast<const TBranch*
>(obj);
1031 if (element ==
nullptr) {
1033 return StatusCode::FAILURE;
1035 const std::string objClassName = element->GetClassName();
1036 std::string key = obj->GetName();
1039 if (objClassName == targetClassName) {
1040 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1042 keys.insert(std::move(key));
1050 ATH_MSG_DEBUG(
"Scanning output objects for \"" << targetClassName <<
"\"");
1051 for (
const auto &[key, vmgr] : outAux) {
1054 if (mgr ==
nullptr) {
1057 const std::string &objClassName = mgr->holder()->getClass()->GetName();
1060 if (objClassName == targetClassName) {
1061 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1067 vkeys.insert(vkeys.end(),
keys.begin(),
keys.end());
1070 return StatusCode::SUCCESS;
1095 return StatusCode::FAILURE;
1103 return StatusCode::SUCCESS;
1107 if (silent ==
false) {
1110 return StatusCode::RECOVERABLE;
1116 if (silent ==
false) {
1124 ::TBranch* br =
m_inTree->GetBranch(key.c_str());
1125 if (br ==
nullptr) {
1130 return StatusCode::RECOVERABLE;
1134 br->SetMakeClass(0);
1138 std::string className = br->GetClassName();
1139 if (className ==
"") {
1143 className = ef->className();
1146 "Couldn't find an appropriate type with a dictionary for branch \""
1148 return StatusCode::FAILURE;
1151 ::TClass* realClass = ::TClass::GetClass(className.c_str());
1152 if (((!realClass) || (!realClass->IsLoaded())) && ef) {
1156 className = ef->className();
1157 realClass = ::TClass::GetClass(className.c_str());
1159 if ((!realClass) || (!realClass->IsLoaded())) {
1162 "Couldn't find an appropriate type with a dictionary for branch \""
1164 return StatusCode::FAILURE;
1171 static const ::EDataType dataType = kOther_t;
1177 void* ptr =
nullptr;
1182 if (mgr ==
nullptr) {
1183 ATH_MSG_ERROR(
"Couldn't access output manager for: " << key);
1184 return StatusCode::FAILURE;
1187 ptr = mgr->holder()->get();
1193 if (ptr ==
nullptr) {
1194 ptr = realClass->New();
1199 auto mgr = std::make_unique<TObjectManager>(
1200 nullptr, std::make_unique<THolder>(ptr, realClass), renewOnRead);
1209 << key <<
"\" is " << br->GetSplitLevel()
1210 <<
". This can only be read in kAthenaAccess mode.");
1212 *(mgr->holder()->getPtr()) =
nullptr;
1214 return StatusCode::FAILURE;
1218 const ::Int_t status =
1219 m_inTree->SetBranchAddress(key.c_str(), mgr->holder()->getPtr(),
1220 mgr->branchPtr(), realClass, dataType, kTRUE);
1223 << className <<
"\" to input branch \"" << key
1224 <<
"\". Return code: " << status);
1226 *(mgr->holder()->getPtr()) = 0;
1228 return StatusCode::FAILURE;
1248 return StatusCode::SUCCESS;
1264 return StatusCode::FAILURE;
1269 return StatusCode::SUCCESS;
1274 if (br ==
nullptr) {
1275 if (silent ==
false) {
1277 <<
"\" not available on input");
1279 return StatusCode::RECOVERABLE;
1283 if (br->GetEntries() == 0) {
1284 if (silent ==
false) {
1286 <<
"\" doesn't hold any data");
1288 return StatusCode::RECOVERABLE;
1292 br->SetMakeClass(0);
1296 ::EDataType dt = kOther_t;
1297 if (br->GetExpectedType(cl, dt) || (!cl)) {
1298 ATH_MSG_ERROR(
"Couldn't get the type for metadata branch \"" << key
1300 return StatusCode::FAILURE;
1304 void* ptr = cl->New();
1306 auto mgr = std::make_unique<TObjectManager>(
1307 nullptr, std::make_unique<THolder>(ptr, cl), renewOnRead);
1311 key.c_str(), mgr->holder()->getPtr(), mgr->branchPtr(), cl, dt, kTRUE);
1314 << cl->GetName() <<
"\" to input branch \"" << key
1315 <<
"\". Return code: " << status);
1317 *(mgr->holder()->getPtr()) = 0;
1319 return StatusCode::FAILURE;
1328 ATH_MSG_ERROR(
"Couldn't read in metadata object with key \"" << key
1330 return StatusCode::FAILURE;
1343 static constexpr bool METADATA =
true;
1348 return StatusCode::SUCCESS;
1365 return StatusCode::FAILURE;
1369 if ((!
m_inTree->GetBranch(prefix.c_str())) &&
1373 return StatusCode::SUCCESS;
1378 return StatusCode::SUCCESS;
1386 static constexpr bool SILENT =
false;
1390 return StatusCode::SUCCESS;
1396 static constexpr bool TOP_STORE =
true;
1397 auto store = std::make_unique<TAuxStore>(
1410 static constexpr bool IS_OWNER =
true;
1412 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1415 return StatusCode::SUCCESS;
1420 return StatusCode::FAILURE;
1436 return StatusCode::SUCCESS;
1442 return StatusCode::FAILURE;
1450 static constexpr bool SILENT =
false;
1454 return StatusCode::SUCCESS;
1460 static constexpr bool TOP_STORE =
true;
1461 auto store = std::make_unique<TAuxStore>(
1474 static constexpr bool IS_OWNER =
true;
1476 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1479 return StatusCode::SUCCESS;
1484 return StatusCode::FAILURE;
1504 (isAuxStore ==
false)) {
1505 return StatusCode::SUCCESS;
1518 auto itr = objects.find(key +
"Aux.");
1519 if (itr == objects.end()) {
1522 return StatusCode::SUCCESS;
1524 auxMgr = itr->second.get();
1525 auxKey = key +
"Aux.";
1528 if (metadata ==
false) {
1530 const ::Int_t readBytes = auxMgr->
getEntry();
1531 if (readBytes < 0) {
1533 "Couldn't load current entry for auxiliary object with key \""
1535 return StatusCode::FAILURE;
1540 const std::string dynAuxKey = auxKey +
"Dynamic";
1541 auto dynAuxMgr = objects.find(dynAuxKey);
1543 if ((dynAuxMgr != objects.end()) &&
1549 dynAuxMgr->second->getEntry();
1560 auto dynAuxMgr = objects.find(dynAuxKey);
1561 if (dynAuxMgr == objects.end()) {
1563 return StatusCode::FAILURE;
1565 dynAuxMgr->second->getEntry();
1572 return StatusCode::SUCCESS;
1578 switch (mgr.holder()->typeKind()) {
1593 if (
vec && (!
vec->trackIndices())) {
1594 Details::forceTrackIndices(*
vec);
1600 << mgr.holder()->getClass()->GetName()
1601 <<
"\" as SG::AuxVectorBase or SG::AuxElement");
1602 return StatusCode::FAILURE;
1612 << auxKey <<
"\" is not of the right type");
1613 return StatusCode::FAILURE;
1629 << auxKey <<
"\" is not of the right type");
1630 return StatusCode::FAILURE;
1637 return StatusCode::FAILURE;
1642 vec->setStore(store);
1644 aux->setStore(store);
1647 return StatusCode::FAILURE;
1651 return StatusCode::SUCCESS;
1670 const std::string &key,
bool overwrite,
bool metadata,
1676 "No output tree defined. Did you forget to call writeTo(...)?");
1677 return StatusCode::FAILURE;
1687 ATH_MSG_ERROR(
"Meta-object \"" << typeName <<
"\"/\"" << key
1688 <<
"\" already recorded");
1689 return StatusCode::FAILURE;
1692 TClass* cl = TClass::GetClass(typeName.c_str());
1694 ATH_MSG_ERROR(
"Didn't find dictionary for type: " << typeName);
1695 return StatusCode::FAILURE;
1700 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1702 return StatusCode::SUCCESS;
1709 <<
"\" already accessed from the input, can't be "
1710 "overwritten in memory");
1711 return StatusCode::FAILURE;
1715 const Int_t splitLevel = (key.ends_with(
"Aux.") ? 1 : 0);
1722 TClass* cl = TClass::GetClass(typeName.c_str());
1723 if (cl ==
nullptr) {
1724 ATH_MSG_ERROR(
"Didn't find dictionary for type: " << typeName);
1725 return StatusCode::FAILURE;
1736 auto mgr = std::make_unique<TObjectManager>(
1737 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1742 static constexpr Int_t basketSize = 32000;
1744 m_outTree->Branch(key.c_str(), cl->GetName(),
1747 ATH_MSG_ERROR(
"Failed to create branch \"" << key <<
"\" out of type \""
1748 << cl->GetName() <<
"\"");
1751 return StatusCode::FAILURE;
1756 static constexpr bool METADATA =
false;
1761 return StatusCode::SUCCESS;
1767 ATH_MSG_ERROR(
"Manager object of the wrong type encountered");
1768 return StatusCode::FAILURE;
1777 TClass* cl = TClass::GetClass(typeName.c_str());
1779 ::strcmp(cl->GetName(), omgr->
holder()->
getClass()->GetName())) {
1781 << key <<
"\" the previous type was \""
1783 <<
"\", but the newly requested type is \"" << typeName
1785 return StatusCode::FAILURE;
1793 static constexpr bool METADATA =
false;
1797 return StatusCode::SUCCESS;
1805 if (iomgr !=
nullptr) {
1807 static const bool OVERWRITE =
true;
1808 static const bool IS_OWNER =
true;
1810 key, OVERWRITE, metadata, IS_OWNER));
1811 return StatusCode::SUCCESS;
1816 if (auxmgr !=
nullptr) {
1820 "TAuxStore auxiliary objects can only be recorded for event data");
1821 return StatusCode::FAILURE;
1825 return StatusCode::SUCCESS;
1829 ATH_MSG_ERROR(
"Unknown auxiliary store manager type encountered");
1830 return StatusCode::FAILURE;
1843 return StatusCode::SUCCESS;
1848 ATH_MSG_ERROR(
"Function called on an uninitialised object");
1849 return StatusCode::FAILURE;
1858 for (; itr != end; ++itr) {
1861 const std::string &branchName = itr->second.branchName();
1864 if (branchName.find(
"Aux.") != std::string::npos) {
1873 const std::string intName = branchName.substr(0, branchName.size() - 4);
1881 ::Bool_t auxFound = kFALSE;
1884 std::vector<TObjArray* > fullListOfBranches = {};
1886 fullListOfBranches.push_back(
m_inTree->GetListOfBranches());
1889 if (
m_inTree->GetListOfFriends()) {
1891 TList* fList =
m_inTree->GetListOfFriends();
1893 for (TObject* feObj : *fList) {
1896 auto* pElement =
dynamic_cast<TFriendElement*
>(feObj);
1899 TTree* friendTree = pElement->GetTree();
1901 fullListOfBranches.push_back(friendTree->GetListOfBranches());
1906 for (TObjArray* branches : fullListOfBranches) {
1907 for (Int_t i = 0; i < branches->GetEntriesFast(); ++i) {
1908 if (!branches->At(i))
1911 const TString
name(branches->At(i)->GetName());
1912 if (
name.BeginsWith(branchName) ||
name.BeginsWith(dynName)) {
1920 << intName <<
"\" belonging to branch \""
1921 << branchName <<
"\"");
1928 ::TClass* cl = ::TClass::GetClass(el->className().c_str());
1929 if ((!cl) || (!cl->IsLoaded())) {
1931 << el->className() <<
"\"");
1938 static ::TClass*
const baseCl = ::TClass::GetClass(baseName.c_str());
1940 ATH_MSG_ERROR(
"Couldn't get dictionary for type \"" << baseName
1942 return StatusCode::FAILURE;
1952 static constexpr bool TOP_STORE =
true;
1953 TAuxStore temp(branchName, TOP_STORE, mode);
1954 static constexpr bool PRINT_WARNINGS =
false;
1962 stats.branch(branchName,
id);
1966 stats.setBranchNum(stats.branchNum() + temp.getAuxIDs().size());
1980 return StatusCode::SUCCESS;
1996 const std::string &key) {
2001 "No output tree defined. Did you forget to call writeTo(...)?");
2002 return StatusCode::FAILURE;
2006 const std::set<std::string>* filter = 0;
2009 filter = &(filter_itr->second);
2018 store->selectAux(*filter);
2023 static constexpr bool OWNS_STORE =
true;
2025 std::make_unique<TAuxManager>(store.release(), OWNS_STORE);
2028 return StatusCode::SUCCESS;
2032 if (vitr->second->object() == store.get()) {
2034 return StatusCode::SUCCESS;
2043 if (mgr ==
nullptr) {
2045 << key <<
"\" already exists, and is not of type TAuxStore");
2046 return StatusCode::FAILURE;
2051 store->selectAux(*filter);
2058 mgr->setObject(store.release());
2061 return StatusCode::SUCCESS;
2075 ::TMethodCall setNameCall;
2079 setNameCall.InitWithPrototype(mgr.holder()->getClass(),
"setName",
2081 if (setNameCall.IsValid()) {
2084 const ::TString params =
2085 ::TString::Format(
"\"%s\"", mgr.branch()->GetName());
2086 const char* charParams = params.Data();
2087 setNameCall.Execute(mgr.holder()->get(), charParams);
2090 ATH_MSG_WARNING(
"Couldn't find setName(...) function for container \""
2091 << mgr.branch()->GetName() <<
"\" (type: "
2092 << mgr.holder()->getClass()->GetName() <<
")");
2097 static const TClass*
const holderClass =
2099 if (!mgr.holder()->getClass()->InheritsFrom(holderClass)) {
2101 return StatusCode::SUCCESS;
2109 return StatusCode::FAILURE;
2116 static constexpr bool TOP_STORE =
false;
2117 auto store = std::make_unique<TAuxStore>(
2118 mgr.branch()->GetName(), TOP_STORE,
2137 static constexpr bool SHARED_OWNER =
false;
2138 m_inputObjects[std::string(mgr.branch()->GetName()) +
"Dynamic"] =
2139 std::make_unique<TAuxManager>(store.get(), SHARED_OWNER);
2142 storeHolder->
setStore(store.release());
2145 return StatusCode::SUCCESS;
2168 return StatusCode::SUCCESS;
2172 if (!mgr->holder()->getClass()->InheritsFrom(
"SG::IAuxStoreIO")) {
2173 return StatusCode::SUCCESS;
2181 return StatusCode::FAILURE;
2188 auto item_itr =
m_auxItemList.find(mgr->branch()->GetName());
2190 sel.selectAux(item_itr->second);
2197 sel.getSelectedAuxIDs(
aux->getSelectedAuxIDs());
2201 if (auxids.
empty()) {
2202 return StatusCode::SUCCESS;
2206 const std::string dynNamePrefix =
2215 typedef std::pair<std::string, SG::auxid_t> AuxVarSort_t;
2216 std::vector<AuxVarSort_t> varsort;
2217 varsort.reserve(auxids.
size());
2219 varsort.emplace_back(
r.getName(
id),
id);
2221 std::sort(varsort.begin(), varsort.end());
2224 for (
const auto &p : varsort) {
2230 const std::string brName = dynNamePrefix + p.first;
2233 Object_t::iterator bmgr = objects.find(brName);
2236 if (bmgr == objects.end()) {
2239 const std::type_info* brType =
aux->getIOType(
id);
2242 return StatusCode::FAILURE;
2245 std::string brProperTypeName =
"<unknown>";
2251 if (strlen(brType->name()) == 1) {
2254 brProperTypeName = brTypeName;
2258 if (rootType ==
'\0') {
2260 << brName <<
"\" of type \"" << brTypeName <<
"\"");
2261 return StatusCode::FAILURE;
2265 std::ostringstream leaflist;
2266 leaflist << brName <<
"/" << rootType;
2269 static constexpr bool IS_OWNER =
false;
2270 auto auxmgr = std::make_unique<TPrimitiveAuxBranchManager>(
2271 id,
nullptr,
new THolder(
aux->getIOData(
id),
nullptr, IS_OWNER));
2274 static constexpr Int_t BASKET_SIZE = 32000;
2275 *(auxmgr->branchPtr()) =
2276 outTree.Branch(brName.c_str(), auxmgr->holder()->get(),
2277 leaflist.str().c_str(), BASKET_SIZE);
2278 if (!auxmgr->branch()) {
2280 << brName <<
"\" out of type \"" << brProperTypeName
2283 *(auxmgr->holder()->getPtr()) = 0;
2284 return StatusCode::FAILURE;
2286 br = auxmgr->branch();
2289 objects[brName] = std::move(auxmgr);
2294 static constexpr Bool_t LOAD_IF_NOT_FOUND = kTRUE;
2295 static constexpr Bool_t SILENT = kTRUE;
2296 TClass* cl = TClass::GetClass(*brType, LOAD_IF_NOT_FOUND, SILENT);
2297 if (cl ==
nullptr) {
2300 cl = TClass::GetClass(brTypeName.c_str());
2302 if (cl ==
nullptr) {
2304 << brName <<
"\" of type \"" << brTypeName <<
"\"");
2305 return StatusCode::FAILURE;
2310 brProperTypeName = cl->GetName();
2313 static constexpr bool IS_OWNER =
false;
2314 auto auxmgr = std::make_unique<TAuxBranchManager>(
2315 id,
nullptr,
new THolder(
aux->getIOData(
id), cl, IS_OWNER));
2318 static constexpr Int_t BASKET_SIZE = 32000;
2319 static constexpr Int_t SPLIT_LEVEL = 0;
2320 *(auxmgr->branchPtr()) = outTree.Branch(brName.c_str(), cl->GetName(),
2321 auxmgr->holder()->getPtr(),
2322 BASKET_SIZE, SPLIT_LEVEL);
2323 if (!auxmgr->branch()) {
2325 << brName <<
"\" out of type \"" << brProperTypeName
2328 *(auxmgr->holder()->getPtr()) = 0;
2329 return StatusCode::FAILURE;
2331 br = auxmgr->branch();
2334 objects[brName] = std::move(auxmgr);
2339 if (outTree.GetEntries()) {
2340 void* ptr = br->GetAddress();
2342 for (::Long64_t i = 0; i < outTree.GetEntries(); ++i) {
2345 br->SetAddress(ptr);
2352 mgr->branch()->GetName(),
2361 bmgr = objects.find(brName);
2362 if (bmgr == objects.end()) {
2363 ATH_MSG_FATAL(
"There is an internal logic error in the code...");
2364 return StatusCode::FAILURE;
2370 const_cast<void*
>(
static_cast<const void*
>(
aux->getIOData(
id)));
2371 bmgr->second->setObject(nc_data);
2375 return StatusCode::SUCCESS;
2383 return StatusCode::FAILURE;
2387 const std::set<std::string>* filter = 0;
2390 filter = &(filter_itr->second);
2399 store->selectAux(*filter);
2404 static constexpr bool OWNS_STORE =
false;
2405 m_outputObjects[key] = std::make_unique<TAuxManager>(store, OWNS_STORE);
2408 return StatusCode::SUCCESS;
2412 if (vitr->second->object() == store) {
2414 return StatusCode::SUCCESS;
2423 if (mgr ==
nullptr) {
2425 << key <<
"\" already exists, and is not of type TAuxStore");
2426 return StatusCode::FAILURE;
2431 store->selectAux(*filter);
2438 mgr->setObject(store);
2441 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Base class for elements of a container that can have aux data.
Handle mappings between names and auxid_t.
Manage index tracking and synchronization of auxiliary data.
std::vector< size_t > vec
Recursively separate out template arguments in a C++ class name.
Interface providing I/O for a generic auxiliary store.
void upgrade()
Convert the lock from upgrade to exclusive.
Exception to signal a malformed class name.
bit_t size() const
Count the number of 1 bits in the set.
bool empty() const
Return true if there are no 1 bits in the set.
Base class for elements of a container that can have aux data.
Handle mappings between names and auxid_t.
static AuxTypeRegistry & instance()
Return the singleton registry instance.
Manage index tracking and synchronization of auxiliary data.
Interface for objects taking part in direct ROOT I/O.
AuxStoreType
Type of the auxiliary store.
@ AST_ContainerStore
The store describes a container.
@ AST_ObjectStore
The store describes a single object.
virtual AuxStoreType getStoreType() const =0
Return the type of the store object.
virtual void setStore(IAuxStore *store)=0
Give an auxiliary store object to the holder object.
Interface providing I/O for a generic auxiliary store.
Interface for non-const operations on an auxiliary store.
Interface for const operations on an auxiliary store.
A set of aux data identifiers.
Class helping in dealing with dynamic branch selection.
Manager for EDM objects created by ROOT.
const THolder * holder() const
Accessor to the Holder object.
EventFormat m_inputEventFormat
Format of the current input file.
const std::string & name() const override
Get the name of the instance.
std::set< std::string > m_inputMissingObjects
Objects that have been asked for, but were found to be missing in the current input.
const void * getInputObject(SG::sgkey_t key, const std::type_info &ti, bool silent) override
Function for retrieving an input object in a non-template way.
upgrade_mutex_t m_branchesMutex
Mutex for multithread synchronization.
AthContainers_detail::upgrading_lock< upgrade_mutex_t > upgrading_lock_t
Lock type for multithread synchronization.
Object_t m_inputObjects
Collection of all the managed input objects.
static const char *const METADATA_OBJECT_NAME
Name of the metadata tree or RNTuple.
Event(std::string_view name)
Constructor with a name.
std::unordered_map< std::string, std::unique_ptr< TVirtualManager > > Object_t
Definition of the internal data structure type.
StatusCode keys(std::vector< std::string > &vkeys, bool metadata) const
Provide a list of all data object keys associated with a specific type.
void setActive() const
Set this event object as the currently active one.
SG::sgkey_t getHash(const std::string &key) const override
Function returning the hash describing an object name.
Object_t m_inputMetaObjects
Collection of all the managed input meta-objects.
std::unordered_map< std::string, std::set< std::string > > m_auxItemList
Rules for selecting which auxiliary branches to write.
EventFormat * m_outputEventFormat
Format of the current output file.
Object_t m_outputObjects
Collection of all the managed output object.
SG::SGKeyMap< BranchInfo > m_branches ATLAS_THREAD_SAFE
Map from hashed sgkey to BranchInfo.
std::vector< TVirtualIncidentListener * > m_listeners
Listeners who should be notified when certain incidents happen.
Object_t m_outputMetaObjects
Collection of all the managed output meta-objects.
ReadStats & stats()
Access the object belonging to the current thread.
static IOStats & instance()
Singleton object accessor.
Class describing the access statistics of a collection of branches.
void nextEvent()
Function incrementing the processed event counter.
BranchStats * container(const std::string &name)
Access the description of a container. Creating it if necessary.
void setBranchNum(::Int_t num)
Set the total number of branches on the input.
void readContainer(const std::string &name)
Function incrementing the read counter on a specific container.
Manager for TAuxStore objects.
TAuxStore * getStore()
Get a type-specific pointer to the managed object.
const SG::IConstAuxStore * getConstStore() const
Get a convenience pointer to the managed object.
"ROOT @c TTree implementation" of IAuxStore
Helper class for making sure the current directory is preserved.
EAuxMode
Auxiliary store "mode".
@ kAthenaAccess
Access containers/objects like Athena does.
@ kClassAccess
Access auxiliary data using the aux containers.
@ kBranchAccess
Access auxiliary data branch-by-branch.
::TTree * m_inMetaTree
Pointer to the metadata tree in the input file.
StatusCode connectObject(const std::string &key, bool silent) override
Function setting up access to a particular object.
StatusCode connectMetaAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches for a metadata object.
StatusCode connectAux(const std::string &prefix, bool standalone) override
Function setting up access to a set of auxiliary branches.
bool hasOutput() const override
Check if an output file is connected to the object.
std::unique_ptr< TChainStateTracker > m_inChainTracker
Optional object for tracking the state changes of an input TChain.
::Int_t getEntry(::Long64_t entry, ::Int_t getall=0) override
Function loading a given entry of the input TTree.
StatusCode setAuxStore(const std::string &key, Details::IObjectManager &mgr, bool metadata) override
Function connecting a DV object to its auxiliary store.
EAuxMode auxMode() const
Get what auxiliary access mode the object was constructed with.
bool hasInput() const override
Check if an input file is connected to the object.
StatusCode initStats()
Function to initialise the statistics for all Tree content.
::Long64_t m_entry
The entry to look at from the input tree.
::Long64_t getFiles() const
Get how many files are available on the currently defined input.
void setOtherMetaDataTreeNamePattern(const std::string &pattern)
Change the pattern used for collecting information from other MetaData trees NB: Additional MetaData ...
StatusCode finishWritingTo(TFile &file) override
Finish writing to an output file.
StatusCode getNames(const std::string &targetClassName, std::vector< std::string > &vkeys, bool metadata) const override
Function determining the list keys associated with a type name.
StatusCode setUpDynamicStore(TObjectManager &mgr, ::TTree *tree)
Function adding dynamic variable reading capabilities to an auxiliary store object.
std::regex m_otherMetaDataTreeNamePattern
::TChain * m_inChain
The (optional) chain provided as input.
StatusCode putAux(::TTree &outTree, TVirtualManager &mgr, bool metadata)
Function saving the dynamically created auxiliary properties.
EAuxMode m_auxMode
The auxiliary access mode.
::Int_t fill() override
Function filling one event into the output tree.
StatusCode readFrom(::TFile &inFile) override
Set up the reading of an input file from TFile This method implements the interface from Event.
virtual ~TEvent()
Destructor.
TEvent(EAuxMode mode=kClassAccess)
Default constructor.
SG::IAuxStore * recordAux(const std::string &key, SG::IAuxStoreHolder::AuxStoreType type=SG::IAuxStoreHolder::AST_ContainerStore)
Add an auxiliary store object to the output.
StatusCode record(void *obj, const std::string &typeName, const std::string &key, bool overwrite, bool metadata, bool isOwner) override
Record an object into a connected output file.
std::unique_ptr<::TTree > m_outTree
The tree that we are writing to.
bool m_inTreeMissing
Internal status flag showing that an input file is open, but it doesn't contain an event tree.
::Int_t m_inTreeNumber
The number of the currently open tree in the input chain.
::Int_t getFile(::Long64_t file, ::Int_t getall=0)
Load the first event for a given file from the input TChain.
StatusCode writeTo(TFile &file) override
Connect the object to an output file.
::TTree * m_inTree
The main tree that we are reading from.
StatusCode connectMetaObject(const std::string &key, bool silent) override
Function setting up access to a particular metadata object.
::Long64_t getEntries() const override
Get how many entries are available from the current input file(s)
Helper class keeping track of the files that got accessed.
This class takes care of holding EDM objects in memory.
void setOwner(::Bool_t state=kTRUE)
Set whether the holder should own its object.
void ** getPtr()
Return a typeless pointer to the held object's pointer.
const ::TClass * getClass() const
virtual void * getAs(const std::type_info &tid, ::Bool_t silent=kFALSE) const
Return the object as a specific pointer.
@ DATAVECTOR
A DataVector container.
@ AUXELEMENT
A type inheriting from SG::AuxElement.
Class describing a certain "incident" that is communicated to user code.
Manager for EDM objects created by ROOT.
::TBranch ** branchPtr()
Pointer to the branch's pointer.
virtual void setObject(void *obj) override
Function replacing the object being handled.
virtual::Int_t getEntry(::Int_t getall=0) override
Function for updating the object in memory if needed.
::TBranch * branch()
Accessor to the branch.
Class providing an interface for classes listening to xAOD incidents.
Interface class for the "manager classes".
virtual const void * object() const =0
Function getting a const pointer to the object being handled.
virtual::Int_t getEntry(::Int_t getall=0)=0
Function for updating the object in memory if needed.
void setStructMode(EStructMode mode)
Set the structure mode of the object to a new value.
EStructMode
"Structural" modes of the object
@ kUndefinedStore
The structure mode is not defined.
@ kObjectStore
The object describes a single object.
@ kContainerStore
The object describes an entire container.
EStructMode structMode() const
Get what structure mode the object was constructed with.
std::vector< std::string > files
file names and file pointers
std::string normalizedTypeinfoName(const std::type_info &info)
Convert a type_info to a normalized string representation (matching the names used in the root dictio...
size_t auxid_t
Identifier for a particular aux data item.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
bool hasAuxStore(const TClass &cl)
Helper function deciding if a given type "has an auxiliary store".
bool isAuxStore(const TClass &cl)
Helper function deciding if a given type "is an auxiliary store".
bool isStandalone(const TClass &cl)
Helper function deciding if a given type "is a standalone object".
static const ::Int_t BeginEvent
A new event was just loaded.
static const ::Int_t EndInputFile
The processing of an input file has finished.
static const ::Int_t MetaDataStop
The metadata for the output file should be written out.
static const ::Int_t BeginInputFile
A new input file was just opened.
std::string dynBranchPrefix(const std::string &key)
This function is used to figure out what to name dynamic auxiliary branches coming from a container c...
char rootType(char typeidType)
This function is used internally in the code when creating primitive dynamic auxiliary branches.
std::string getFirstBranchMatch(TTree *tree, const std::string &pre)
This function is used to search for a branch in a TTree that contains a given substring.
std::string getTypeName(const std::type_info &ti)
This function is necessary in order to create type names that ROOT can understand.
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
EventFormat_v1 EventFormat
Definition of the current event format version.
static const ::Int_t CACHE_SIZE
Size of a possible TTreeCache.
Helper to disable undefined behavior sanitizer for a function.
Convert a type_info to a normalized string representation (matching the names used in the root dictio...