17#include <TChainElement.h>
20#include <TFriendElement.h>
22#include <TMethodCall.h>
88 "Did not call finishWritingTo() before destroying the TEvent object!");
104 if (pattern.size()) {
113 return StatusCode::SUCCESS;
127 std::string_view treeName) {
130 if (
file ==
nullptr) {
132 return StatusCode::SUCCESS;
158 ATH_MSG_ERROR(
"Couldn't find metadata tree on input. Object is unusable!");
159 return StatusCode::FAILURE;
166 return StatusCode::FAILURE;
171 ATH_MSG_WARNING(
"Was expecting a metadata tree with size 1, instead of "
173 ATH_MSG_WARNING(
"The input file was most probably produced by hadd...");
179 static const std::string eventFormatTypeName =
181 ::TClass* cl = ::TClass::GetClass(eventFormatTypeName.c_str());
188 auto readEventFormatMetadata =
189 [&](std::string_view thisTreeName) -> StatusCode {
191 TTree* metaTree =
file->Get<TTree>(thisTreeName.data());
192 if (metaTree ==
nullptr) {
193 ATH_MSG_ERROR(
"Couldn't find metadata tree \"" << thisTreeName
195 return StatusCode::FAILURE;
198 if (metaTree->LoadTree(0) < 0) {
200 << thisTreeName <<
"\"");
201 return StatusCode::FAILURE;
205 const std::string eventFormatBranchName =
207 if (!metaTree->GetBranch(eventFormatBranchName.c_str())) {
211 ATH_MSG_INFO(
"Input file provides no event or metadata");
212 return StatusCode::RECOVERABLE;
219 metaTree->SetBranchAddress(eventFormatBranchName.c_str(), &format, &br);
221 ATH_MSG_ERROR(
"Failed to connect to xAOD::EventFormat object");
222 return StatusCode::FAILURE;
227 for (
const auto &[key, element] : *format) {
238 return StatusCode::SUCCESS;
244 if (
sc.isRecoverable()) {
247 return StatusCode::SUCCESS;
254 std::set<std::string> lOtherMetaTreeNames = {};
255 TList* lKeys =
file->GetListOfKeys();
258 for (
int iKey = 0; iKey < lKeys->GetEntries(); iKey++) {
260 std::string keyName = lKeys->At(iKey)->GetName();
267 const char* className = ((::TKey* )lKeys->At(iKey))->GetClassName();
268 static constexpr Bool_t LOAD = kFALSE;
269 static constexpr Bool_t SILENT = kTRUE;
270 ::TClass* cl = ::TClass::GetClass(className, LOAD, SILENT);
271 if ((cl !=
nullptr) && cl->InheritsFrom(::TTree::Class())) {
273 lOtherMetaTreeNames.insert(std::move(keyName));
280 for (
const std::string &metaTreeName : lOtherMetaTreeNames) {
281 ATH_CHECK(readEventFormatMetadata(metaTreeName));
304 stats.setNEvents(stats.nEvents() +
m_inTree->GetEntries());
310 listener->handle(beginIncident);
319 listener->handle(endIncident);
323 return StatusCode::SUCCESS;
346 if (useTreeCache && (!
m_inChain->GetCacheSize())) {
356 ATH_MSG_ERROR(
"Couldn't get the list of files from the input TChain");
357 return StatusCode::FAILURE;
359 if (!
files->GetEntries()) {
360 ATH_MSG_ERROR(
"No files are present in the received TChain");
361 return StatusCode::FAILURE;
363 const ::TChainElement* chEl =
364 dynamic_cast<const ::TChainElement*
>(
files->At(0));
367 return StatusCode::FAILURE;
370 std::unique_ptr<TFile> dummyFile{TFile::Open(chEl->GetTitle())};
373 return StatusCode::FAILURE;
388 return StatusCode::SUCCESS;
398 ::TFile*
file =
tree->GetCurrentFile();
416 return StatusCode::SUCCESS;
428 std::string_view treeName) {
433 return StatusCode::FAILURE;
438 ATH_MSG_ERROR(
"Object already writing to a file. Close that file first!");
439 return StatusCode::FAILURE;
447 m_outTree = std::make_unique<TTree>(treeName.data(),
"xAOD event tree");
457 return StatusCode::SUCCESS;
480 ATH_MSG_ERROR(
"The object doesn't seem to be connected to an output file!");
481 return StatusCode::FAILURE;
491 listener->handle(incident);
505 return StatusCode::SUCCESS;
511 metatree->SetAutoSave(10000);
512 metatree->SetAutoFlush(-30000000);
513 metatree->SetDirectory(
file);
521 }
catch (
const CxxUtils::ClassName::ExcBadClassName &
e) {
522 ::Error(
"xAOD::TEvent::finishWritingTo",
523 XAOD_MESSAGE(
"Class name parsing fails for %s ! "),
e.what());
524 return StatusCode::FAILURE;
530 std::vector<std::pair<std::string, TObjectManager* >> outputMetaObjects;
534 if (objMgr ==
nullptr) {
536 return StatusCode::FAILURE;
538 outputMetaObjects.emplace_back(key, objMgr);
543 for (
auto &[key, mgr] : outputMetaObjects) {
547 const ::Int_t splitLevel = (key.ends_with(
"Aux.") ? 1 : 0);
549 *(mgr->branchPtr()) =
550 metatree->Branch(key.c_str(), mgr->holder()->getClass()->GetName(),
551 mgr->holder()->getPtr(), 32000, splitLevel);
552 if (!mgr->branch()) {
554 << mgr->holder()->getClass()->GetName() <<
"/" << key
556 return StatusCode::FAILURE;
560 static constexpr bool METADATA =
true;
565 if (metatree->Fill() <= 0) {
566 ATH_MSG_ERROR(
"Failed to write event format metadata into the output");
567 metatree->SetDirectory(
nullptr);
568 return StatusCode::FAILURE;
573 metatree->SetDirectory(
nullptr);
579 return StatusCode::SUCCESS;
618 static constexpr bool TOP_STORE =
true;
620 key, TOP_STORE, mode), key)
622 ATH_MSG_ERROR(
"Couldn't connect TAuxStore object to the output");
691 const ::Long64_t fileEntry =
m_inChain->LoadTree(entry);
694 <<
" from the input chain");
708 static constexpr bool USE_TREE_CACHE =
false;
733 <<
" from the input file");
749 static const std::string dynStorePostfix =
"Aux.Dynamic";
750 if (key.ends_with(dynStorePostfix)) {
758 static constexpr bool SILENT =
true;
759 static constexpr bool METADATA =
false;
766 result += mgr->getEntry(getall);
774 listener->handle(incident);
793 return m_inChain->GetListOfFiles()->GetEntries();
829 ::Long64_t entry = 0;
830 for (::Long64_t i = 0; i <
file; ++i) {
871 std::string unsetObjects;
872 std::vector<std::pair<std::string, TVirtualManager* >> outputObjectsCopy;
875 outputObjectsCopy.emplace_back(key, mgr.get());
877 for (
auto &[key, mgr] : outputObjectsCopy) {
879 if (!mgr->create()) {
882 if (unsetObjects.size()) {
883 unsetObjects +=
", ";
885 unsetObjects.append(
"\"" + key +
"\"");
891 static constexpr bool METADATA =
false;
894 "in the output for object \""
901 if (unsetObjects.size()) {
902 ATH_MSG_ERROR(
"The following objects were not set in the current event: "
910 ATH_MSG_ERROR(
"Output tree filling failed with return value: " << ret);
930 std::vector<std::string> &vkeys,
931 bool metadata)
const {
933 std::set<std::string>
keys;
937 std::vector<TObjArray* > fullListOfBranches = {};
943 fullListOfBranches.push_back(
m_inMetaTree->GetListOfBranches());
949 fullListOfBranches.push_back(
m_inTree->GetListOfBranches());
954 TList* fList =
m_inTree->GetListOfFriends();
956 for (TObject* feObj : *fList) {
959 auto* pElement =
dynamic_cast<TFriendElement*
>(feObj);
960 if (pElement ==
nullptr) {
963 TTree* friendTree = pElement->GetTree();
965 fullListOfBranches.push_back(friendTree->GetListOfBranches());
973 for (
const TObjArray* in : fullListOfBranches) {
975 for (
const TObject* obj : *in) {
977 if (obj ==
nullptr) {
980 const TBranch* element =
dynamic_cast<const TBranch*
>(obj);
983 return StatusCode::FAILURE;
985 const std::string objClassName = element->GetClassName();
986 std::string key = obj->GetName();
989 if (objClassName == targetClassName) {
990 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
992 keys.insert(std::move(key));
999 ATH_MSG_DEBUG(
"Scanning input objects for \"" << targetClassName <<
"\"");
1000 for (
const auto &[key, vmgr] : inAux) {
1004 if (mgr ==
nullptr) {
1007 const std::string &objClassName = mgr->holder()->getClass()->GetName();
1010 if (objClassName == targetClassName) {
1011 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1019 const TObjArray* out =
m_outTree->GetListOfBranches();
1022 for (
const TObject* obj : *out) {
1023 if (obj ==
nullptr) {
1026 const TBranch* element =
dynamic_cast<const TBranch*
>(obj);
1027 if (element ==
nullptr) {
1029 return StatusCode::FAILURE;
1031 const std::string objClassName = element->GetClassName();
1032 std::string key = obj->GetName();
1035 if (objClassName == targetClassName) {
1036 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1038 keys.insert(std::move(key));
1046 ATH_MSG_DEBUG(
"Scanning output objects for \"" << targetClassName <<
"\"");
1047 for (
const auto &[key, vmgr] : outAux) {
1050 if (mgr ==
nullptr) {
1053 const std::string &objClassName = mgr->holder()->getClass()->GetName();
1056 if (objClassName == targetClassName) {
1057 ATH_MSG_DEBUG(
"Matched \"" << targetClassName <<
"\" to key \"" << key
1063 vkeys.insert(vkeys.end(),
keys.begin(),
keys.end());
1066 return StatusCode::SUCCESS;
1091 return StatusCode::FAILURE;
1099 return StatusCode::SUCCESS;
1103 if (silent ==
false) {
1106 return StatusCode::RECOVERABLE;
1112 if (silent ==
false) {
1120 ::TBranch* br =
m_inTree->GetBranch(key.c_str());
1121 if (br ==
nullptr) {
1126 return StatusCode::RECOVERABLE;
1130 br->SetMakeClass(0);
1134 std::string className = br->GetClassName();
1135 if (className ==
"") {
1139 className = ef->className();
1142 "Couldn't find an appropriate type with a dictionary for branch \""
1144 return StatusCode::FAILURE;
1147 ::TClass* realClass = ::TClass::GetClass(className.c_str());
1148 if (((!realClass) || (!realClass->IsLoaded())) && ef) {
1152 className = ef->className();
1153 realClass = ::TClass::GetClass(className.c_str());
1155 if ((!realClass) || (!realClass->IsLoaded())) {
1158 "Couldn't find an appropriate type with a dictionary for branch \""
1160 return StatusCode::FAILURE;
1167 static const ::EDataType dataType = kOther_t;
1173 void* ptr =
nullptr;
1178 if (mgr ==
nullptr) {
1179 ATH_MSG_ERROR(
"Couldn't access output manager for: " << key);
1180 return StatusCode::FAILURE;
1183 ptr = mgr->holder()->get();
1189 if (ptr ==
nullptr) {
1190 ptr = realClass->New();
1195 auto mgr = std::make_unique<TObjectManager>(
1196 nullptr, std::make_unique<THolder>(ptr, realClass), renewOnRead);
1205 << key <<
"\" is " << br->GetSplitLevel()
1206 <<
". This can only be read in kAthenaAccess mode.");
1208 *(mgr->holder()->getPtr()) =
nullptr;
1210 return StatusCode::FAILURE;
1214 const ::Int_t status =
1215 m_inTree->SetBranchAddress(key.c_str(), mgr->holder()->getPtr(),
1216 mgr->branchPtr(), realClass, dataType, kTRUE);
1219 << className <<
"\" to input branch \"" << key
1220 <<
"\". Return code: " << status);
1222 *(mgr->holder()->getPtr()) = 0;
1224 return StatusCode::FAILURE;
1244 return StatusCode::SUCCESS;
1260 return StatusCode::FAILURE;
1265 return StatusCode::SUCCESS;
1270 if (br ==
nullptr) {
1271 if (silent ==
false) {
1273 <<
"\" not available on input");
1275 return StatusCode::RECOVERABLE;
1279 if (br->GetEntries() == 0) {
1280 if (silent ==
false) {
1282 <<
"\" doesn't hold any data");
1284 return StatusCode::RECOVERABLE;
1288 br->SetMakeClass(0);
1292 ::EDataType dt = kOther_t;
1293 if (br->GetExpectedType(cl, dt) || (!cl)) {
1294 ATH_MSG_ERROR(
"Couldn't get the type for metadata branch \"" << key
1296 return StatusCode::FAILURE;
1300 void* ptr = cl->New();
1302 auto mgr = std::make_unique<TObjectManager>(
1303 nullptr, std::make_unique<THolder>(ptr, cl), renewOnRead);
1307 key.c_str(), mgr->holder()->getPtr(), mgr->branchPtr(), cl, dt, kTRUE);
1310 << cl->GetName() <<
"\" to input branch \"" << key
1311 <<
"\". Return code: " << status);
1313 *(mgr->holder()->getPtr()) = 0;
1315 return StatusCode::FAILURE;
1324 ATH_MSG_ERROR(
"Couldn't read in metadata object with key \"" << key
1326 return StatusCode::FAILURE;
1339 static constexpr bool METADATA =
true;
1344 return StatusCode::SUCCESS;
1361 return StatusCode::FAILURE;
1365 if ((!
m_inTree->GetBranch(prefix.c_str())) &&
1369 return StatusCode::SUCCESS;
1374 return StatusCode::SUCCESS;
1382 static constexpr bool SILENT =
false;
1386 return StatusCode::SUCCESS;
1392 static constexpr bool TOP_STORE =
true;
1393 auto store = std::make_unique<TAuxStore>(
1407 static constexpr bool IS_OWNER =
true;
1409 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1412 return StatusCode::SUCCESS;
1417 return StatusCode::FAILURE;
1433 return StatusCode::SUCCESS;
1439 return StatusCode::FAILURE;
1447 static constexpr bool SILENT =
false;
1451 return StatusCode::SUCCESS;
1457 static constexpr bool TOP_STORE =
true;
1458 auto store = std::make_unique<TAuxStore>(
1472 static constexpr bool IS_OWNER =
true;
1474 std::make_unique<TAuxManager>(store.release(), IS_OWNER);
1477 return StatusCode::SUCCESS;
1482 return StatusCode::FAILURE;
1502 (isAuxStore ==
false)) {
1503 return StatusCode::SUCCESS;
1516 auto itr = objects.find(key +
"Aux.");
1517 if (itr == objects.end()) {
1520 return StatusCode::SUCCESS;
1522 auxMgr = itr->second.get();
1523 auxKey = key +
"Aux.";
1526 if (metadata ==
false) {
1528 const ::Int_t readBytes = auxMgr->
getEntry();
1529 if (readBytes < 0) {
1531 "Couldn't load current entry for auxiliary object with key \""
1533 return StatusCode::FAILURE;
1538 const std::string dynAuxKey = auxKey +
"Dynamic";
1539 auto dynAuxMgr = objects.find(dynAuxKey);
1541 if ((dynAuxMgr != objects.end()) &&
1547 dynAuxMgr->second->getEntry();
1558 auto dynAuxMgr = objects.find(dynAuxKey);
1559 if (dynAuxMgr == objects.end()) {
1561 return StatusCode::FAILURE;
1563 dynAuxMgr->second->getEntry();
1570 return StatusCode::SUCCESS;
1576 switch (mgr.holder()->typeKind()) {
1591 if (
vec && (!
vec->trackIndices())) {
1592 Details::forceTrackIndices(*
vec);
1596 if ((!
vec) && (!aux)) {
1598 << mgr.holder()->getClass()->GetName()
1599 <<
"\" as SG::AuxVectorBase or SG::AuxElement");
1600 return StatusCode::FAILURE;
1604 const SG::IConstAuxStore* store = 0;
1605#ifndef XAOD_STANDALONE
1613 << auxKey <<
"\" is not of the right type");
1614 return StatusCode::FAILURE;
1625#ifndef XAOD_STANDALONE
1633 << auxKey <<
"\" is not of the right type");
1634 return StatusCode::FAILURE;
1636 void* p = omgr->
holder()->
getAs(
typeid(SG::IConstAuxStore));
1637 SG::IConstAuxStore* store1 =
reinterpret_cast<SG::IConstAuxStore*
>(p);
1639#ifndef XAOD_STANDALONE
1645 return StatusCode::FAILURE;
1648#ifndef XAOD_STANDALONE
1650 if (store_nc)[[
likely]] {
1654 return StatusCode::FAILURE;
1660 vec->setStore(store);
1662 aux->setStore(store);
1665 return StatusCode::FAILURE;
1669 return StatusCode::SUCCESS;
1688 const std::string &key,
bool overwrite,
bool metadata,
1694 "No output tree defined. Did you forget to call writeTo(...)?");
1695 return StatusCode::FAILURE;
1705 ATH_MSG_ERROR(
"Meta-object \"" << typeName <<
"\"/\"" << key
1706 <<
"\" already recorded");
1707 return StatusCode::FAILURE;
1710 TClass* cl = TClass::GetClass(typeName.c_str());
1712 ATH_MSG_ERROR(
"Didn't find dictionary for type: " << typeName);
1713 return StatusCode::FAILURE;
1718 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1720 return StatusCode::SUCCESS;
1727 <<
"\" already accessed from the input, can't be "
1728 "overwritten in memory");
1729 return StatusCode::FAILURE;
1733 const Int_t splitLevel = (key.ends_with(
"Aux.") ? 1 : 0);
1740 TClass* cl = TClass::GetClass(typeName.c_str());
1741 if (cl ==
nullptr) {
1742 ATH_MSG_ERROR(
"Didn't find dictionary for type: " << typeName);
1743 return StatusCode::FAILURE;
1754 auto mgr = std::make_unique<TObjectManager>(
1755 nullptr, std::make_unique<THolder>(obj, cl, isOwner), renewOnRead);
1760 static constexpr Int_t basketSize = 32000;
1762 m_outTree->Branch(key.c_str(), cl->GetName(),
1765 ATH_MSG_ERROR(
"Failed to create branch \"" << key <<
"\" out of type \""
1766 << cl->GetName() <<
"\"");
1769 return StatusCode::FAILURE;
1774 static constexpr bool METADATA =
false;
1779 return StatusCode::SUCCESS;
1785 ATH_MSG_ERROR(
"Manager object of the wrong type encountered");
1786 return StatusCode::FAILURE;
1795 TClass* cl = TClass::GetClass(typeName.c_str());
1797 ::strcmp(cl->GetName(), omgr->
holder()->
getClass()->GetName())) {
1799 << key <<
"\" the previous type was \""
1801 <<
"\", but the newly requested type is \"" << typeName
1803 return StatusCode::FAILURE;
1811 static constexpr bool METADATA =
false;
1815 return StatusCode::SUCCESS;
1823 if (iomgr !=
nullptr) {
1825 static const bool OVERWRITE =
true;
1826 static const bool IS_OWNER =
true;
1828 key, OVERWRITE, metadata, IS_OWNER));
1829 return StatusCode::SUCCESS;
1834 if (auxmgr !=
nullptr) {
1838 "TAuxStore auxiliary objects can only be recorded for event data");
1839 return StatusCode::FAILURE;
1843 return StatusCode::SUCCESS;
1847 ATH_MSG_ERROR(
"Unknown auxiliary store manager type encountered");
1848 return StatusCode::FAILURE;
1861 return StatusCode::SUCCESS;
1866 ATH_MSG_ERROR(
"Function called on an uninitialised object");
1867 return StatusCode::FAILURE;
1876 for (; itr != end; ++itr) {
1879 const std::string &branchName = itr->second.branchName();
1882 if (branchName.find(
"Aux.") != std::string::npos) {
1891 const std::string intName = branchName.substr(0, branchName.size() - 4);
1899 ::Bool_t auxFound = kFALSE;
1902 std::vector<TObjArray* > fullListOfBranches = {};
1904 fullListOfBranches.push_back(
m_inTree->GetListOfBranches());
1907 if (
m_inTree->GetListOfFriends()) {
1909 TList* fList =
m_inTree->GetListOfFriends();
1911 for (TObject* feObj : *fList) {
1914 auto* pElement =
dynamic_cast<TFriendElement*
>(feObj);
1917 TTree* friendTree = pElement->GetTree();
1919 fullListOfBranches.push_back(friendTree->GetListOfBranches());
1924 for (TObjArray* branches : fullListOfBranches) {
1925 for (Int_t i = 0; i < branches->GetEntriesFast(); ++i) {
1926 if (!branches->At(i))
1929 const TString
name(branches->At(i)->GetName());
1930 if (
name.BeginsWith(branchName) ||
name.BeginsWith(dynName)) {
1938 << intName <<
"\" belonging to branch \""
1939 << branchName <<
"\"");
1946 ::TClass* cl = ::TClass::GetClass(el->className().c_str());
1947 if ((!cl) || (!cl->IsLoaded())) {
1949 << el->className() <<
"\"");
1956 static ::TClass*
const baseCl = ::TClass::GetClass(baseName.c_str());
1958 ATH_MSG_ERROR(
"Couldn't get dictionary for type \"" << baseName
1960 return StatusCode::FAILURE;
1970 static constexpr bool TOP_STORE =
true;
1972 static constexpr bool PRINT_WARNINGS =
false;
1980 stats.branch(branchName,
id);
1984 stats.setBranchNum(stats.branchNum() + temp.getAuxIDs().size());
1989 const ::TBranch* container =
m_inTree->GetBranch(branchName.c_str());
1998 return StatusCode::SUCCESS;
2014 const std::string &key) {
2019 "No output tree defined. Did you forget to call writeTo(...)?");
2020 return StatusCode::FAILURE;
2024 const std::set<std::string>* filter = 0;
2027 filter = &(filter_itr->second);
2036 store->selectAux(*filter);
2041 static constexpr bool OWNS_STORE =
true;
2043 std::make_unique<TAuxManager>(store.release(), OWNS_STORE);
2046 return StatusCode::SUCCESS;
2050 if (vitr->second->object() == store.get()) {
2052 return StatusCode::SUCCESS;
2061 if (mgr ==
nullptr) {
2063 << key <<
"\" already exists, and is not of type TAuxStore");
2064 return StatusCode::FAILURE;
2069 store->selectAux(*filter);
2076 mgr->setObject(store.release());
2079 return StatusCode::SUCCESS;
2093 ::TMethodCall setNameCall;
2097 setNameCall.InitWithPrototype(mgr.holder()->getClass(),
"setName",
2099 if (setNameCall.IsValid()) {
2102 const ::TString params =
2103 ::TString::Format(
"\"%s\"", mgr.branch()->GetName());
2104 const char* charParams = params.Data();
2105 setNameCall.Execute(mgr.holder()->get(), charParams);
2108 ATH_MSG_WARNING(
"Couldn't find setName(...) function for container \""
2109 << mgr.branch()->GetName() <<
"\" (type: "
2110 << mgr.holder()->getClass()->GetName() <<
")");
2115 static const TClass*
const holderClass =
2117 if (!mgr.holder()->getClass()->InheritsFrom(holderClass)) {
2119 return StatusCode::SUCCESS;
2127 return StatusCode::FAILURE;
2134 static constexpr bool TOP_STORE =
false;
2136 auto store = std::make_unique<TAuxStore>(
2137 ctx, mgr.branch()->GetName(), TOP_STORE,
2153 static constexpr bool SHARED_OWNER =
false;
2154 m_inputObjects[std::string(mgr.branch()->GetName()) +
"Dynamic"] =
2155 std::make_unique<TAuxManager>(store.get(), SHARED_OWNER);
2158 storeHolder->
setStore(store.release());
2161 return StatusCode::SUCCESS;
2184 return StatusCode::SUCCESS;
2188 if (!mgr->holder()->getClass()->InheritsFrom(
"SG::IAuxStoreIO")) {
2189 return StatusCode::SUCCESS;
2197 return StatusCode::FAILURE;
2204 auto item_itr =
m_auxItemList.find(mgr->branch()->GetName());
2206 sel.selectAux(item_itr->second);
2217 if (auxids.empty()) {
2218 return StatusCode::SUCCESS;
2222 const std::string dynNamePrefix =
2231 typedef std::pair<std::string, SG::auxid_t> AuxVarSort_t;
2232 std::vector<AuxVarSort_t> varsort;
2233 varsort.reserve(auxids.size());
2235 varsort.emplace_back(
r.getName(
id),
id);
2237 std::sort(varsort.begin(), varsort.end());
2240 for (
const auto &p : varsort) {
2246 const std::string brName = dynNamePrefix + p.first;
2249 Object_t::iterator bmgr = objects.find(brName);
2252 if (bmgr == objects.end()) {
2255 const std::type_info* brType = aux->
getIOType(
id);
2258 return StatusCode::FAILURE;
2261 std::string brProperTypeName =
"<unknown>";
2267 if (strlen(brType->name()) == 1) {
2270 brProperTypeName = brTypeName;
2274 if (rootType ==
'\0') {
2276 << brName <<
"\" of type \"" << brTypeName <<
"\"");
2277 return StatusCode::FAILURE;
2281 std::ostringstream leaflist;
2282 leaflist << brName <<
"/" << rootType;
2285 static constexpr bool IS_OWNER =
false;
2286 auto auxmgr = std::make_unique<TPrimitiveAuxBranchManager>(
2290 static constexpr Int_t BASKET_SIZE = 32000;
2291 *(auxmgr->branchPtr()) =
2292 outTree.Branch(brName.c_str(), auxmgr->holder()->get(),
2293 leaflist.str().c_str(), BASKET_SIZE);
2294 if (!auxmgr->branch()) {
2296 << brName <<
"\" out of type \"" << brProperTypeName
2299 *(auxmgr->holder()->getPtr()) = 0;
2300 return StatusCode::FAILURE;
2302 br = auxmgr->branch();
2305 objects[brName] = std::move(auxmgr);
2310 static constexpr Bool_t LOAD_IF_NOT_FOUND = kTRUE;
2311 static constexpr Bool_t SILENT = kTRUE;
2312 TClass* cl = TClass::GetClass(*brType, LOAD_IF_NOT_FOUND, SILENT);
2313 if (cl ==
nullptr) {
2316 cl = TClass::GetClass(brTypeName.c_str());
2318 if (cl ==
nullptr) {
2320 << brName <<
"\" of type \"" << brTypeName <<
"\"");
2321 return StatusCode::FAILURE;
2326 brProperTypeName = cl->GetName();
2329 static constexpr bool IS_OWNER =
false;
2330 auto auxmgr = std::make_unique<TAuxBranchManager>(
2334 static constexpr Int_t BASKET_SIZE = 32000;
2335 static constexpr Int_t SPLIT_LEVEL = 0;
2336 *(auxmgr->branchPtr()) = outTree.Branch(brName.c_str(), cl->GetName(),
2337 auxmgr->holder()->getPtr(),
2338 BASKET_SIZE, SPLIT_LEVEL);
2339 if (!auxmgr->branch()) {
2341 << brName <<
"\" out of type \"" << brProperTypeName
2344 *(auxmgr->holder()->getPtr()) = 0;
2345 return StatusCode::FAILURE;
2347 br = auxmgr->branch();
2350 objects[brName] = std::move(auxmgr);
2355 if (outTree.GetEntries()) {
2356 void* ptr = br->GetAddress();
2358 for (::Long64_t i = 0; i < outTree.GetEntries(); ++i) {
2361 br->SetAddress(ptr);
2368 mgr->branch()->GetName(),
2377 bmgr = objects.find(brName);
2378 if (bmgr == objects.end()) {
2379 ATH_MSG_FATAL(
"There is an internal logic error in the code...");
2380 return StatusCode::FAILURE;
2386 const_cast<void*
>(
static_cast<const void*
>(aux->
getIOData(
id)));
2387 bmgr->second->setObject(nc_data);
2391 return StatusCode::SUCCESS;
2399 return StatusCode::FAILURE;
2403 const std::set<std::string>* filter = 0;
2406 filter = &(filter_itr->second);
2415 store->selectAux(*filter);
2420 static constexpr bool OWNS_STORE =
false;
2421 m_outputObjects[key] = std::make_unique<TAuxManager>(store, OWNS_STORE);
2424 return StatusCode::SUCCESS;
2428 if (vitr->second->object() == store) {
2430 return StatusCode::SUCCESS;
2439 if (mgr ==
nullptr) {
2441 << key <<
"\" already exists, and is not of type TAuxStore");
2442 return StatusCode::FAILURE;
2447 store->selectAux(*filter);
2454 mgr->setObject(store);
2457 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(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.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
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.
virtual SG::auxid_set_t getSelectedAuxIDs() const
Get a list of dynamic variables that need to be written out.
virtual const std::type_info * getIOType(SG::auxid_t auxid) const =0
Return the type of the data to be stored for one aux data item.
virtual const void * getIOData(SG::auxid_t auxid) const =0
Return a pointer to the data to be stored for one aux data item.
Interface for non-const operations on an auxiliary store.
virtual void toTransient(const EventContext &ctx)=0
Perform post-read processing on this 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.
std::unordered_map< std::string, std::unique_ptr< TVirtualManager > > Object_t
Definition of the internal data structure type.
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.
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.
AthContainers_detail::upgrading_lock< upgrade_mutex_t > upgrading_lock_t
Lock type for multithread synchronization.
const EventContext & currentContext() const
Return the event context corresponding to this event.
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).
void add(std::string_view fileName)
Add information about a new file that got accessed.
static TFileAccessTracer & instance()
Access the singleton instance of this class.
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...
AuxElement(SG::AuxVectorData *container, size_t index)
Base class for elements of a container that can have aux data.
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...